ECMAScript Module (ESM)がimportしようとしたらハマった
久々にブログ書く
下のようなコードをECMAScript Module(ES Module、ESMともいう)をimportしようとしたらハマってしまったので書いておく。
//hello.mjs function hello() { console.log("Hello"); } export { hello }
<!DOCTYPE html> <!-- hello.html --> <html lang="ja"> <head> <meta charset="utf-8"> <script type="module"> import { hello } from './hello.mjs' </script> </head> <body> </body> </html>
TL;DR
うまくインポートできなかった原因
ハマった
hello.htmlをChromeで開くと
Access to Script at 'file:///C:/Users/username/Programming/jsworks/es_module/hello.mjs' from origin 'null' has been blocked by CORS policy: Invalid response. Origin 'null' is therefore not allowed access.
というエラー。
調べてみるとどうもAccess Originがnullになっているために読み込んでいないようでした。
同じオリジンからでないと読み込まないようなので pythonを使ってWebサーバを立ち上げてAccess Originを同じlocalhost:8000
にしてもう一度やってみました。
しかし、これが別のエラーの原因になろうとは、まだ知る由もなかった
気を取り直して、Webサーバー起動して、localhost:8000/hello.html
を開いてみると
また別のエラーが出ていました。
Failed to load module script: The server responded with a non-JavaScript MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.
これもググってみたら、どうもModuleのMIME Typeにはjavascriptという文字列が含まれていないといけないようなのですが、
Pythonのhttp.serverのMIME typeの一覧には、まだ.mjsがなく、その代わりにapplication/octet-stream
を送ってしまうためエラーになるようです。
そこで一時的に.mjsを.jsに変更したらきちんと動きました。
ちなみに、http.serverのmimetypeの対応づけはmimetypes
というPythonの標準ライブラリを使っているようで、
その中にまだ.mjsがないために発生するエラーのようです。(Python3.7.0時点)
もうすでにpull reqは出ているようなので()3.8では直っていると思われます。
終わりに
こんな感じでハマってしまいましたが、JavaScriptには言語にモジュールの仕組みがなかったので(Node.jsのCJSなどもありますが、あれはNode.jsの仕様なのでカウントしない)もっと流行ってほしいです。