はじめに
ねぇまってむり
webpackでこれ以上消耗するの
つらいょ
というみなさんへ
これを期に 理解しましょう webpack
今回の記事は webpack の公式ドキュメントhttps://webpack.js.org/ (CC BY 4.0) から内容をたくさん引用しています。ありがとう Webpack チーム!
本題に入る前に
何故webpackを使うのかを考えてみましょう
こういうのは何故必要かも理解しておくと有り難みが増すんやで。
はるか昔の javascript
有史以前、ブラウザでJavaScriptを実行する方法は2つありました
まず1つ目としてスクリプトタグで各機能ごとに切り分けたファイルを読み込む方法があります。しかし大量のスクリプトをロードするとネットワークのボトルネックが発生する可能性があるため、この方法ではスケーリングが困難であると考えられました。
2番目の選択肢は、すべてのプロジェクトコードを含む大きな .jsファイルを使うことです。しかしこの方法もスコープ、サイズ、読みやすさ、そして保守のしやすさに問題がありました。
IIFE's - 即時関数
即時関数
は大規模プロジェクトのスコープの問題を解決しました。
スクリプトファイルが即時関数によってラップされている場合は、スコープの競合を気にせずにファイルを安全に連結、結合ができるのです
即時関数が一世を風靡しMake、Gulp、Grunt、Broccoli、Brunchなどのツールにつながりました。
しかしこれらのツールも1つのファイルの変更で毎回ビルドし直すというバリだるい問題がありました
即時関数でまるごと関数をラップしているライブラリ例としてこちら howler.js を御覧ください。src/howler.core.jsは即時関数で丸ごとラップされています。
Node.jsの登場
Node.js
はブラウザ環境外のコンピュータやサーバーで使用できるJavaScriptランタイムです。
さらにCommonJS
が登場し、 require
を導入しました。requireにより必要な各モジュールをインポートすることでスコープの問題を解決しました。
しかしCommonJSは独自仕様だったためブラウザサポートはまだありません、というかもうサポートしないでしょう
今後はimport
, export
に代表されるECMAScript Modulesが標準になる予定です。しかしこちらもブラウザのサポートは不完全です。
ブラウザでもrequire
, import
を使いたい、その声に応えるためにモジュールバンドラー
が誕生しました
モジュールバンドラー
ブラウザでrequire
はサポートされないと分かった結果Browserify、RequireJS、SystemJSなどのモジュールバンドラーが作成されました。
モジュールバンドラーの役割は、機能ごとに分割されたソースファイルをNode.jsを使って一纏めのバンドルファイルにすることです。
そしてバンドルファイルをスクリプトタグを使って読み込みます。
モジュールバンドラーのおかげでrequire
やimport
を間接的にブラウザで使えるようになりました
Webpack
Webpack
はBrowserify、RequireJS、SystemJSなどの仲間のモジュールバンドラーです。
モジュールバンドラーの中ではデフェクトスタンダードになりつつあります、多分。
Webpack使えても損はないだろうし、ま、多少はね?
webpack.config.js
webpackを理解すると言うことはwebpack.config.js
を理解することと言っても過言ではありません。
しかしwebpack.config.jsは初見だとなかなか読めないです。
なのでwebpack.config.jsを読む場合は以下の5つに注目してください。これさえ押さえておけば何となく読めるようになります。
- Mode
- Entry
- Output
- Loader
- Plugin
Webpack.config.jsを何となく読めるようになったらwebpackの入門は終了です。
Mode
Webpack.config.jsのmode
パラメータをdevelopment
、 production
またはnone
のいずれかに設定することで、それぞれの環境に対応して最適化することができます。 デフォルト値は production
です。
module.exports = {
mode: 'production'
};
簡単に説明すると開発版と製品版を切り替える為に使います。
こちらの記事が分かり易かったです。
webpackで開発用/本番用の設定を分ける
Entry
webpackがバンドルするためのエントリーポイント(一番はじめに読み込むファイル)を指定します。
module.exports = {
entry: './path/to/my/entry/file.js'
};
Output
作成したバンドルをどこに出力するか、およびこれらのファイルの命名方法をwebpackに指示します。 デフォルトのメインの出力ファイルは ./dist/main.js
です。
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
// dist/my-first-webpack.bundle.jsというバンドルファイルが出力されます。
Loader
Loaderの概念はwebpackを理解する時に最優先で覚えるべきです。
何も設定がない場合webpackはJavaScriptとJSONファイルしか理解できません(超大事)。
jsファイル内でcssファイルをimportしたい場合などはLoaderを指定する必要があります。
Loaderを指定することで様々な種類のファイルを使用可能なモジュールに変換します。
Loaderはmoduleプロパティのrules内で配列で指定します。
-
test
プロパティはどのファイルを変換するべきかを正規表現で識別します。 -
use
プロパティは、正規表現に引っかかったファイルがどのローダーを使って変換を行うべきかを示します。
const path = require('path');
module.exports = {
output: {
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};
上記例では、.cssと言う拡張子のファイルをimportする場合はcss-loaderを使えとwebpackに伝えています。
Plugins
プラグインはかなり奥が深いので何となくの理解で大丈夫です。
プラグインが何なのかと言うとローダー以外の全部です。バンドルの最適化、アセットの管理、環境変数の注入などなど出来ることは非常に幅広いです。
そもそもwebpack自体がwebpack.config.jsの プラグインシステムと同じもの の上に構築されているらしいです
プラグインを使うには、プラグインをrequire()
して plugins
プロパティの配列に追加する必要があります。 ほとんどのプラグインはオプションを通じてカスタマイズ可能です。 プラグインはnew
演算子でインスタンスを作成する必要があることに注意してください。
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
module.exports = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
上の例では、 html-webpack-plugin
は自動的にすべてのバンドルが注入されたHTMLファイルを生成します。
終わりに
他にもwebpack.config.jsで指定できるプロパティはたくさんあります。さらにcuiでどのように実行するのかも覚えるべきです。
ですが、この記事に書いてあることが理解できれば何となーくwebpack.config.jsが読めていい感じになるんじゃないでしょうか
最後に宣伝なのですがこんなサイトもやっているので暇があればみてください。