技術探し

JavaScriptを中心に記事を書いていきます :;(∩´﹏`∩);:

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

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

Documentation

webpack.js.org

PR

github.com

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

  • 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
          },
        },
      },
    ],
  },
};