はじめに
前回はwebpackでsassをコンパイルするやり方ついて紹介しました。
まだの方はこちらを参考にしてください。
今回はwebpackでsassの画像やフォントのアセットファイルの依存関係を解決するやり方ついて紹介します。
webpackでsassをコンパイルするときに画像などのパスの指定が合ってなくてエラーになることを経験した方は多いかと思います。
sassの画像やフォントのアセットファイルの依存関係を解決するやり方が分からない方は参考にしてください。
webpackの使い方まとめについてはこちら。
web制作をする場合のwebpackのテンプレート紹介についてはこちら。
それでは説明に移ります。
画像のパス指定方法
webpackでsassをコンパイルするときに画像のパス指定でエラーになった経験をした方は多いのではないでしょうか?
私も同様のエラーに悩まされた経験があります。
webpackで画像を指定する方法としては大きく分けて以下2つあります。
それぞれのやり方で紹介していきますが、実際に実務で使用する場合は絶対パスで指定するのが一般的です。
ディレクトリ構成
ディレクトリ構成は以下です。
test
├ node_modules
├ dist
│ └ css
├ src
│ ├ image
│ │ └ aaa.jpg
│ ├ js
│ │ └ index.js
│ ├ scss
│ │ ├ flocss
│ │ │ ├ _footer.scss
│ │ │ └ _header.scss
│ │ └ style.scss
│ └ index.html
├ package-lock.json
├ package.json
├ webpack.common.js
├ webpack.dev.js
└ webpack.prod.js
エントリポイントをindex.jsとし、imageフォルダにaaa.jpgを入れました。
こちらの画像を_header.scssから読み込んでいきましょう。
相対パスで指定する
それでは相対パスで_header.scssからaaa.jpgを読み込んでいきます。
webpackとその他Live Sass Compilerなど別コンパイラを使って画像を読み込みさせる場合とでは記述が違うことに注意してください。
_header.scss
.p-header {
// webpackで指定する場合
background-image: url('../image/aaa.jpg');
// その他コンパイラで指定する場合
background-image: url('../../image/aaa.jpg');
}
あまりイメージしにくいかもしれませんが、相対パスで指定する場合webpackでは前者のやり方で記述しないとエラーとなってしまいます。
webpackとその他コンパイラで記述の仕方が変わるのは何が原因でしょうか。
結論としては、webpackとその他コンパイラでは画像などのパスを指定する相対パスの基準位置が変わるからです。(おそらく)
いまいちこの辺りの解説記事等が無く検証不足ですが、相対パスの基準位置について以下のような違いがありそうでした。
webpack | sassをインポートしているエントリポイントが基準 |
その他コンパイラ | 画像の読み込みをさせているsassファイルが基準 |
webpackではsassをインポートしているエントリポイントが相対パスの基準となるので、index.jsから画像までの相対パスを指定しないといけないということですね。
基本的にwebpackでは画像やファイルの読み込みなどには相対パスでの記述はあまりしないかと思います。
こういう考え方もあるんだなー程度に思っておいてください。
絶対パスで指定する
ここまででwebpackで相対パスで画像を読み込む方法を紹介しました。
続いて絶対パスで画像を読み込む方法を紹介します。
絶対パスで指定するためにまずはwebpack.common.jsでresolve.aliasオプションでエイリアスを設定していきましょう。
webpack.common.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackWatchedGlobEntries = require('webpack-watched-glob-entries-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const entries = WebpackWatchedGlobEntries.getEntries([path.resolve(__dirname, './src/js/**/*.js')], {
ignore: path.resolve(__dirname, './src/js/**/_*.js'),
})();
const htmlGlobPlugins = (entries, srcPath) => {
return Object.keys(entries).map(
(key) =>
new HtmlWebpackPlugin({
inject: 'body',
filename: `${key}.html`,
template: `${srcPath}/${key}.html`,
chunks: [key],
})
);
};
module.exports = (outputFile) => ({
entry: entries,
output: {
path: path.resolve(__dirname, './dist'),
filename: `./js/${outputFile}.js`,
},
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [require('autoprefixer')({ grid: true })],
},
},
},
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
},
},
],
},
{
test: /\.html$/i,
loader: 'html-loader',
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
generator: {
filename: `./image/[name].[contenthash][ext]`,
},
type: 'asset/resource',
},
],
},
plugins: [
new CleanWebpackPlugin(),
new WebpackWatchedGlobEntries(),
new MiniCssExtractPlugin({
filename: `./css/${outputFile}.css`,
}),
...htmlGlobPlugins(entries, './src'),
],
// 追加
resolve: {
alias: {
'@image': path.resolve(__dirname, './src/image/'),
},
},
});
追加した記述は以下です。
// 追加
resolve: {
alias: {
'@image': path.resolve(__dirname, './src/image/'),
},
},
エイリアスの設定が完了しました。
上記のように設定することでパスの指定などで@imageと記述されていた場合に以下のようにimageフォルダまでの絶対パスに変換してくれます。
C:\Users\shuuk\OneDrive\デスクトップ\test\src\image
それでは@imageを使って画像の読み込みを指定していきます。
以下のようになります。
_header.scss
.p-header {
background-image: url('@image/aaa.jpg');
}
コンパイルを実行して画像が読み込まれていれば正しく設定できています。
おわりに
以上webpackでsassの画像やフォントのアセットファイルの依存関係を解決するやり方ついて紹介しました。
いかがだったでしょうか。
webpaassの画像やフォントのアセットファイルの依存関係を解決するやり方が分からない方は参考にしてください。
コメント