webpackでSassファイル内の画像をバンドルする

webpackのSass内にある画像をバンドルする方法として、webpack5から利用できるassetモジュールを使ってみます。

サンプルコード

webpackでSassファイルをバンドルする方法は以前記事を投稿していますので、そちらをご確認ください。

プロジェクトでpackage.jsonを作成して、使用するプラグインをインストールします。

npm install webpack webpack-cli style-loader css-loader --save-dev

プロジェクトディレクトリ内にsrcディレクトリを作成して、その中にindex.jsとstyle.scssを作成します。

index.js

import "./style.scss";

style.scss

html {
  background: url(cat.jpg);

  &:after {
    content: '';
    display: block;
    width: 30px;
    height: 22px;
    background: url(mail.png);
  }
}

srcディレクトリ内にstyle.scssから読み込んでいるcat.jpgmail.pngを設置します。
これで一通りの準備が完了しました。

asset/inline

asset/inlineはwebpack4以下ではurl-loaderを使って実装していた処理で、画像のデータURIを出力できるようになります。

webpack.config.jsで以下のように設定します。

module.exports = {
  mode: "production",
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          "sass-loader"
        ]
      },
      {
        test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
        type: "asset/inline"
      }
    ]
  }
};

ビルドを行ってみると、画像をバンドルすることができました。
asset/inlineのデモページ

asset/resource

asset/resourceはwebpack4以下ではfile-loaderを使って実装していた処理で、画像をバンドルせずに外部ファイルとして出力できるようになります。

webpack.config.jsを以下のように変更します。

module.exports = {
  mode: "production",
  output: {
    assetModuleFilename: '[name][ext][query]'
  },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          "sass-loader"
        ]
      },
      {
        test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
        type: "asset/resource"
      }
    ]
  }
};

注意点として、16〜19行目の設定のみだと出力する画像ファイル名がハッシュ値になってしまうため、3〜5行目で出力ファイル名を元のファイル名と同じになるように設定しています。
asset/resourceのデモページ

asset

assetはファイルサイズに応じて前述のasset/inlineとasset/resourceを自動選択して出力できるようになります。

webpack.config.jsで以下のように変更します。

module.exports = {
  mode: "production",
  output: {
    assetModuleFilename: '[name][ext][query]'
  },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          "sass-loader"
        ]
      },
      {
        test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
        type: "asset"
      }
    ]
  }
};

8kb未満の場合はasset/inline、それ以外はasset/resourceとして扱われます。
assetのデモページ

assetの自動選択のサイズを変更することもできます。

module.exports = {
  mode: "production",
  output: {
    assetModuleFilename: '[name][ext][query]'
  },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          "sass-loader"
        ]
      },
      {
        test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024 // 4kb
          }
        }
      }
    ]
  }
};

参考サイト

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2021年9月
 1234
567891011
12131415161718
19202122232425
2627282930