開発

ガイドに従ってきた場合、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.jsb.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で利用可能なさまざまなオプションがいくつかあります。

  1. webpackのウォッチモード
  2. webpack-dev-server
  3. webpack-dev-middleware

ほとんどの場合、おそらく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の使用

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-serverlocalhost:8080distディレクトリからファイルを提供するように指示しています。

開発サーバーを簡単に実行するためのスクリプトも追加しましょう。

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-dev-middlewareは、webpackによって処理されたファイルをサーバーに送信するラッパーです。これはwebpack-dev-serverで内部的に使用されていますが、必要に応じてよりカスタムな設定を可能にするために、別のパッケージとして利用できます。webpack-dev-middlewareとexpressサーバーを組み合わせた例を見てみましょう。

まず、expresswebpack-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アプリケーションが実行され、機能しているのが確認できるはずです!

テキストエディターの調整

コードの自動コンパイルを使用している場合、ファイルを保存する際に問題が発生する可能性があります。一部のエディターには、「安全な書き込み」機能があり、再コンパイルを妨げる可能性があります。

一般的なエディターでこの機能を無効にするには、以下のリストを参照してください。

  • Sublime Text 3: ユーザー設定にatomic_save: 'false'を追加します。
  • JetBrains IDE (例: WebStorm): Preferences > Appearance & Behavior > System Settingsで「Use safe write」のチェックを外します。
  • Vim: 設定に:set backupcopy=yesを追加します。

結論

これで、コードを自動的にコンパイルし、開発サーバーを実行する方法を学習しました。次のガイドでは、コード分割について説明します。

15 貢献者

SpaceK33zrafdefvgsTheDutchCoderWojciechKoCalinouGAumalaEugeneHlushkobyzyktrivikraholznerchenxsansnitin315f3ndot