url-loader vs raw-loader vs image-webpack-loader vs file-loader
Webpack アセット処理ローダーの比較と移行ガイド
url-loaderraw-loaderimage-webpack-loaderfile-loader類似パッケージ:

Webpack アセット処理ローダーの比較と移行ガイド

file-loaderimage-webpack-loaderraw-loaderurl-loader は、Webpack 4 以前の環境でアセット(画像、テキスト、バイナリファイルなど)を処理するために使われていたローダーパッケージ群です。これらはそれぞれ、ファイルの出力、Base64 インライン化、生文字列読み込み、画像最適化といった異なる役割を担っていました。ただし、Webpack 5 以降では「Asset Modules」という組み込み機能が導入され、これらのパッケージの多くは非推奨となっています。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
url-loader5,560,5751,402-45年前MIT
raw-loader3,920,153845-55年前MIT
image-webpack-loader99,3782,0233.56 MB81-MIT
file-loader01,851-15年前MIT

Webpack ローダー比較: file-loader、image-webpack-loader、raw-loader、url-loader

Webpack を使ったフロントエンド開発では、画像やフォント、テキストファイルなどのアセットをどう扱うかが重要な設計ポイントです。この記事では、file-loaderimage-webpack-loaderraw-loaderurl-loader の4つのパッケージについて、それぞれの役割と実際の使いどころを詳しく解説します。

⚠️ 重要な注意点:これらのパッケージは非推奨です

まず最初に確認すべき重要な事実があります — これら4つのパッケージはすべて公式に非推奨(deprecated)されています。Webpack 5 以降では、Asset Modules という組み込み機能が提供されており、これらのローダーの機能をネイティブで置き換えられるようになっています。

  • file-loadertype: 'asset/resource'
  • url-loadertype: 'asset/inline' または type: 'asset'
  • raw-loadertype: 'asset/source'

したがって、新規プロジェクトではこれらのパッケージを使用すべきではありません。ただし、既存の Webpack 4 プロジェクトを保守している開発者にとっては、まだ関連知識が必要な場合があります。以下では、そのような文脈での技術的比較を行います。

📁 アセット処理の基本戦略

file-loader: ファイルを出力ディレクトリにコピーし、パスを返す

file-loader は、指定されたファイルをビルド出力ディレクトリにコピーし、そのファイルへの公開パス(例: /static/media/logo.a1b2c3.png)を JavaScript モジュールとしてエクスポートします。

// webpack.config.js (Webpack 4)
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[hash].[ext]',
              outputPath: 'assets/'
            }
          }
        ]
      }
    ]
  }
};

// app.js
import logoPath from './logo.png';
console.log(logoPath); // => "/static/media/logo.a1b2c3.png"
const img = document.createElement('img');
img.src = logoPath;
document.body.appendChild(img);

この方式は、大きな画像やフォントなど、Base64 インライン化に向かないアセットに適しています。

url-loader: 小さいファイルを Base64 でインライン化、大きいファイルは file-loader に委譲

url-loader は、ファイルサイズが閾値以下の場合に Base64 文字列としてバンドル内に埋め込み、それ以上なら file-loader に処理を委譲します。

// webpack.config.js (Webpack 4)
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192, // 8KB 以下なら Base64 化
              fallback: 'file-loader',
              name: '[name].[hash].[ext]'
            }
          }
        ]
      }
    ]
  }
};

// app.js
import smallIcon from './icon-small.png'; // <=8KB → Base64 string
import largeImage from './photo-large.jpg'; // >8KB → file path

console.log(smallIcon); // => "data:image/png;base64,iVBORw0KG..."
console.log(largeImage); // => "/static/media/photo-large.d4e5f6.jpg"

HTTP リクエスト数を減らしたい小さなアイコンや SVG に最適です。

raw-loader: ファイルの内容をそのまま文字列として読み込む

raw-loader は、ファイルの中身を改変せずに UTF-8 文字列として読み込みます。主にテキストベースのアセット(例: .txt, .md, .glsl)に使われます。

// webpack.config.js (Webpack 4)
module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: 'raw-loader'
      }
    ]
  }
};

// app.js
import terms from './terms.txt';
console.log(typeof terms); // => "string"
document.getElementById('terms').textContent = terms;

これは、HTML や JavaScript 内に動的にテキストコンテンツを埋め込む必要がある場合に便利です。

image-webpack-loader: 画像の最適化専用ローダー

image-webpack-loader は、他のローダー(通常は file-loader または url-loader)の後にチェーンして使うことで、画像を圧縮・最適化します。単体では使えません。

// webpack.config.js (Webpack 4)
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        use: [
          {
            loader: 'file-loader',
            options: { name: '[name].[hash:8].[ext]' }
          },
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: { progressive: true, quality: 65 },
              optipng: { enabled: false },
              pngquant: { quality: [0.65, 0.8], speed: 4 },
              gifsicle: { interlaced: false }
            }
          }
        ]
      }
    ]
  }
};

// app.js
import optimizedImage from './photo.jpg';
// 出力される画像ファイルは自動的に圧縮されている

このローダーは、バンドルサイズを削減しつつ画質を維持したい場合に非常に効果的です。

🔗 ローダーチェーンの実際の動作順序

Webpack のローダーは 右から左(または配列の末尾から先頭へ)に適用されます。つまり、以下のように書くと:

use: ['file-loader', 'image-webpack-loader']

実際の処理順は:

  1. 最初に image-webpack-loader が画像を最適化
  2. 次に file-loader が最適化済みの画像を出力ディレクトリに保存

となります。順番を間違えると、最適化前の画像が保存されてしまうため注意が必要です。

🆚 各ローダーの用途と代替手段(Webpack 5 以降)

ローダー主な用途Webpack 5 での代替
file-loaderファイルを出力しパスを返すtype: 'asset/resource'
url-loader小さいファイルを Base64 化type: 'asset' + parser.dataUrlCondition.maxSize
raw-loaderファイル内容を文字列で取得type: 'asset/source'
image-webpack-loader画像の圧縮・最適化依然として必要(ただし非推奨ではない)

💡 注:image-webpack-loader非推奨になっていません。Webpack 5 の Asset Modules はファイルの出力方法を制御するものであり、内容の最適化は別途必要です。そのため、image-webpack-loader は今でも有効な選択肢です。

🛠️ 実際の移行例:Webpack 4 → Webpack 5

Webpack 4(非推奨ローダー使用)

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg)$/,
        use: [
          'file-loader',
          'image-webpack-loader'
        ]
      },
      {
        test: /\.txt$/,
        use: 'raw-loader'
      }
    ]
  }
};

Webpack 5(Asset Modules 使用)

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg)$/,
        type: 'asset/resource',
        generator: {
          filename: 'assets/[name].[hash:8][ext]'
        },
        use: [
          {
            loader: 'image-webpack-loader',
            options: { /* ... */ }
          }
        ]
      },
      {
        test: /\.txt$/,
        type: 'asset/source'
      }
    ]
  }
};

このように、file-loaderraw-loader は完全に置き換えられますが、image-webpack-loader は引き続き使用可能です。

💡 結論:どうすべきか?

  • 新規プロジェクト:Webpack 5+ を使用し、Asset Modules(asset/resource, asset/source, asset)を活用しましょう。image-webpack-loader だけは必要に応じて併用可能です。
  • 既存の Webpack 4 プロジェクト:メンテナンス中であれば、これらのローダーを使い続けるのは問題ありませんが、アップグレード計画を立てることを強く推奨します。
  • 画像最適化が必要な場合image-webpack-loader は今でも有効なツールです。ただし、最近では sharpsquoosh といった代替手段も注目されています。

これらのローダーはかつてフロントエンド開発の標準でしたが、現在はよりシンプルで強力な Webpack のネイティブ機能に取って代わられています。技術的負債を最小限に抑えるためにも、新しい標準への移行を検討してください。

選び方: url-loader vs raw-loader vs image-webpack-loader vs file-loader

  • url-loader:

    url-loader は、小さいファイルを Base64 文字列としてバンドル内に埋め込み、大きいファイルは file-loader に委譲するハイブリッド処理を提供していました。Webpack 5 では type: 'asset'parser.dataUrlCondition.maxSize 設定で同様の振る舞いが実現でき、このパッケージも非推奨です。新規開発ではネイティブの Asset Modules を使うのが正しい選択です。

  • raw-loader:

    raw-loader は、テキストファイル(.txt, .md, .glsl など)の内容を UTF-8 文字列として読み込む用途に使われていました。Webpack 5 では type: 'asset/source' で同等の機能が提供されており、このパッケージは非推奨です。新規プロジェクトでは Asset Modules を使用し、既存プロジェクトでのみ限定的に利用を検討してください。

  • image-webpack-loader:

    image-webpack-loader は、画像ファイルを圧縮・最適化する専用ローダーです。他のローダー(例: file-loader)とチェーンして使用し、バンドルサイズを削減します。このパッケージは非推奨ではなく、Webpack 5 でも引き続き利用可能です。ただし、最適化ロジック自体は Webpack のコア機能ではないため、sharpsquoosh といった代替手段も検討に値します。

  • file-loader:

    file-loader は、画像やフォントなどのバイナリファイルをビルド出力ディレクトリにコピーし、その公開パスをモジュールとして返す用途に使われていました。ただし、Webpack 5 以降では type: 'asset/resource' で完全に置き換え可能であり、新規プロジェクトでの使用は避けるべきです。既存の Webpack 4 プロジェクトを保守している場合のみ考慮してください。

url-loader のREADME

npm node deps tests chat size

url-loader

A loader for webpack which transforms files into base64 URIs.

Getting Started

To begin, you'll need to install url-loader:

$ npm install url-loader --save-dev

url-loader works like file-loader, but can return a DataURL if the file is smaller than a byte limit.

index.js

import img from './image.png';

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192,
            },
          },
        ],
      },
    ],
  },
};

And run webpack via your preferred method.

Options

NameTypeDefaultDescription
limit{Boolean|Number|String}trueSpecifying the maximum size of a file in bytes.
mimetype{Boolean|String}based from mime-typesSets the MIME type for the file to be transformed.
encoding{Boolean|String}base64Specify the encoding which the file will be inlined with.
generator{Function}() => type/subtype;encoding,base64_dataYou can create you own custom implementation for encoding data.
fallback{String}file-loaderSpecifies an alternative loader to use when a target file's size exceeds the limit.
esModule{Boolean}trueUse ES modules syntax.

limit

Type: Boolean|Number|String Default: undefined

The limit can be specified via loader options and defaults to no limit.

Boolean

Enable or disable transform files into base64.

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: false,
            },
          },
        ],
      },
    ],
  },
};

Number|String

A Number or String specifying the maximum size of a file in bytes. If the file size is equal or greater than the limit file-loader will be used (by default) and all query parameters are passed to it.

Using an alternative to file-loader is enabled via the fallback option.

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192,
            },
          },
        ],
      },
    ],
  },
};

mimetype

Type: Boolean|String Default: based from mime-types

Specify the mimetype which the file will be inlined with. If unspecified the mimetype value will be used from mime-types.

Boolean

The true value allows to generation the mimetype part from mime-types. The false value removes the mediatype part from a Data URL (if omitted, defaults to text/plain;charset=US-ASCII).

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              mimetype: false,
            },
          },
        ],
      },
    ],
  },
};

String

Sets the MIME type for the file to be transformed.

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              mimetype: 'image/png',
            },
          },
        ],
      },
    ],
  },
};

encoding

Type: Boolean|String Default: base64

Specify the encoding which the file will be inlined with. If unspecified the encoding will be base64.

Boolean

If you don't want to use any encoding you can set encoding to false however if you set it to true it will use the default encoding base64.

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              encoding: false,
            },
          },
        ],
      },
    ],
  },
};

String

It supports Node.js Buffers and Character Encodings which are ["utf8","utf16le","latin1","base64","hex","ascii","binary","ucs2"].

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              encoding: 'utf8',
            },
          },
        ],
      },
    ],
  },
};

generator

Type: Function Default: (mimetype, encoding, content, resourcePath) => mimetype;encoding,base64_content

You can create you own custom implementation for encoding data.

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|html)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              // The `mimetype` and `encoding` arguments will be obtained from your options
              // The `resourcePath` argument is path to file.
              generator: (content, mimetype, encoding, resourcePath) => {
                if (/\.html$/i.test(resourcePath)) {
                  return `data:${mimetype},${content.toString()}`;
                }

                return `data:${mimetype}${
                  encoding ? `;${encoding}` : ''
                },${content.toString(encoding)}`;
              },
            },
          },
        ],
      },
    ],
  },
};

fallback

Type: String Default: 'file-loader'

Specifies an alternative loader to use when a target file's size exceeds the limit set in the limit option.

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              fallback: require.resolve('responsive-loader'),
            },
          },
        ],
      },
    ],
  },
};

The fallback loader will receive the same configuration options as url-loader.

For example, to set the quality option of a responsive-loader above use:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              fallback: require.resolve('responsive-loader'),
              quality: 85,
            },
          },
        ],
      },
    ],
  },
};

esModule

Type: Boolean Default: true

By default, file-loader generates JS modules that use the ES modules syntax. There are some cases in which using ES modules is beneficial, like in the case of module concatenation and tree shaking.

You can enable a CommonJS module syntax using:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              esModule: false,
            },
          },
        ],
      },
    ],
  },
};

Examples

SVG

SVG can be compressed into a more compact output, avoiding base64. You can read about it more here. You can do it using mini-svg-data-uri package.

webpack.config.js

const svgToMiniDataURI = require('mini-svg-data-uri');

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              generator: (content) => svgToMiniDataURI(content.toString()),
            },
          },
        ],
      },
    ],
  },
};

Contributing

Please take a moment to read our contributing guidelines if you haven't yet done so.

CONTRIBUTING

License

MIT