前提条件
Node.jsがインストールされており、npmとnpxコマンドが実行可能な状態であること。
最終的なファイル構成
project | `--- /node_modules | `--- /src | | | `--- /js | `--- app.js | `--- /dist | | | `--- /js | | `--- bundle.js <--- webpackで生成される | | `--- bundle.js.map <--- webpackで生成される | `--- index.html | `--- package-lock.json `--- package.json `--- webpack.common.js `--- webpack.dev.js `--- webpack.prod.js
パッケージのインストール
- webpack
- webpack-cli
- @webpack-cli/serve
- webpack-dev-server
- webpack-merge
- path
上記のパッケージをインストールする。
npm install --save-dev webpack webpack-cli @webpack-cli/serve webpack-dev-server webpack-merge
設定ファイル作成
webpackの設定ファイルを作成する。@webpack-cli/initをインストールすることでコマンドでひな形を作成することも可能らしい。
今回は開発環境用と本番環境用で、webpackの設定ファイルを分けることにした。
共有設定ファイル
下記内容でwebpack.common.jsを作成する。
const path = require('path'); module.exports = { entry: [ path.join(__dirname, 'src', 'js', 'app.js') ], output: { path: path.join(__dirname, 'dist', 'js'), publicPath: '/js/', filename: "bundle.js", chunkFilename: '[name].js' }, target: ["web", "es5"], resolve: { extensions: ['.js', '.jsx'] }, devServer: { contentBase: path.join(__dirname, 'dist'), watchContentBase: true, inline: true, hot: true, host: 'localhost', port: 8080, open: true, }, };
entry
ここに指定されたファイルを元に、モジュール間の依存関係が解析され、バンドルプロセスが実行される。
output.path
絶対パスでバンドルファイルの出力先を指定する。
output.publicPath
バンドルファイルが存在するパスを指定する。
正しく設定されていないと、webpack-dev-serverがうまく動かなかったり、画像やファイルの読み込み、遅延読み込みなどでエラーが発生する可能性がある。
target
指定されたプラットフォームで利用できるようにビルドされる。デフォルトではブラウザ向けにビルドされるようになっている。ECMAScriptのバージョンを指定することもできる。
resolve
モジュールリクエストの解決方法を変更するためのオプション。
webpackはresolve.extensionsに設定された拡張子を使い、モジュールの探索用パスを生成するらしい。
devServer
webpack-dev-serverに渡すオプションを指定できる。
ちなみに、webpack-dev-serverは、ビルドしたバンドルをメモリに保持する。
開発環境用設定ファイル
次に下記内容で、開発環境用にwebpack.dev.jsを作成する。
const path = require('path') const { merge } = require('webpack-merge') const common = require('./webpack.common.js') module.exports = merge(common, { entry: ['webpack-dev-server/client?'], mode: 'development', devtool: 'eval', })
entryにwebpack-dev-serverのエントリーポイントを指定している。これはHMR(Hot Module Replacement)を有効にするために必要なようだ。
mode
指定されたモードに応じて、ビルド設定が最適化される。
利用可能な値は、developmentとproduction、noneの3種類。
devtool
ソースマップの生成について、設定することができる。
今回は開発ビルドに推奨されるevalと、本番ビルドに推奨されるsource-mapを指定した。
本番環境用設定ファイル
最後に下記内容で、本番環境用にwebpack.prod.jsを作成する。
const path = require('path') const { merge } = require('webpack-merge') const common = require('./webpack.common.js') module.exports = merge(common, { mode: 'production', devtool: 'source-map', })
package.jsonのmain
package.jsonのmain部分はwebpack.common.jsにする。
ビルドコマンド
.\node_modules.bin\webpack --config webpack.prod.js
上記のようにwebpackを実行することも可能だが、下記のようにpackage.jsonのscriptsにコマンドを追記する方が楽だと思う。
{ // .... "scripts": { "build": "webpack --config webpack.prod.js", "start": "webpack-cli serve --config webpack.dev.js" }, // .... }
実際にコマンドを実行する場合は、下記のようになる。
本番環境
下記コマンドでdist内のjsフォルダにbundle.jsとそのソースマップが生成される。
npm run build
index.htmlは自動で生成されないので、distフォルダ内に適当に作成する。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Hello World</title> </head> <body> <script src="js/bundle.js"></script> </body> </html>
開発環境
下記コマンドでwebpack-dev-serverが立ち上がり、ブラウザが起動する。
npm run start