file-loader、image-webpack-loader、raw-loader、url-loader は、Webpack 4 以前の環境でアセット(画像、テキスト、バイナリファイルなど)を処理するために使われていたローダーパッケージ群です。これらはそれぞれ、ファイルの出力、Base64 インライン化、生文字列読み込み、画像最適化といった異なる役割を担っていました。ただし、Webpack 5 以降では「Asset Modules」という組み込み機能が導入され、これらのパッケージの多くは非推奨となっています。
Webpack を使ったフロントエンド開発では、画像やフォント、テキストファイルなどのアセットをどう扱うかが重要な設計ポイントです。この記事では、file-loader、image-webpack-loader、raw-loader、url-loader の4つのパッケージについて、それぞれの役割と実際の使いどころを詳しく解説します。
まず最初に確認すべき重要な事実があります — これら4つのパッケージはすべて公式に非推奨(deprecated)されています。Webpack 5 以降では、Asset Modules という組み込み機能が提供されており、これらのローダーの機能をネイティブで置き換えられるようになっています。
file-loader → type: 'asset/resource'url-loader → type: 'asset/inline' または type: 'asset'raw-loader → type: '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']
実際の処理順は:
image-webpack-loader が画像を最適化file-loader が最適化済みの画像を出力ディレクトリに保存となります。順番を間違えると、最適化前の画像が保存されてしまうため注意が必要です。
| ローダー | 主な用途 | 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.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg)$/,
use: [
'file-loader',
'image-webpack-loader'
]
},
{
test: /\.txt$/,
use: 'raw-loader'
}
]
}
};
// 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-loader と raw-loader は完全に置き換えられますが、image-webpack-loader は引き続き使用可能です。
asset/resource, asset/source, asset)を活用しましょう。image-webpack-loader だけは必要に応じて併用可能です。image-webpack-loader は今でも有効なツールです。ただし、最近では sharp や squoosh といった代替手段も注目されています。これらのローダーはかつてフロントエンド開発の標準でしたが、現在はよりシンプルで強力な Webpack のネイティブ機能に取って代わられています。技術的負債を最小限に抑えるためにも、新しい標準への移行を検討してください。
url-loader は、小さいファイルを Base64 文字列としてバンドル内に埋め込み、大きいファイルは file-loader に委譲するハイブリッド処理を提供していました。Webpack 5 では type: 'asset' と parser.dataUrlCondition.maxSize 設定で同様の振る舞いが実現でき、このパッケージも非推奨です。新規開発ではネイティブの Asset Modules を使うのが正しい選択です。
raw-loader は、テキストファイル(.txt, .md, .glsl など)の内容を UTF-8 文字列として読み込む用途に使われていました。Webpack 5 では type: 'asset/source' で同等の機能が提供されており、このパッケージは非推奨です。新規プロジェクトでは Asset Modules を使用し、既存プロジェクトでのみ限定的に利用を検討してください。
image-webpack-loader は、画像ファイルを圧縮・最適化する専用ローダーです。他のローダー(例: file-loader)とチェーンして使用し、バンドルサイズを削減します。このパッケージは非推奨ではなく、Webpack 5 でも引き続き利用可能です。ただし、最適化ロジック自体は Webpack のコア機能ではないため、sharp や squoosh といった代替手段も検討に値します。
file-loader は、画像やフォントなどのバイナリファイルをビルド出力ディレクトリにコピーし、その公開パスをモジュールとして返す用途に使われていました。ただし、Webpack 5 以降では type: 'asset/resource' で完全に置き換え可能であり、新規プロジェクトでの使用は避けるべきです。既存の Webpack 4 プロジェクトを保守している場合のみ考慮してください。
A loader for webpack which transforms files into base64 URIs.
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.
| Name | Type | Default | Description |
|---|---|---|---|
limit | {Boolean|Number|String} | true | Specifying the maximum size of a file in bytes. |
mimetype | {Boolean|String} | based from mime-types | Sets the MIME type for the file to be transformed. |
encoding | {Boolean|String} | base64 | Specify the encoding which the file will be inlined with. |
generator | {Function} | () => type/subtype;encoding,base64_data | You can create you own custom implementation for encoding data. |
fallback | {String} | file-loader | Specifies an alternative loader to use when a target file's size exceeds the limit. |
esModule | {Boolean} | true | Use ES modules syntax. |
limitType: Boolean|Number|String
Default: undefined
The limit can be specified via loader options and defaults to no limit.
BooleanEnable 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|StringA 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,
},
},
],
},
],
},
};
mimetypeType: 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.
BooleanThe 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,
},
},
],
},
],
},
};
StringSets 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',
},
},
],
},
],
},
};
encodingType: Boolean|String
Default: base64
Specify the encoding which the file will be inlined with.
If unspecified the encoding will be base64.
BooleanIf 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,
},
},
],
},
],
},
};
StringIt 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',
},
},
],
},
],
},
};
generatorType: 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)}`;
},
},
},
],
},
],
},
};
fallbackType: 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,
},
},
],
},
],
},
};
esModuleType: 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,
},
},
],
},
],
},
};
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()),
},
},
],
},
],
},
};
Please take a moment to read our contributing guidelines if you haven't yet done so.