shou.com
JP / EN

webpack 画像 バンドルのあれこれ

Wed Mar 4, 2020
Wed Mar 4, 2020

webpackで画像ファイルをバンドルする方法は2つあります。

  • 画像ファイルをDateUrl化する方法
    • 画像サイズは小さいでも個数が多いやつに使う
    • 例) アイコンとか
  • 単純に画像ファイルのパスを管理する方法
    • 画像サイズが大きく個数も少ないやつに使う
    • 例) 背景画像とか

画像ファイルをDateUrl化する方法

url-loaderを使うことで、画像ファイルをDataUrl化して、.jsファイルの一部として取り込めます。

インストール

1
$ npm install --save-dev webpack webpack-cli url-loader

webpack.config.jsの設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!-- webpack.config.js -->

module.exports = {
    entry: './src/index.js',
    output: {
        path: `${__dirname}/public`,
        filename: 'main.js'
    },
    devServer: {
        contentBase: `${__dirname}/public`,
    },
    module: {
        rules: [
            {
                test: /\.(gif|png|jpg)$/,
                loader: 'url-loader'
            }
        ],
    }
};

url-loaderを使うのはアイコンなどの利用が多いので、index.jsに以下のようにimportして、sass側で画像を指定します。

1
2
3
<!-- index.js -->

import './assets/images/logo.svg';

sassで使う場合は普通に

1
2
3
account-icon::after {
    background-image: url("../images/logo.svg")
}

JavaScriptで画像を出力する場合は、コードを見た方が早いと思うので、こんな感じ。

1
2
3
4
5
6
7
8
// Logo
import logo from './assets/images/logo.svg';
window.addEventListener('DOMContentLoaded', function () {
    const headerLogo = document.createElement('img');
    headerLogo.src = logo;
    headerLogo.alt = 'logo';
    siteHeader.appendChild(headerLogo);
})

単純に画像ファイルのパスを管理する方法

file-loaderはファイルをバンドルせずに外部ファイルの参照を保つためのローダーです。

インストール

1
$ npm install --save-dev webpack webpack-cli file-loader

webpack.config.jsの設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- webpack.config.js -->

module.exports = {
    entry: './src/index.js',
    output: {
        path: `${__dirname}/public`,
        filename: 'main.js'
    },
    devServer: {
        contentBase: `${__dirname}/public`,
    },
    module: {
        rules: [
            {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            limit: 51200,
                            name: '../images/[name].[ext]'
                        }
                    }
                ]
            }
        ],
    }
};

options配下のlimitパラメータは、ファイルをDateUrl形式にするかファイルにするかを決める閾値をバイトで単位で表します。上記の場合だと画像サイズが50KB以上であれば、これを../images/[name].[ext]のような名前で出力しなさいという意味になります。

  • path: リソースへのパス
  • name: 元ファイルへのベース名
  • ext: 元のファイルの拡張子
  • hash: データ内容に応じたハッシュ値

参照する方法は、url-loaderと一緒。

1
2
3
<!-- index.js -->

import './assets/images/backgroudimage.jpg';

sassは普通に

1
background-image: url("../images/backgroudimage.jpg");

閾値を超えた画像ファイルはファイル出力

例)

50KB以下の画像はDateUrl化して、50KB以上はファイル出力。みたいな形にして切り替える場合は、optionsを設定すればいい。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
module: {
    rules: [
        {
            test: /\.(svg|png|jpe?g)$/,
            loader: 'url-loader',
            options: {
                limit: 51200,
                name: '../images/[name].[ext]'
            }
        }
    ],
}
See Also