概要
PyScriptからJavaScriptのESMモジュールをインポートするのは難しくはないですが、当たり前とはいえJavaScriptとは全然違うのでメモ
謎モジュールを作る
テストするにあたって今使いたいモジュールが特に思いつかなかったので、こんな感じのどうでもいいモジュールを自作してみた。
export { test2 } from './testmod2.js';
export function test() {
alert('test');
}
export default () => {
alert('test default');
}
export function test2() {
alert('test2');
}
PyScriptのconfigについて
PyScriptでは外部PythonファイルやJavaScriptモジュールなどの様々な設定をJSONやTOMLフォーマットで記述できます。
設定を記述したJSONやTOMLファイルをscript要素のconfig属性に指定するのが一般的ですが、JSONやTOMLをpy-config(MicroPythonの場合はmpy-config)要素内やscriptタグのconfig要素に直接記述することもできるようです。
詳しくは公式ドキュメントを見てください。
静的インポート
JavaScriptではコードのトップレベルにimport
を書く形のインポートをPyScriptで実現するには、configでインポートするJavaScriptファイルとモジュール名を設定すると、pyscript.js_modules
モジュールに登録されているのでconfigで設定したモジュール名をimport
する形になります。
これも詳しくは公式ドキュメントを見てください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2025.3.1/core.css" />
<script type="module" src="https://pyscript.net/releases/2025.3.1/core.js"></script>
<mpy-config>
{
"js_modules": {
"main": {
"./testmod.js": "testmod"
}
}
}
</mpy-config>
<title>Document</title>
</head>
<body>
<button id="btn">default export</button>
<button id="btn2">named export</button>
<button id="btn3">external module export</button>
<script type="mpy">
import js
from pyscript.js_modules import testmod
btn = js.document.getElementById('btn')
btn.addEventListener('click', testmod.default);
btn2 = js.document.getElementById('btn2')
btn2.addEventListener('click', testmod.test);
btn3 = js.document.getElementById('btn3')
btn3.addEventListener('click', testmod.test2);
</script>
</body>
</html>
動的インポート
JavaScriptでいうところのdynamic importというかimport呼び出し(関数ではないらしい)のようにスクリプト実行中に動的にインポートすることも可能です。
PyScriptでは、pyscript
モジュールのjs_import
関数で動的インポートします。
多分バグだと思いますが、2025年5月現在のバージョンでは相対パスを渡すとPyScript本体のURLになってしまうようなので、JavaScriptのlocation.href
の最後の/
以降を削除したURLを文字列結合してモジュールのURLを生成しました。
js_import
は常にタプルを返すので、戻り値の変数の後ろにカンマをつけるか、戻り値の変数の[0]を参照することでモジュール本体を取得できます。
こちらも詳しくは公式ドキュメントを見てください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2025.3.1/core.css" />
<script type="module" src="https://pyscript.net/releases/2025.3.1/core.js"></script>
<title>Document</title>
</head>
<body>
<button id="btn">default export</button>
<button id="btn2">named export</button>
<button id="btn3">external module export</button>
<script type="mpy">
import js
from pyscript import js_import, display
base = js.location.href.rsplit('/', 1)[0]
display(js.location.href)
display(base)
testmod, = await js_import(base + '/testmod.js')
btn = js.document.getElementById('btn')
btn.addEventListener('click', testmod.default)
btn2 = js.document.getElementById('btn2')
btn2.addEventListener('click', testmod.test)
btn3 = js.document.getElementById('btn3')
btn3.addEventListener('click', testmod.test2)
</script>
</body>
</html>