HoteKanの開発担当者です。
webpackではimport、exportを使ってモジュール解決ができます。
しかし、webpackのimportは厳密にはES2015(ES6)のimportとは違います。
webpackでは独自のモジュール解決ルールを持っています。
普段はほとんど気にする必要はないですが、何か問題が起こった際にはこの独自ルールを知ってないとハマることになるでしょう。
webpackがモジュールのimportを解決する仕組み
モジュールが絶対パス/相対パスで指定されている場合
import '/home/me/file';
import '../src/file1';
これは簡単です。
指定されたファイルを見に行くだけです。
モジュール名を使って指定されている場合
import 'module';
import 'module/lib/file';
npmを使ってパッケージをインストールした場合利用する方法です。
この場合以下の順序でモジュール解決が行われます。
- webpackの設定で
resolve.modules
で指定されたディレクトリ内からモジュールを探します。 - 指定されたパスに拡張子がついている場合、該当するファイルで解決されます。
- 拡張子がない場合、
resolve.extentions
で指定された拡張子のファイルがないか探します。あればそのファイルで解決されます。該当するファイルが複数ある場合、resolve.extentions
で最初にリストされている拡張子が採用されます。 - 指定されたパスがフォルダで、かつ、そのフォルダにpackage.jsonがある場合、
resolve.mainFields
に指定されたフィールドをresolve.mainFields
での指定順に探します。見つかればそこに記載されたファイルで解決されます。 - 指定されたパスがフォルダで、package.jsonがない場合、あるいは、package.jsonはあるが
resolve.mainFields
で指定されたフィールドがバリッドなファイルパスを返さない場合、resolve.mainFiles
で指定されたファイルを探します。その際もresolve.extentions
が参照されます。
各webpackオプションのデフォルト値は以下の通りです。
module.exports = {
//...
resolve: {
modules: ['node_modules'],
extensions: ['.wasm', '.mjs', '.js', '.json'],
mainFields: ['browser', 'module', 'main'],
mainFiles: ['index']
}
};
上記のresolve.mainFields
に関してはwebpackのtarget
オプションの設定によってデフォルト値が変ります。上記はwebworker
、web
か指定無しの場合で、それ以外では['module', 'main']
がデフォルト値となります。