Webページ作成では画像ファイルを取り扱う事はよくあります。
webpack実行時に、使用する画像ファイルもdistファイルに出力されると便利です。
今回はwebpack実行時に、使用する画像ファイルをdistディレクトリへ出力させます。
なお、前回までの内容の続きになります。
概要
今までは nodejs のパッケージを使用して、cssファイルのような jsファイルとは違うファイルをバンドルしていました。webpackではイメージ画像の類(アセットファイル)はローダーを使用せずともバンドルが可能です。
構成
今回はサンプルとしてsrcディレクトリ以下に image ディレクトリを作成し、このディレクトリに適当に2つの画像ファイルを配置しました。なお、ディレクトリ名やファイル名は任意で構いません。
また、jsディレクトリ以下に image_list.js ファイルを作成しました。なお、こちらもファイル名は任意で構いません。
.
├── node_modules
├── package-lock.json
├── package.json
├── src
│ ├── image
│ │ ├── bg_image_org.png
│ │ └── play_icon.png
│ ├── js
│ │ ├── index.js
│ │ ├── test.mjs
│ │ └── image_list.js
│ ├── css
│ │ └── style.css
│ └── index.html
└── webpack.config.js
style.css
今回は cssから、画像ファイル bg_image_org.png を background-image プロパティを使用して読み込ませます。
.box {
background-image: url(../image/bg_image_org.png);
}index.html
index.htmlからは play_icon.pngをimgタグを使用して読み込ませます。
<div class="box">
<h1>Hello, Webpack!</h1>
<img src="image/play_icon.png">
</div>image_list.js
新たに作成した image_list.js にはバンドルさせたい画像ファイルをimportさせます。
今回は play_icon.png を import します。なお、bg_image_org.pngをimportさせない理由は後ほど説明します。
import '../image/play_icon.png'webpackの設定
webpack.config.js を以下のように修正します。
'use strict'
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: 'development',
entry: './src/js/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: "image/[name][ext]",
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new MiniCssExtractPlugin()
],
module: {
rules: [
{
test: /\.(css)$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
// Interprets `@import` and `url()` like `import/require()` and will resolve them
loader: 'css-loader'
}
]
},
{
test: /\.(png|jpg|gif|svg)$/,
type: "asset/resource"
}
]
}
}説明
今回は output に assetModuleFilename を指定してイメージ画像の出力先を指定します。
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: "image/[name][ext]",
},そして、画像ファイルの拡張子をバンドルさせるルールを追記します。
module: {
rules: [
{
....(省略)
},
{
test: /\.(png|jpg|gif|svg)$/,
type: "asset/resource"
}
]
}webpackの実行
webpackを実行します。
npx webpackdistディレクトリは以下のようになります。imageディレクトリが作成され、そのディレクトリ以下に画像ファイルが存在する事が分かります。
dist
├── image
│ ├── bg_image_org.png
│ └── play_icon.png
├── index.html
├── main.css
└── main.js
dist以下のindex.htmlをブラウザで表示させます。

適当な画像を使用しているので少し分かりにくいですが、三角アイコンはimgタグを使用して読み込んだ画像 play_icon.png になります。
背景画像はbackground-image プロパティを使用して読み込んだ画像 bg_image_org.png になります。
background-image プロパティ
なぜ、background-image プロパティを使用して読み込んだ画像ファイル bg_image_org.png は、image_list.js に imoprtを記載しなくても良いかというと、index.js が cssファイル(style.css)をimportしているからです。style.cssは bg_image_org.png を background-image プロパティを使用して読み込んでいます。この為、bg_image_org.png はバンドル対象になります。
一方、index.html は imgタグを使用して画像ファイル play_icon.png を読み込んでいますが、index.htmlはindex.jsからimportされていません。したがって、index.htmlでimgタグを使用している画像ファイルはバンドル対象になりません。なので今回は、image_list.js を作成し、image_list.js からplay_icon.pngをimportし、さらに index.js が image_list.js を読み込むようにしました。これで index.jsからimportを辿って画像ファイルをバンドルさせる事が出来ます。
最後に
特にありません。