【webpack5】html-webpack-pluginを使ってhtmlファイルを出力する【web制作】

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

はじめに

前回はclean-webpack-pluginを使ってコンパイル毎に出力先フォルダ内を削除するやり方について紹介しました。

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

今回はhtml-webpack-pluginを使ってhtmlファイルを出力する方法について紹介します。

webpackはいろんなファイルをバンドルすることができますが、htmlファイルはバンドルさせずに個別に出力させたいですよね。

html-webpack-pluginを使えば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のファイル名はエントリポイントにするjsファイルと同じ名前にしておくと後々扱いやすいのでそのようにしています。

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

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

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

スポンサーリンク

ファイル内容

今回は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>

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');		//	追加

module.exports = (outputFile) => ({
	entry: {
		index: './src/js/index.js',
		another: './src/js/another.js',
	},

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

	plugins: [
		new CleanWebpackPlugin(),
		new HtmlWebpackPlugin({						//	追加
			inject: 'body',
			filename: 'index.html',
			template: './src/index.html',
			chunks: ['index'],
		}),
	],
});
スポンサーリンク

html-webpack-pluginオプション

html-webpack-pluginの処理を定義しました。

今回定義したオプションについてまとめておきます。

オプション内容
inject‘body’指定したバンドルファイルの読み込み(scriptタグ)をhtmlファイルのどこに配置させるかを設定する
‘head’:<head>タグの一番下に配置
‘body’:<body>タグの一番下に配置
filename‘index.html’distフォルダに出力するhtmlのファイル名を設定
template‘./src/index.html’読み込ませるhtmlファイルの相対パスまたは絶対パスを設定
chunks[‘index’]entryオプションのキーを指定することで、読み込ませるバンドルファイルを設定できる
スポンサーリンク

コンパイルする

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

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

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

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

PS C:\Users\shuuk\OneDrive\デスクトップ\test> npx webpack --config ./webpack.dev.js
asset ./js/index.js 3.54 KiB [emitted] (name: index) 1 related asset
asset index.html 322 bytes [emitted]
asset ./js/another.js 250 bytes [emitted] (name: another) 1 related asset
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 195 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>

injectオプションで指定したように<body>タグの一番下にバンドルファイルが配置されているのが分かります。

ちなみにinjectオプションを‘head’にしてコンパイルした場合はこんな感じ。

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>
<script defer src="./js/index.js"></script></head>
<body>
  <h1>index.htmlです</h1>
</body>
</html>
スポンサーリンク

複数のhtmlファイルを出力させる

html-webpack-pluginを使ってhtmlファイルを出力させることができました。

続いて複数のhtmlファイルを出力させるやり方について説明します。

複数のhtmlファイルを出力させるにはHtmlWebpackPluginを複数記述します。

  // 省略

	plugins: [
		//  省略

		new HtmlWebpackPlugin({
			inject: 'body',
			filename: 'index.html',
			template: './src/index.html',
			chunks: ['index'],
		}),

		new HtmlWebpackPlugin({					//	追加
			inject: 'body',
			filename: 'another.html',
			template: './src/another.html',
			chunks: ['another'],
		}),
	],

複数のhtmlファイルの分だけHtmlWebpackPluginを記述すればいいのですが、htmlファイルが大量になってくると記述するのも面倒ですよね。

複数のhtmlファイルを動的に出力するやり方については以下のやり方を参考にしてください。

スポンサーリンク

画像の読み込みがうまくいかない

ここまでで複数のhtmlファイルを出力するやり方について説明しました。

html-webpack-pluginを使用すれば簡単にhtmlファイルを出力できることが分かったと思います。

ただし1点注意として、html-webpack-pluginだけではhtmlファイル内の<img>タグやcssで指定した画像等の読み込みが上手くいきません。

原因としてはwebpackが画像等のパス指定を検出して依存関係を解決してくれないためのようです。

これらの依存関係を解決するにはまた別のプラグインやローダーを使用する必要があります。

こちらを参照してください。

スポンサーリンク

おわりに

以上html-webpack-pluginを使ってhtmlファイルを出力する方法について紹介しました。

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

htmlファイルを個別に出力させたいと思っている方は参考にしてください。

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

コメント

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