created: 2020-01-23T08:46:27.000Z
browserifyからwebpackに移行するときのエラー
browserifyのcommonjsと、webpackのcommonjsの違いにハマったときの話
経緯
browserifyからwebpackに移行するときに、ある古いライブラリが読み込み時エラーとなってしまった その古いライブラリはモジュール解決のロジックを以下のように行なっていた
if ( typeof define === 'function' && define.amd ) {
// AMD
define( ['jquery'], function ( $ ) {
return factory( $, window, document );
} );
}
else if ( typeof exports === 'object' ) {
// CommonJS
module.exports = function (root, $) {
browserifyでモジュール解決をしていたときは名前空間に define
がなかったため無事にcommonjsとしてモジュールを読み込めていたが、webpackでビルドすると名前空間に define
が存在し、分岐の結果AMDとしてモジュールを読み込もうとしているようだった
これまでbrowserify(commonjs)でビルドしていたので、このファイルのみAMDで読み込むことになりエラーになった
commonjsとAMD
両方ともjsでモジュールを読み込むための仕様
commonjsはnodejsで使われており、AMDはブラウザ側で使うために作られた (クライアント側が通信してjsファイルを取ってくるといったことをする)
datatable.netはcommonjsとAMDを背反なものとして分岐させているが、実際にはcommonjsとAMDを同時に動作させるといったことも行われているようだ
参照
commonjsのwikiにAMDの仕様がPROPOSALであがっていたり
commonjsのwikiにメーリングリストにAMDを別口に分けようとするスレッドがあったりする
もともとこの辺りのスニペットをコピペしたライブラリなのかもしれない
解決方法
説明から遠回りしたが、今回の問題はつまるところ次の点に尽きる
- browserifyのcommonjsではAMDが有効になっていないが
- webpackのcommonjsではAMDが有効になっている
- コンパイル時のグローバル名前空間に
define
関数が存在している
- コンパイル時のグローバル名前空間に
なのでwebpackの設定でAMDを無効にした
module.exports = {
module: {
rules: [
{
parser: {
amd: false, // disable AMD
}
}
]
}
}
この設定でbrowserifyでビルドできていたときと同じ動作にすることができた