当記事では、ESモジュール(JavaScript modules・ES6モジュール・ESMなどとも呼ばれる)を使ってみたところ、ブラウザのコンソールに以下のようなエラーが表示され、モジュールの読み込みに失敗したときの対処方法を紹介します。
Failed to load module script: The server responded with a non-JavaScript MIME type of "".
Strict MIME type checking is enforced for module scripts per HTML spec.
1. 注意事項
これから紹介する対処方法を試してみるときは以下の2点に注意してください。
1-1. 動作確認済み環境
直ることを確認した環境は以下の通りです。
- OS: Windows 10 Home 64bit版
- Webサーバー: Apache HTTP Server v2.4.46(インストーラー不使用。バイナリを直接ダウンロード・配置して構築)
- ブラウザ: Google Chrome v87.0.4280.88 64bit版
1-2. 原理不明
私自身、何故この設定で動くのかよく分かっていません。
2. 対処方法
Apache HTTP Serverの設定ファイルであるhttpd.confに以下のようなディレクティブを追加してください。
LoadModule mime_module "./modules/mod_mime.so"
<FilesMatch "\.mjs$">
AddType text/javascript .mjs
</FilesMatch>
エラーが出ている原因はJavaScriptをモジュールとして読み込むときにMIMEタイプが設定されていないのが原因っぽい(確証はありません)ので、AddTypeディレクティブでtext/javascript
というMIMEタイプを設定することでエラーを回避しています。
なお、既にmod_mimeモジュール(mime_module)を読み込んでいるときは重複して読み込ませる必要はありません。重複したLoadModuleディレクティブは無視されます。
2-1. FileMatchセクションの必要性
AddTypeディレクティブをFileMatchセクションで囲んでいるのは、AddTypeディレクティブの脆弱性回避のためです。FileMatchセクションで囲んでいないと、例えばtest.mjs.phなどという意味不明な拡張子を持つファイルもESモジュールとして読み込んでしまいます。詳しくは以下記事を参照してください。
AddType, AddHandler, SetHandlerの違い – senooken.jp
2-2. AddTypeディレクティブの第2引数は.mjs
じゃないと駄目
ESモジュールの拡張子は.js、あるいは.mjsを使うことになっているようです。
JavaScript モジュール - JavaScript | MDN
上記ディレクティブを見た感じだと、拡張子が.mjsでないとESモジュールとして読み込まれないように思われますが、実際は.js・.mjsの両方に対応できています。理由は謎です(ESモジュールとして読み込むときは内部的に.mjsとして解釈しているのかも?)。
また、AddTypeディレクティブの第2引数を.js
に直した場合は.jsも.mjsもESモジュールとして読み込めなくなります。理由は謎です(.jsは既定されているからかも?)。
2-3. AddHandlerディレクティブ・SetHandlerディレクティブは駄目
AddTypeディレクティブと似ているAddHandlerディレクティブ・SetHandlerディレクティブは、任意の拡張子を任意のハンドラに割り当てるディレクティブなので、当問題の解決には使えません。
2-4. TypeConfigディレクティブとmime.typesで代替できるかも
当記事で書かれている方法はTypeConfigディレクティブとmime.typesで代替できるかもしれません。ただ、MIMEタイプを追加するときはmime.typesを弄るのではなく、AddTypeディレクティブで追加したほうが良いみたいです。