webpackの次のバージョンで入るassetModulesの紹介

2020 / 06 / 02

Edit
🚨 This article hasn't been updated in over a year
💁‍♀️ This post was copied from Hatena Blog

この機能が導入されることにより、{raw/file/url}-loader が不要となります。 webpack@4 でも使えますが、まだ実験的フェーズです。

Documentation

Asset Modules | webpack webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, ...

PR

add experimental asset support by hiroppy · Pull Request #8983 · webpack/webpack module.exports = { output: { assetModuleFilename: "images/[hash][ext]" }, module: { ru...

モジュールタイプと以前との対応表

  • asset/resource -> file-loader
  • asset/inline -> url-loader
  • asset/source -> raw-loader
  • asset -> asset/resourceasset/inlineを自動選択する(閾値: 8kb)

使い方

実験フラグをオンにする。

// webpack.config.js
module.exports = {
  experiments: {
    asset: true,
  },
};

アセットを出力する (file-loader)

別ディレクトリにファイルを出力しそのファイルパスを返す。 output.assetModuleFilenameに出力ファイル名を指定することができる。

// webpack.config.js
module.exports = {
  output: {
    assetModuleFilename: "images/[hash][ext]",
  },
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        type: "asset/resource",
      },
    ],
  },
};
// src/index.js
import foo from "./images/foo.png";

console.log(foo);
// /dist/images/151cfcfa1bd74779aadb.png
img.src = foo;

データ URI を出力する (url-loader)

Base64 アルゴリズムを使い出力される文字列を返す。(カスタマイズ可能)

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif|svg)$/,
        type: "asset/inline",
      },
    ],
  },
};
// src/index.js
import foo from "./images/foo.svg";

console.log(foo);
// data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDo...vc3ZnPgo=

block.style.background = `url(${foo})`;

ソースを出力する (raw-loader)

ソースコードの中身を返す。

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.txt/,
        type: "asset/source",
      },
    ],
  },
};
// src/index.js
import foo from "./foo.txt";

console.log(foo);
// hello!
block.textContent = foo;

自動的に選択させる

ファイルの大きさにより、自動的にasset/resourceasset/inlineの実行を決定する。 8kb 以下の場合は、inline となりそれ以上は resouce となる。

閾値を変えたい場合は、parser.dataUrlCondition.maxSizeを指定することができる。

module.exports = {
  output: {
    assetModuleFilename: "images/[hash][ext]",
  },
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024, // 4kb
          },
        },
      },
    ],
  },
};