はじめに
前回はclean-webpack-pluginを使ってコンパイル毎に出力先フォルダ内を削除するやり方について紹介しました。
まだの方はこちらを参考にしてください。
今回はhtml-webpack-pluginを使ってhtmlファイルを出力する方法について紹介します。
webpackはいろんなファイルをバンドルすることができますが、htmlファイルはバンドルさせずに個別に出力させたいですよね。
html-webpack-pluginを使えばhtmlファイルを個別に出力させることができるようになります。
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を使って画像やフォントのアセットファイルを使用できるようにするやり方を紹介します。
コメント