Webpackで外部ライブラリも実装コードもひとまとめにすると、非常にビルド時間が長くなります。それを解決する手段は多々ありますが、Bowerとnpm両方で対応可能な方法について説明します。
※文中のjQueryはnpmにもありますが、敢えてBowerのパッケージしかないと仮定します。
Bowerのモジュール
WebpackとBowerは相性がよくないため(諸説ありますが)、Bowerのモジュールもnode_modules以下にインストールして、Webpackから特別なことをしなくてもロードできるようにします。
まず、.bowerrcをプロジェクトルートに配置します。私は好みで@bower
以下に配置されるようにしています。
{
"directory": "node_modules/@bower/"
}
$ bower install jquery
これでjqueryがnode_modules/@bower/jquery以下に配置されます。
npmのモジュール
npmでそのままインストールして、その名前でrequireが可能です。
グローバル上にエクスポートするためのJSファイル作成
以下のファイルをWebpackの設定のエントリに追加します。
//BowerのjQueryを読み込む場合
window.$ = require("@bower/jquery/dist/jquery");
//npmのangularを読み込む場合
//window.angular = require("angular");
webpack.config.jsは以下の通りになります。
module.exports = {
entry: "./export.js",
output: {
path: "../../dist",
filename: "vendor.js"
},
resolve: {
extensions: ["", ".js"]
}
};
これらのファイルをsrc/vendor以下に配置します。
使う側のコード
使う側は特に意識せずにrequireすれば問題ありません。webpack.config.jsのexternalsの設定で、
jqueryが参照された時にグローバルに存在する$を返すようにします。
module.exports = {
entry: "./main.js",
output: {
path: "../../dist",
filename: "bundle.js"
},
resolve: {
extensions: ["", ".js"]
},
externals : {
"jquery" : "$"
},
};
var $ = require("jquery");
console.log($(document));
これらのファイルをsrc/main以下に配置します。
ビルド
src/main及びsrc/vendor以下でwebpackを実行するとdist以下にbundle.jsとvendor.jsが作成されます。
あとは、dist以下にindex.htmlを作成して開いてみましょう。
<html>
<script src="vendor.js"></script>
<script src="bundle.js"></script>
</html>
vendor.jsを必ず先に読み込む必要があります。
応用
style-loader、css-loader、sass-loader、file-loaderなどを駆使すると、CSSやアセットなどもセットになったパッケージを取り込むことも可能です。
私はjQuery、AngularJS、MaterializeCSS、babel-polyfillを取り込んでみましたが、Uglifyで縮小すると600Kbちょいのサイズになりました。