はじめに
前回はhtml-webpack-pluginを使ってhtmlファイルを出力する方法について紹介しました。
まだの方はこちらを参考にしてください。
今回はhtml-loaderとAsset Modulesを使って画像やフォントのアセットファイルを使用できるようにするやり方を紹介します。
htmlやcssでは画像の読み込みやフォントの設定をするかと思います。
ですがそのままでは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を使用して依存関係を解決しながらコンパイルするようにします。
webpack4までは、Asset Modulesではなく、raw-loaderやurl-loader、style-loaderなどのローダーを使用してアセットファイルの依存関係を解決していました。
webpack5ではAsset Modulesのみで同様のことを実現できます。
ディレクトリ構成
今回のディレクトリ構成は以下です。
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ファイルを動的に出力するやり方について紹介します。
コメント