どうしてもES2015で書きたくて初めて webpack 導入してみました。険しい道のりだったので躓いたところをメモしておきます。
1. jsをコンパイルしてくれない
現象
jsファイルのコピー(結合)はしてくれるものの、()=>{ ... }
がそのままになっているなど、Babel が働いていない様子。コンソールには Unexpected token import
などと表示されます。
解決策
webpack.config.js
の設定で loaders
のスペルを間違えて loders
にしてました(テヘペロ
警告が出たりしないので、なんか動かないというときは要チェックです。
2. コンパイルが遅い
現象
コンパイルに40秒くらいかかってました。 ツイッターがはかどる 仕事が進まず大変ストレスになりますね。
解決策
node.js のバージョンを最新にして、さらに node_modules をいったん全部消してnpm install
しなおしたら3秒くらいになりました。(v4 → v6.9.1)
参考:babel-loader 6 VERY slow in webpack #139
ちなみに、node_modules
を exclude
するというのが効果大のようです。(自分はすでに書いていた)
3. watcherが動かない(WebStorm)
現象
WebStorm はどのタイミングでセーブしてるのかいまいちはっきりしないんですが、待てども待てどもファイルが更新されない。
解決策
設定で"safe write"を検索し、チェックボックスを外す。
参考:File saves in WebStorm don’t trigger the watcher
4. モジュールが足りないと言われる
現象
Chromeでは怒られなかったんですが、const
や let
をグローバルスコープで宣言はできないみたいです。
const info = {
name: 'noobar'
};
$(document).ready( () => {
$('#name').text(info.name); // エラー: info is not declared
});
解決策
import
/ export
を使います。
const info = {
name: 'noobar'
};
export default info;
import info from 'info';
$(document).ready( () => {
$('#name').text(info.name); // エラー: info is not declared
});
参考:ES6(ES2015)でグローバルに定義したlet,const,classはグローバルオブジェクトのプロパティにならない
5. import を使うとエラー
現象
上記の main.js
で import しようとしているモジュールが見つからないと怒られます。(ブラウザではなくwebpackのコンソールでエラー)
Module not found: Error: Cannot resolve module 'info' in ...
解決策
方法1: パスを明示的な相対パスにする
/* before */ import info from 'info';
/* after */ import info from './info';
方法2: 設定ファイルにresolve/rootを定義
const Path = require('path');
module.exports = {
...
resolve: {
root: Path.resolve('./src/js')
// ファイルが./src/js/info.jsにある想定
}
};
どっちでも解決しましたが、方法2の方が今後が楽そうですね。
参考:Module not found: Error: Cannot resolve module 'components/app'. webpack + reactjs issue