【webpack5】html-loaderとAsset Modulesを使って画像やフォントのアセットファイルを使用できるようにする【web制作】

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

はじめに

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

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

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

htmlやcssでは画像の読み込みやフォントの設定をするかと思います。

ですがそのままではwebpackがこれらの設定をうまく検出してくれなくて、依存関係を解決してくれないままコンパイルされてしまいます。

画像やフォントのアセットファイルの扱いに困っている方は参考にしてください。

対象者
  • webpackで画像やフォントのアセットファイルを使いたい方
  • webpackに興味がある方

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

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

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

スポンサーリンク

html-loaderとは

html-loaderとはその名前の通りwebpackにhtmlファイルを読み込ませる処理です。

html-loader

webpackに読み込ませることでhtmlファイルに対していろんな処理ができるようになります。

スポンサーリンク

Asset Modulesとは

Asset Modulesとはwebpack5から新たに搭載された標準モジュールの1つです。

Asset Modules

htmlやcssでは以下のように画像の読み込みやフォントの設定をするかと思います。

index.html

<img src="./image/aaa.jpg" alt="aaaの画像" />

style.scss

.image {
	background-image: url('../image/aaa.jpg');
}

そのままwebpackでコンパイルするとこれらのパスの依存関係を解決できずに正しく表示できません。

そこでAsset Modulesを使用して依存関係を解決しながらコンパイルするようにします。

css上の画像ファイルなどの依存関係を解決するには別途css-loaderが必要になってきます。

ここではhtmlの画像ファイルなどの依存関係の解決のみ紹介します。

webpack4までは、Asset Modulesではなく、raw-loaderやurl-loader、style-loaderなどのローダーを使用してアセットファイルの依存関係を解決していました。

webpack5ではAsset Modulesのみで同様のことを実現できます。

Asset Modulesを使用するにあたって、raw-loaderやurl-loader、style-loaderが混在すると二重で処理をすることになってしまい動作がおかしくなるので注意してください。

スポンサーリンク

ディレクトリ構成

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

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

今回はimageフォルダにaaa.jpgという画像を1つ用意しました。

html-loaderとAsset Modulesを使って依存関係を解決しながらwebpackでコンパイルしていきます。

スポンサーリンク

ファイル内容

今回は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>
  <img src="./image/aaa.jpg" alt="aaaの画像" />
</body>
</html>

imgタグaaa.jpgを指定しています。

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',

});
スポンサーリンク

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

webpackにhtmlファイルを読み込ませるためにhtml-loaderをインストールしていきます。

npm i -D html-loader

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

npm i -D html-loader

html-loader公式

スポンサーリンク

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`,
	},

	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(),
		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'],
		}),
	],
});

moduleオプションにhtml-loaderとAsset Modulesの指定を追記しました。

スポンサーリンク

html-loaderの設定

html-loaderの設定を定義しました。

今回定義した設定についてまとめておきます。

オプション内容
test/.html$/i.html の拡張子に対して処理を実行する。
正規表現で記述する。
loader‘html-loader’html-loaderを使用する。

html-loaderにはいくつか指定できるオプションがありますが、特に便利なオプションが無さそうなので指定していません。

スポンサーリンク

Asset Modulesの設定

Asset Modulesの設定を定義しました。

今回定義した設定についてまとめておきます。

オプション内容
test/.(png|jpe?g|gif|svg)$/i指定した拡張子に対して処理を実行する。
正規表現で記述する。
generator.filename‘./image/[name].[contenthash][ext]’出力先の指定。
[name]や[ext]のプレースホルダーを使用できる。
[contenthash]などのハッシュの指定等もできる。
type‘asset/resource’アセットモジュールタイプの指定。
個別にファイルを生成して、そのURLを出力する。

testオプションやgenerator.filenameオプションはご自身の環境に合った拡張子を指定してください。

typeには4つの指定方法があるのでまとめておきます。

asset/resource 以外の指定方法にいまいち使用用途が見つけられないですが念のため。

typeオプション内容
‘asset/resource’個別のファイルを生成し、その URL をエクスポートする。
file-loaderと同じ機能。
‘asset/inline’アセットのデータ URI をエクスポートする。
url-loaderと同じ機能。
‘asset/source’アセットのソースコードをエクスポートする。
raw-loaderと同じ機能。
‘asset’データ URI をエクスポートするか、別のファイルを生成するかを自動的に選択する。
url-loaderでアセットサイズを制限した場合と同じ機能。
スポンサーリンク

コンパイルする

html-loaderとAsset Modulesの設定が完了したのでコンパイルしてみましょう。

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

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

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

PS C:\Users\shuuk\OneDrive\デスクトップ\test> npx webpack --config ./webpack.dev.js
assets by path ./ 178 KiB
  asset ./image/aaa.18c8db99e27a2df03aeb.jpg 174 KiB [emitted] [immutable] [from: src/image/aaa.jpg]
  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 719 bytes
  asset index.html 394 bytes [emitted]
  asset another.html 325 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 552 ms

aaa.jpgファイルがimageフォルダの中に出力されているはずです。

コンパイル後のindex.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>
  <img src="./image/aaa.18c8db99e27a2df03aeb.jpg" alt="aaaの画像" />
<script defer src="./js/index.js"></script></body>
</html>
スポンサーリンク

おわりに

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

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

画像やフォントのアセットファイルの扱いに困っている方は参考にしてください。

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

コメント

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