webpack.config.jsがいつまでたってもわからない
Javascript開発には欠かせないwebpackですが、webpack.config.js
ファイルの書き方がいつまで経っても検索&コピペばかりで身に付きません。別にコピペでいいじゃんという考え方もありますが、webpackのドキュメントに沿って設定内容を理解し、自分の環境に合わせた形でwebpack.config.js
が書けるようにまとめていきたいと思います。バージョンは3.8.1の想定です。ディレクトリ構成も考えながらやっていきたいと思います。今のところproject
ディレクトリ以下に次のようにファイルが存在しているとします。
project
- /node_modules/
- package.json
- webpack.config.js
const path = require('path')
module.exports = {
}
ここからスタートです。
Concepts
webpack.config.js
には大量の設定項目がありますが、まずは4つの中心的な項目について理解する必要があります。
- Entry
- Output
- Loaders
- Plugins
Entry
webpackがビルドを始める際の開始点となるjsファイルで、エントリーポイントと呼びます。webpackはエントリーポイントに入ったあと、エントリーポイントがどのモジュールやライブラリに依存しているのかを判断し、処理してbundleと呼ばれるファイルに出力します。
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, "entry.js"),
}
Output
bundleファイルをwebpackがどこにどのような名前で出力すればいいのかを指定できます。dist
ディレクトリの中にbundle.js
という名前で出力するとしたら次のようになります。
project
- /node_modules/
- /dist/
- package.json
- webpack.config.js
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, "entry.js"),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
}
Loaders
webpack自身はJavaScriptしか理解できませんが、Loaderを使うことによってJavaScript以外のものも処理できるようになります。どのような種類のファイルであってもwebpackが処理できるモジュールにLoaderが変換してくれることで、webpackがbundleファイルを作れるようになります。(モジュール化がwebpackの根本的な仕組みです)
Loaderには以下のような2つの目的があります。
-
test
プロパティに拡張子を指定して、あるLoaderがどのような種類のファイルを処理するべきなのか特定する(正規表現で拡張子を指定) -
use
プロパティにLoaderを指定して、test
プロパティに指定したファイルがアプリケーションの依存関係や最終的なbundleファイルに加えられるように変換する
const path = require('path')
module.exports = {
entry: path.resolve(__dirname, "entry.js"),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
}
この場合の指定だと、webpackに対してこう言っているのと同じです。
"Hey webpack compiler, when you come across a path that resolves to a '.txt' file inside of a require()/import statement, use the raw-loader to transform it before you add it to the bundle."
webpackさん、require()文の中で'.txt'で終わるようなパスに出会ったら、bundleファイルに追加する前にraw-loaderで変換してください。
Plugins
Loaderがある種のモジュールを変換するのに対して、Pluginはwebpackができることの幅を広げてくれます。Pluginがあるとbundleファイルの最適化や環境変数の設定などいろいろなことができるようになります。Pluginを使うには、require()
をして、plugins
配列に追加する必要があります。configファイルの中で同じPluginを別の用途に使うことができるので、new
演算子でその都度インスタンスを生成する必要があります。
Plugin一覧
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
module.exports = {
entry: path.resolve(__dirname, "entry.js"),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
}
ここまでの感想
- Loaderの役割
-
module
プロパティは「こういう拡張子のファイルはこのLoaderでいい感じにTransformして」という指定だった - Pluginはとりあえず使わなそう
- Loadersをもうちょっと掘り下げたい(Babelやscssで明らかによく見る)
次回はLoaderを掘り下げます。