【webpack5】html-webpack-pluginで複数のhtmlファイルを動的に出力する【web制作】

html/css
この記事は約12分で読めます。
スポンサーリンク

はじめに

前回はhtml-loaderとAsset Modulesを使って画像やフォントのアセットファイルを使用できるようにするやり方を紹介しました。

まだの方はこちらを参考にしてください。

今回はhtml-webpack-pluginで複数のhtmlファイルを動的に出力するやり方について紹介します。

web制作ではページごとにhtmlファイルを複数作成するかと思います。

ですがhtml-webpack-pluginは複数のhtmlファイルを動的に出力するオプションみたいなものはなく、自分で作るしかありません。

複数のhtmlファイルを扱っている方は参考にしてください。

対象者
  • webpackで複数のhtmlファイルを動的に出力させたい方
  • webpackに興味がある方

webpackの使い方まとめについてはこちら。

web制作をする場合のwebpackのテンプレート紹介についてはこちら。

それでは説明に移ります。

スポンサーリンク

ディレクトリ構成

今回のディレクトリ構成は以下です。

test
├ node_modules
├ src
│ ├ js
│ │ ├ another.js
│ │ └ index.js
│ ├ another.html
│ └ index.html
├ package-lock.json
├ package.json
├ webpack.common.js
├ webpack.dev.js
└ webpack.prod.js

今回はhtmlファイルを2つ用意しました。

html-webpack-pluginを使って複数のhtmlファイルを出力させていきます。

index.htmlではindex.jsをエントリポイントとしたバンドルファイルを読み込ませます。

another.htmlではanother.jsをエントリポイントとしたバンドルファイルを読み込ませます。

エントリポイントにするjsファイルとそれに対するhtmlファイルは同じ名前になっていることに注意してください。

この記事では以下のサイトを参考にしています。

スポンサーリンク

ファイル内容

今回はwebpack.common.js の記述がメインとなるので、それ以外のファイル内容を参考までに示しておきます。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>index.htmlです</h1>
</body>
</html>

another.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>another.htmlです</h1>
</body>
</html>

webpack.dev.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const outputFile = '[name]';

module.exports = merge(common(outputFile), {
  mode: 'development',
  devtool: 'source-map',

});

webpack.prod.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const outputFile = '[name].[chunkhash]';

module.exports = merge(common(outputFile), {
  mode: 'production',

});
スポンサーリンク

プラグインをインストールしよう

コンパイル時にhtmlファイルを出力させるためにhtml-webpack-pluginをインストールする必要があります。

npm i -D html-webpack-plugin

下記コマンドをターミナルで実行してhtml-webpack-pluginをインストールします。

npm i -D html-webpack-plugin

html-webpack-plugin公式

スポンサーリンク

webpack.common.jsを編集する

プラグインのインストールが完了したらwebpack.common.jsを編集していきましょう。

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackWatchedGlobEntries = require('webpack-watched-glob-entries-plugin');

const entries = WebpackWatchedGlobEntries.getEntries([path.resolve(__dirname, './src/js/**/*.js')], {
  ignore: path.resolve(__dirname, './src/js/**/_*.js'),
})();

// 追加
const htmlGlobPlugins = (entries, srcPath) => {
  return Object.keys(entries).map((key) =>
    new HtmlWebpackPlugin({
      inject: 'body',
      filename: `${key}.html`,
      template: `${srcPath}/${key}.html`,
      chunks: [key],
    })
  );
};

module.exports = (outputFile) => ({
  entry: entries,

  output: {
    path: path.resolve(__dirname, './dist'),
    filename: `./js/${outputFile}.js`,
  },

  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        generator: {
	        filename: `./image/[name].[contenthash][ext]`,
        },
        type: 'asset/resource',
      },

      {
        test: /\.html$/i,
        loader: 'html-loader',
      },
    ],
  },

  plugins: [
    new CleanWebpackPlugin(),

    ...htmlGlobPlugins(entries, './src')     //  追加
  ],
});

html-webpack-pluginを複数生成する処理をhtmlGlobPluginsとして追加しました。

処理名は適当に付けたのでなんでもかまいません。

htmlGlobPluginsは以下2つの引数をとります。

項目備考
第一引数objectオブジェクト形式で表される複数のエントリポイント
第二引数string指定したいhtmlファイルまでの相対パス

またpluginsオプションの中でhtmlGlobPluginsに対してスプレッド演算子を用いています。

こちらでエントリポイントを指定した数だけhtml-webpack-pluginを動的に展開しています。

スポンサーリンク

html-webpack-pluginオプション

html-webpack-pluginで複数のhtmlファイルを動的に出力する処理を追加しました。

html-webpack-pluginオプションについて分からない方は以下を参考にしてください。

スポンサーリンク

コンパイルする

設定が完了したのでコンパイルしてみましょう。

以下のコマンドをターミナルから打ち込みます。

npx webpack --config ./webpack.dev.js

以下のようなメッセージが出力されていれば正しく実行できています。

PS C:\Users\shuuk\OneDrive\デスクトップ\test> npx webpack --config ./webpack.dev.js
assets by path ./js/*.js 3.78 KiB
  asset ./js/index.js 3.54 KiB [emitted] (name: index) 1 related asset
  asset ./js/another.js 250 bytes [emitted] (name: another) 1 related asset
assets by path *.html 647 bytes
  asset another.html 325 bytes [emitted]
  asset index.html 322 bytes [emitted]
runtime modules 937 bytes 4 modules
cacheable modules 84 bytes
  ./src/js/index.js 52 bytes [built] [code generated]
  ./src/js/another.js 32 bytes [built] [code generated]
webpack 5.61.0 compiled successfully in 647 ms

複数のhtmlファイルが出力されているはずです。

以下が出力されたhtmlファイルになります。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>index.htmlです</h1>
<script defer src="./js/index.js"></script></body>
</html>

another.js

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>another.htmlです</h1>
<script defer src="./js/another.js"></script></body>
</html>
スポンサーリンク

おわりに

以上html-webpack-pluginで複数のhtmlファイルを動的に出力するやり方について紹介しました。

いかがだったでしょうか。

web制作をされている方で複数のhtmlファイルを扱っている方は参考にしてください。

次回はwebpackでsassをコンパイルするやり方について紹介します。

コメント

タイトルとURLをコピーしました