ガイドに従ってきた場合、webpackの基本についてしっかり理解できているはずです。続ける前に、もう少し簡単に作業できるように開発環境をセットアップしましょう。
mode
を'development'
に、title
を'Development'
に設定することから始めましょう。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
+ mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
plugins: [
new HtmlWebpackPlugin({
- title: 'Output Management',
+ title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
webpackがソースコードをバンドルすると、エラーや警告が元の場所にたどり着くのが難しくなることがあります。たとえば、3つのソースファイル(a.js
、b.js
、およびc.js
)を1つのバンドル(bundle.js
)にバンドルし、いずれかのソースファイルにエラーが含まれている場合、スタックトレースはbundle.js
を指します。どのソースファイルからエラーが発生したのか正確に知りたい場合、これは必ずしも役に立ちません。
エラーや警告の追跡を容易にするために、JavaScriptは、コンパイルされたコードを元のソースコードにマッピングするソースマップを提供しています。エラーがb.js
から発生した場合、ソースマップはそれを正確に伝えます。
ソースマップに関しては、さまざまなオプションが利用可能です。ニーズに合わせて構成できるように、必ず確認してください。
このガイドでは、inline-source-map
オプションを使用しましょう。これは説明目的には適していますが、本番環境には適していません。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
+ devtool: 'inline-source-map',
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
では、デバッグするものがあることを確認するために、print.js
ファイルにエラーを作成しましょう。
src/print.js
export default function printMe() {
- console.log('I get called from print.js!');
+ cosnole.log('I get called from print.js!');
}
npm run build
を実行すると、次のようなものにコンパイルされるはずです。
...
[webpack-cli] Compilation finished
asset index.bundle.js 1.38 MiB [emitted] (name: index)
asset print.bundle.js 6.25 KiB [emitted] (name: print)
asset index.html 272 bytes [emitted]
runtime modules 1.9 KiB 9 modules
cacheable modules 530 KiB
./src/index.js 406 bytes [built] [code generated]
./src/print.js 83 bytes [built] [code generated]
./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
webpack 5.4.0 compiled successfully in 706 ms
次に、ブラウザで結果のindex.html
ファイルを開きます。ボタンをクリックして、エラーが表示されるコンソールを確認します。エラーには次のようなものが表示されます。
Uncaught ReferenceError: cosnole is not defined
at HTMLButtonElement.printMe (print.js:2)
エラーには、エラーが発生したファイル(print.js
)と行番号(2)への参照も含まれていることがわかります。これにより、問題を修正するためにどこを見ればよいのかが正確にわかるため、非常に便利です。
コードをコンパイルするたびに手動でnpm run build
を実行するのはすぐに面倒になります。
変更があるたびにコードを自動的にコンパイルするのに役立つ、webpackで利用可能なさまざまなオプションがいくつかあります。
ほとんどの場合、おそらくwebpack-dev-server
を使用したいと思うでしょうが、上記のすべてのオプションを調べてみましょう。
webpackに、依存関係グラフ内のすべてのファイルの変更を「監視」するように指示できます。これらのファイルのいずれかが更新されると、コードが再コンパイルされるため、手動でフルビルドを実行する必要はありません。
webpackのウォッチモードを開始するnpmスクリプトを追加しましょう。
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
+ "watch": "webpack --watch",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^4.5.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
次に、コマンドラインからnpm run watch
を実行し、webpackがどのようにコードをコンパイルするかを確認してください。スクリプトが現在ファイルを監視しているため、コマンドラインが終了しないことがわかります。
次に、webpackがファイルを監視している間に、先ほど導入したエラーを削除しましょう。
src/print.js
export default function printMe() {
- cosnole.log('I get called from print.js!');
+ console.log('I get called from print.js!');
}
ファイルを保存して、ターミナルウィンドウを確認してください。webpackが変更されたモジュールを自動的に再コンパイルすることがわかるはずです!
唯一の欠点は、変更を確認するためにブラウザを更新する必要があることです。自動的に更新される方がはるかに良いでしょう。そこで、それを実現するwebpack-dev-server
を試してみましょう。
webpack-dev-server
は、基本的なWebサーバーとライブリロード機能を提供します。これを設定してみましょう。
npm install --save-dev webpack-dev-server
構成ファイルを変更して、開発サーバーにファイルの検索場所を指示します。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
devtool: 'inline-source-map',
+ devServer: {
+ static: './dist',
+ },
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
+ optimization: {
+ runtimeChunk: 'single',
+ },
};
これは、webpack-dev-server
にlocalhost:8080
のdist
ディレクトリからファイルを提供するように指示しています。
開発サーバーを簡単に実行するためのスクリプトも追加しましょう。
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
+ "start": "webpack serve --open",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"html-webpack-plugin": "^4.5.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
これで、コマンドラインからnpm start
を実行すると、ブラウザが自動的にページを読み込むのが確認できます。ソースファイルのいずれかを変更して保存すると、コードがコンパイルされた後、Webサーバーが自動的にリロードされます。試してみてください!
webpack-dev-server
には、設定可能なオプションが多数あります。詳細については、ドキュメントを参照してください。
webpack-dev-middleware
は、webpackによって処理されたファイルをサーバーに送信するラッパーです。これはwebpack-dev-server
で内部的に使用されていますが、必要に応じてよりカスタムな設定を可能にするために、別のパッケージとして利用できます。webpack-dev-middleware
とexpressサーバーを組み合わせた例を見てみましょう。
まず、express
とwebpack-dev-middleware
をインストールしましょう。
npm install --save-dev express webpack-dev-middleware
次に、ミドルウェアが正しく機能するように、webpack構成ファイルを調整する必要があります。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
print: './src/print.js',
},
devtool: 'inline-source-map',
devServer: {
static: './dist',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
+ publicPath: '/',
},
};
publicPath
は、http://localhost:3000
でファイルが正しく提供されるように、サーバー スクリプト内でも使用されます。ポート番号は後で指定します。次のステップは、カスタムのexpress
サーバーの設定です。
プロジェクト
webpack-demo
|- package.json
|- package-lock.json
|- webpack.config.js
+ |- server.js
|- /dist
|- /src
|- index.js
|- print.js
|- /node_modules
server.js
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(
webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
})
);
// Serve the files on port 3000.
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
});
次に、サーバーの実行を少し簡単にするためにnpmスクリプトを追加します。
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack serve --open",
+ "server": "node server.js",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"express": "^4.17.1",
"html-webpack-plugin": "^4.5.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",
"webpack-dev-middleware": "^4.0.2",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"lodash": "^4.17.20"
}
}
ターミナルでnpm run server
を実行すると、次のような出力が表示されます。
Example app listening on port 3000!
...
<i> [webpack-dev-middleware] asset index.bundle.js 1.38 MiB [emitted] (name: index)
<i> asset print.bundle.js 6.25 KiB [emitted] (name: print)
<i> asset index.html 274 bytes [emitted]
<i> runtime modules 1.9 KiB 9 modules
<i> cacheable modules 530 KiB
<i> ./src/index.js 406 bytes [built] [code generated]
<i> ./src/print.js 83 bytes [built] [code generated]
<i> ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
<i> webpack 5.4.0 compiled successfully in 709 ms
<i> [webpack-dev-middleware] Compiled successfully.
<i> [webpack-dev-middleware] Compiling...
<i> [webpack-dev-middleware] assets by status 1.38 MiB [cached] 2 assets
<i> cached modules 530 KiB (javascript) 1.9 KiB (runtime) [cached] 12 modules
<i> webpack 5.4.0 compiled successfully in 19 ms
<i> [webpack-dev-middleware] Compiled successfully.
次に、ブラウザを起動してhttp://localhost:3000
にアクセスします。webpackアプリケーションが実行され、機能しているのが確認できるはずです!
コードの自動コンパイルを使用している場合、ファイルを保存する際に問題が発生する可能性があります。一部のエディターには、「安全な書き込み」機能があり、再コンパイルを妨げる可能性があります。
一般的なエディターでこの機能を無効にするには、以下のリストを参照してください。
atomic_save: 'false'
を追加します。Preferences > Appearance & Behavior > System Settings
で「Use safe write」のチェックを外します。:set backupcopy=yes
を追加します。これで、コードを自動的にコンパイルし、開発サーバーを実行する方法を学習しました。次のガイドでは、コード分割について説明します。