0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PyScriptでESMモジュールを使う

Last updated at Posted at 2025-05-02

概要

PyScriptからJavaScriptのESMモジュールをインポートするのは難しくはないですが、当たり前とはいえJavaScriptとは全然違うのでメモ

謎モジュールを作る

テストするにあたって今使いたいモジュールが特に思いつかなかったので、こんな感じのどうでもいいモジュールを自作してみた。

testmod.js
export { test2 } from './testmod2.js';

export function test() {
    alert('test');
}

export default () => {
    alert('test default');
}
testmod2.js
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する形になります。

これも詳しくは公式ドキュメントを見てください。

index.html
<!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]を参照することでモジュール本体を取得できます。

こちらも詳しくは公式ドキュメントを見てください。

index.html
<!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>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?