出力管理

これまではすべてのアセットを `index.html` ファイルに手動で含めていましたが、アプリケーションが大きくなり、ファイル名にハッシュを使用したり、複数のバンドルを出力したりするようになると、 `index.html` ファイルを手動で管理するのが難しくなります。しかし、このプロセスをはるかに簡単に管理できるプラグインがいくつか存在します。

準備

まず、プロジェクトを少し調整しましょう

プロジェクト

  webpack-demo
  |- package.json
  |- package-lock.json
  |- webpack.config.js
  |- /dist
  |- /src
    |- index.js
+   |- print.js
  |- /node_modules

`src/print.js` ファイルにロジックを追加しましょう

src/print.js

export default function printMe() {
  console.log('I get called from print.js!');
}

そして、その関数を `src/index.js` ファイルで使用します

src/index.js

 import _ from 'lodash';
+import printMe from './print.js';

 function component() {
   const element = document.createElement('div');
+  const btn = document.createElement('button');

   element.innerHTML = _.join(['Hello', 'webpack'], ' ');

+  btn.innerHTML = 'Click me and check the console!';
+  btn.onclick = printMe;
+
+  element.appendChild(btn);
+
   return element;
 }

 document.body.appendChild(component());

webpack がエントリを分割できるように、 `dist/index.html` ファイルも更新しましょう

dist/index.html

 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8" />
-    <title>Asset Management</title>
+    <title>Output Management</title>
+    <script src="./print.bundle.js"></script>
   </head>
   <body>
-    <script src="bundle.js"></script>
+    <script src="./index.bundle.js"></script>
   </body>
 </html>

次に、設定を調整します。 `src/print.js` を新しいエントリポイント( `print` )として追加し、出力も変更して、エントリポイント名に基づいてバンドル名を動的に生成するようにします

webpack.config.js

 const path = require('path');

 module.exports = {
-  entry: './src/index.js',
+  entry: {
+    index: './src/index.js',
+    print: './src/print.js',
+  },
   output: {
-    filename: 'bundle.js',
+    filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
 };

`npm run build` を実行して、何が生成されるかを見てみましょう

...
[webpack-cli] Compilation finished
asset index.bundle.js 69.5 KiB [emitted] [minimized] (name: index) 1 related asset
asset print.bundle.js 316 bytes [emitted] [minimized] (name: print)
runtime modules 1.36 KiB 7 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 1996 ms

webpack が `print.bundle.js` と `index.bundle.js` ファイルを生成していることがわかります。これらのファイルは `index.html` ファイルでも指定しました。ブラウザで `index.html` を開くと、ボタンをクリックしたときに何が起こるかを確認できます。

しかし、エントリポイントのいずれかの名前を変更したり、新しいエントリポイントを追加したりするとどうなるでしょうか?生成されたバンドルはビルド時に名前が変更されますが、 `index.html` ファイルは引き続き古い名前を参照します。`HtmlWebpackPlugin` を使用して修正しましょう。

HtmlWebpackPlugin の設定

まず、プラグインをインストールし、 `webpack.config.js` ファイルを調整します

npm install --save-dev html-webpack-plugin

webpack.config.js

 const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
+  plugins: [
+    new HtmlWebpackPlugin({
+      title: 'Output Management',
+    }),
+  ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
 };

ビルドを行う前に、 `dist/` フォルダーに `index.html` が既に存在する場合でも、 `HtmlWebpackPlugin` はデフォルトで独自の `index.html` ファイルを生成することを知っておく必要があります。つまり、 `index.html` ファイルが新しく生成されたファイルに置き換えられます。 `npm run build` を実行したときに何が起こるかを見てみましょう

...
[webpack-cli] Compilation finished
asset index.bundle.js 69.5 KiB [compared for emit] [minimized] (name: index) 1 related asset
asset print.bundle.js 316 bytes [compared for emit] [minimized] (name: print)
asset index.html 253 bytes [emitted]
runtime modules 1.36 KiB 7 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 2189 ms

コードエディターで `index.html` を開くと、 `HtmlWebpackPlugin` がまったく新しいファイルを作成し、すべてのバンドルが自動的に追加されていることがわかります。

`HtmlWebpackPlugin` が提供するすべての機能とオプションについて詳しく知りたい場合は、`HtmlWebpackPlugin` リポジトリで読んでください。

/dist フォルダのクリーンアップ

これまでのガイドやコード例でお気づきかもしれませんが、/dist フォルダには不要なファイルがかなり溜まってきています。Webpack はファイルを生成して /dist フォルダに配置しますが、プロジェクトで実際に使用されているファイルは追跡しません。

一般的に、各ビルドの前に /dist フォルダをクリーンアップして、使用されているファイルのみが生成されるようにすることをお勧めします。output.clean オプションを使用して、これに対処しましょう。

webpack.config.js

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
   plugins: [
     new HtmlWebpackPlugin({
       title: 'Output Management',
     }),
   ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
+    clean: true,
   },
 };

npm run build を実行し、/dist フォルダを確認してください。すべてがうまくいけば、ビルドから生成されたファイルのみが表示され、古いファイルは表示されなくなります。

マニフェスト

Webpack とそのプラグインが、どのファイルが生成されているかをどのように「認識」しているのか疑問に思われるかもしれません。その答えは、Webpack がすべてのモジュールと出力バンドルの対応関係を追跡するために保持するマニフェストにあります。Webpack の output を他の方法で管理することに興味がある場合は、マニフェストから始めるのが良いでしょう。

マニフェストデータは、WebpackManifestPlugin を使用して JSON ファイルに抽出できます。

このプラグインをプロジェクト内で使用する方法の完全な例はここでは説明しませんが、コンセプトページキャッシングガイド を読んで、これが長期キャッシングにどのように関連しているかを確認できます。

まとめ

HTML にバンドルを動的に追加する方法を学習したので、次は 開発ガイド を見てみましょう。または、より高度なトピックについて詳しく知りたい場合は、コード分割ガイド をお勧めします。

8 貢献者

skipjackTheDutchCodersudarsangpJGJPEugeneHlushkoAnayaDesignchenxsansnitin315