KDE BLOG

バイブス

【webpack速習】vol.3: Output Management

下記ページの要点をまとめていきます。

webpack.js.org

ざっくりいうと、出力されたバンドルファイルの読み込みを自動で行うようにするためにhtmlの生成を動的にするガイドです。

概要

  • アプリケーションが大きくなると、手動でindex.htmlにアセットを含めていくのは大変になる。しかしこれを楽にするプラグインがいくつかある

準備

▼ src/print.js (新規作成)

export default function printMe() {
  console.log('I get called from print.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());

▼ dist/index.html

<!doctype html>
  <html>
    <head>
      <title>Output Management</title>
      <script src="./print.bundle.js"></script>
    </head>
    <body>
      <script src="./app.bundle.js"></script>
    </body>
  </html>

エントリーポイントとアウトプットの設定を修正

  • src/print.js を新しくエントリーポイントに含める
  • エントリーポイント名に基づいて動的に出力ファイル名を生成するようにする

▼ webpack.config.js

const path = require('path');

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

yarn build を実行して、/dist フォルダにファイルが生成されちゃんと動作すればOK。

ただ問題点として、エントリーポイントの名前が変わったり、新しく追加する場合、アウトプットされるファイルは自動だが、htmlファイル側は都度読み込むファイル名を手動で更新する手間が出てしまう。

しかし HtmlWebpackPlugin を使えば解決できる。

HtmlWebpackPlugin

インストール

yarn add html-webpack-plugin --dev

▼ webpack.config.js

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

module.exports = {
  // 略
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'タイトルを指定できる',
    }),
  ],
};

yarn build 実行する。
出力されたhtmlを見ると、自動でjsが読み込まれて、指定した title になっているのが分かる。

▼ dist/index.html の中身

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>タイトルを指定できる</title>
  </head>
  <body>
  <script type="text/javascript" src="app.bundle.js"></script><script type="text/javascript" src="print.bundle.js"></script></body>
</html>

より詳しい設定については html-webpack-pluginリポジトリ参照。

github.com

またデフォルトのテンプレートに加えていくつかの追加機能を提供する html-webpack-template も参考に。

github.com

テンプレート機能を試してみる

必要なものは、

  • webpack.config.js の修正
  • templateファイルの作成

▼ webpack.config.js

module.exports = {
  // 略
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Webpack入門 vol.3',
      filename: 'webpack.html',
      template: './src/index.html',
      description: 'Webpack入門 vol.3 についてのページです'
    }),
  ],
};

templateファイルはデフォルトで lodashtemplate 構文が使える。

▼ src/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <h1><%= htmlWebpackPlugin.options.title %></h1>
    <p><%= htmlWebpackPlugin.options.description %></p>
  </body>
</html>

出力結果

▼ dist/webpack.html (指定したfilename になっている)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Webpack入門 vol.3</title>
  </head>
  <body>
    <h1>Webpack入門 vol.3</h1>
    <p>Webpack入門 vol.3 についてのページです</p>
  <script type="text/javascript" src="app.bundle.js"></script><script type="text/javascript" src="print.bundle.js"></script></body>
</html>

clean-webpack-plugin/dist フォルダの掃除

/dist フォルダにはこれまで出力されたファイルがどんどんと積み重なって、不要なファイルもそのままになっている。

clean-webpack-plugin を使えば、ビルド時に、指定フォルダをまるごと削除できる。 https://www.npmjs.com/package/clean-webpack-plugin

インストール

yarn add clean-webpack-plugin --dev

▼ webpack.config.js

// 略
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  // 略
  plugins: [
    new CleanWebpackPlugin(['dist']), // 追加
    new HtmlWebpackPlugin({
      title: 'Webpack入門 vol.3',
      filename: 'webpack.html',
      template: './src/index.html',
      description: 'Webpack入門 vol.3 についてのページです'
    }),
  ],
};

yarn build すると、/dist フォルダがまるっと削除されて、そのあとに再び /dist フォルダが生成されてファイルが出力されるのが確認できる。


そのほか、バンドル前とバンドル後のファイルのマッピングができる WebpackManifestPlugin についてのことが書いてあるが、すぐには使わなそうなのでスルーします (下記記事に参考になりそうな使い方が書いてあります)

qiita.com