RitoLabo

webpackインストール後のセットアップパターンまとめ。Babel/ESLint/SASSなどを用いてフロントエンド開発環境を整える

  • 公開:
  • 更新:
  • カテゴリ: webpack
  • タグ: Linux,JavaScript,Webpack,ES6,BABEL,sass,node.js,NPM,CSS,SCSS,ESLint,ES2015

webpackを用いたフロントエンド開発環境構築を行います。環境やインストールについては前回の記事を参考にしてください。

アジェンダ
  1. 最小構成のビルド
  2. トランスコンパイラを用いたコンパイル&複数ファイルのバンドル
    1. Babelのインストール
    2. webpack.config.jsの設定
    3. JSファイル作成
    4. 動作確認
  3. コードテスト(静的コード解析)
    1. ESLintのインストール
    2. webpack.config.jsの設定
    3. .ESLintrcの作成
    4. 動作確認
  4. CSSを出力する
    1. 複数のCSSファイルをバンドルする
    2. CSSファイルをminifyする
    3. SASSファイルをコンパイルする
    4. 画像をbase64エンコードでバンドルする

最小構成のビルド

まずはwebpackを使って最小のビルドを行ってみます。プロジェクトルート以下にJSファイルとHTMLファイルを作成します。構成は以下の通りです。

project_root/
├─ assets
│   └─ js
│     └─ index.js
├─ htdocs
│   ├─ index.html
│   └─ js
│     └─ app.js
├─ node_modules/
├─ package.json
├─ package-lock.json
└─ webpack.config.js

黄色の字の部分のファイルを作成していきます。

htdocsディレクトリ以下には、公開ソースを設置していきます。

htdocs/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>webpack sample</title>
</head>
<body>

<script src="js/app.js"></script>
</body>
</html>

HTMLファイルには、最少部分のみを記述しています。

htdocs/js/app.js は、未作成でもOK、もしくは空っぽのJSファイルを作成しておきます。

assetsディレクトリ以下には開発ソースを設置していきます。

assets/js/index.js
alert('I built it with webpack!!');

アラートを表示させるスクリプトのみを記述しています。

最後に、webpack.config.js を作成します。このファイルでwebpackの動作設定を行います。

webpack.config.js
const path = require('path');

module.exports = {
mode: "development",
entry: ["./assets/js/index.js"],
output: {
filename: "app.js",
path: path.join(__dirname, 'htdocs/js'),
}
};

上から解説します。

const path = require('path');

出力ファイルを指定する部分で絶対パスを作成する為に、 Node.jsのpath モジュールを読み込みます。

Pathモジュールは、ファイルパスについての操作をいい感じに行ってくれるNode.jsの標準モジュールです。
https://nodejs.org/api/path.html

module.exports = {
mode: "development",
entry: ["./assets/js/index.js"],
output: {
filename: "app.js",
path: path.join(__dirname, 'htdocs/js'),
}
};

webpackの設定をここで行います。

webpack4からはmodeプロパティが登場し、実行時に引数を渡さない場合はここの設定は必須になっています。設定値は以下の3つです。

  • production
  • development
  • none

尚、未設定の場合はproduction扱いとなり、警告が表示されます。

entryプロパティでは、エントリポイントを指定します。エントリポイントは、ビルドを行う基となるファイルを指定します。例えばここで指定したJSファイルから派生するJSファイル群(など)を1つのファイルへバンドルされる事になります。

outputプロパティでは、出力先ファイルに関する設定を行います。filenameプロパティにはファイル名、pathプロパティにはファイルまでのパスを指定します。

pathプロパティでは、先頭で読み込んだpathモジュールを用い、join()メソッドで「プロジェクトルートまでのパス」と「プロジェクトルートから公開ファイルまでのパス」を連結しています。

最後に、package.json の scriptプロパティに以下を追記して、webpackコマンドを登録しておきます。

package.json
"scripts": {
"dev": "webpack --mode development",
"production": "webpack --mode production"
},

これで設定は完了です。コンソールからプロジェクトルートへ移動し、ビルドを行ってみます。

# プロジェクトルートへ移動
cd /path/to/project_root

# webpackでビルドを実行
npm run dev

# 実行結果
[demo@localhost src]$ npm run dev

> src@1.0.0 dev /var/www/html/src
> webpack --mode development

Hash: 75032354ef21564e4aaa
Version: webpack 4.28.2
Time: 170ms
Built at: 01/02/2019 3:02:21 PM
Asset Size Chunks Chunk Names
app.js 4.25 KiB main [emitted] main
Entrypoint main =
app.js
[0] multi ./assets/js/index.js 28 bytes
{main} [built]
[./assets/js/index.js] 92 bytes
{main} [built]

ビルドが完了すると、htdocs/js 配下に app.js が生成されます。

ブラウザからアクセスして動作を確認してみます。

webpack動作確認

webpackでJSファイルのビルドが行われ、app.jsに出力されるまでを確認できました。

トランスコンパイラを用いたコンパイル&複数ファイルのバンドル

次は、ES6(ES2015)で記述したJSのコンパイルと、複数のファイルをビルド(バンドル)してみます。

Babelのインストール

ES6等を扱う為にトランスコンパイラであるBabelをインストールします。

Babel
https://babeljs.io/

# プロジェクトルートへ移動
cd /path/to/project

# Babelインストール
npm i -D babel-loader @babel/core @babel/preset-env

# 実行結果
[demo@localhost src]# npm i -D babel-loader @babel/core @babel/preset-env
+ babel-loader@8.0.4
+ @babel/core@7.2.2
+ @babel/preset-env@7.2.3
added 105 packages from 24 contributors and audited 63645 packages in 46.798s
found 0 vulnerabilities

webpack.config.jsの設定

コンパイル時にBabelを用いる為に、webpack.config.js に以下の設定を追加します。

webpack.config.js
const path = require('path');

module.exports = {
mode: "development",
entry: ["./assets/js/index.js"],
output: {
filename: "app.js",
path: path.join(__dirname, 'htdocs/js'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
]
}
}
]
}
]
}
};

moduleプロパティ部分が追加した部分です。

JSファイル作成

設定は済んだので、次はコンパイルを行うJSファイルを用意します。今回はES6での記法で且つ複数ファイルを扱うので、assetsディレクトリ以下をこんな構成にして単純な四則演算を行うスクリプトを作成していきます。

assets/
└─ js
├─ Component
│   └─
calculatorComponent.js
├─ Controller
│   └─
calculationController.js
└─ index.js

それぞれを実装していきます。実行されると、コンソールに結果を表示するようにします。

assets/js/Component/calculatorComponent.js
export default class CalculatorComponent {
constructor(value) {
this.value = value;
this.total = 0;
this.operation = [];
}
getInitValue() {
return this.value;
}
getValue() {
this.total = this.getInitValue();
for (let i=0; i<this.operation.length; i++) {
this.calculation(this.operation[i].ope, this.operation[i].val);
}

return this.total;
}
calculation(operation, value) {
switch (operation) {
case "add": this.total += value; break;
case "sub": this.total -= value; break;
case "mul": this.total *= value; break;
case "div": this.total /= value; break;
}
}
reset() {
this.operation = [];
}
cancel() {
this.operation.pop();
}
add(value) {
this.operation.push({"ope": "add", "val": value});
}
sub(value) {
this.operation.push({"ope": "sub", "val": value});
}
mul(value) {
this.operation.push({"ope": "mul", "val": value});
}
div(value) {
this.operation.push({"ope": "div", "val": value});
}
}
assets/js/Controller/calculationController.js
import Calculator from '../Component/calculatorComponent';

// 100 を基にする
let calculator = new Calculator(100);

// 130 加算
calculator.add(130);
// 20 減算
calculator.sub(20);
// 4 乗算
calculator.mul(4);
// 2 除算
calculator.div(2);

// 操作を1つキャンセル(除算取り消し)
calculator.cancel();

// 結果出力
console.log(
'計算結果:' + calculator.getValue()
);

// 演算リセット
calculator.reset();

// 結果出力
console.log(
'リセット結果:' + calculator.getValue()
);
assets/index.js
import calculation from './Controller/calculationController';

動作確認

それではwebpackでコンパイル&ビルドを実行します。

# プロジェクトルートへ移動
cd /path/to/project_root

# webpackでビルドを実行
npm run dev

# 実行結果
[demo@localhost src]$ npm run dev

> src@1.0.0 dev /var/www/html/src
> webpack --mode development

Hash: 9b4692b388fa64ca418a
Version: webpack 4.28.2
Time: 841ms
Built at: 01/02/2019 6:59:26 PM
Asset Size Chunks Chunk Names
app.js 8.75 KiB main [emitted] main
Entrypoint main =
app.js
[0] multi ./assets/js/index.js 28 bytes
{main} [built]
[./assets/js/Component/calculatorComponent.js] 2.49 KiB
{main} [built]
[./assets/js/Controller/calculationController.js] 415 bytes
{main} [built]
[./assets/js/index.js] 61 bytes
{main} [built]

ブラウザからアクセスして動作確認を行います。

Babel動作確認画面

ES6記法がBabelによってトランスコンパイルされ、実行可能なソースコードへ変換された事と、複数のJSファイルがapp.jsへ集約された事が確認できました。

コードテスト(静的コード解析)

webpackでは、テストも同時に回す事が出来ます。コンパイル&ビルドを行うのと同時にテストも回す事で、スクリプトの信頼性も高まります。

今回はESLintを導入して静的コード解析を行います。

ESLintのインストール

コードテストを回す為にESLintをインストールします。

ESLint
https://eslint.org/

# プロジェクトルートへ移動
cd /path/to/project

# ESlintインストール
npm i -D eslint eslint-loader

# 実行結果
[demo@localhost src]$ npm i -D eslint eslint-loader
+ eslint-loader@2.1.1
+ eslint@5.11.0
added 1001 packages from 132 contributors and audited 20177 packages in 924.854s
found 0 vulnerabilities

webpack.config.jsの設定

インストールが完了したら、webpack実行時に静的コード解析を行うように設定ファイルに以下を追記します。

webpack.config.js
const path = require('path');

module.exports = {
mode: "development",
entry: ["./assets/js/index.js"],
output: {
filename: "app.js",
path: path.join(__dirname, 'htdocs/js'),
},
module: {
rules: [
// Babel
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
]
}
}
]
},
// ESlint
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: 'eslint-loader',
},
]
}
]
}
};

.ESLintrcの作成

ESLintの解析ルールを設定する為に、プロジェクトルートに.eslintrc(ESLintの設定ファイル)を作成し、以下を記述します。

.eslintrc
{
"extends": ["eslint:recommended"],
"plugins": [],
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2016
},
"env": {
"browser": true,
"es6": true
},
"globals": {},
"rules": {
"semi": "error",
"no-console": "warn",
"no-unused-vars": "warn"
}
}

注目してほしいのは extendsプロパティです。ここで eslint:recommended と指定する事で、ESLintが推奨するテスト項目が既に設定されます。

具体的にどんなチェック項目があるのかは、以下から確認できます。 https://eslint.org/docs/rules/

とはいえもちろん、個別に指定する事も可能です。その場合は rulesプロパティに指定していきます。今回は、推奨設定に入っていない「セミコロン忘れ」を追加し、さらに、いちいちエラーにされると辛いconsole出力メソッドと不使用変数のエラーレベルを引き下げています。

semi
エラーに設定
ASI(自動セミコロン挿入)の使用を禁止とし、セミコロン忘れをチェックします。
no-console
エラー → 警告に設定
consoleの使用を許可しない。console.log()などがソースコードに残っていないかをチェックします。
no-unused-vars
エラー → 警告に設定
未使用の変数を許可しない。宣言・定義されているがその後、使用されていない変数がないかをチェックします。

ルールや指定できる項目は沢山あるので、以下で確認してください。

Configuring ESLint
https://eslint.org/docs/user-guide/configuring

動作確認

それではwebpackでコンパイルと同時に静的コード解析を実行します。

# プロジェクトルートへ移動
cd /path/to/project_root

# webpackでコンパイルを実行
npm run dev

すると、以下のようなメッセージが出力されます。

/var/www/html/src/assets/js/Controller/calculationController.js
19:1 warning Unexpected console statement no-console
27:1 warning Unexpected console statement no-console

2 problems (0 errors, 2 warnings)

calculationController.js で console.log() を出力しているので、その部分で警告が出ています。これらを除去すれば、警告は表示されなくなります。

このようにして、webpackでコンパイルを行うのと同時にインデントとスペースの混合やコンソールメソッドなど、指定したルールの基でコードテストを実行する事が出来ます。

CSSを出力する

webpackではJavaScriptだけでなくCSSも扱う事が出来ます。

複数のCSSファイルをバンドルする

複数に分けたCSSファイルを1つにまとめて出力します。また、JSファイルとCSSファイルは別々に出力する形で行います。

まずはCSSファイルを作成し、styleを記述していきます。assetsディレクトリ配下にcssディレクトリを作成し、その配下に以下3つのCSSファイルを作成します。

assets
├─ css
│   ├─ index.css
│   ├─ style_a.css
│   └─ style_b.css
style_a.css
body {
background-color: #666666;
}
style_b.css
p {
font-size: 16px;
color: #FFFFFF;
}
index.css
@import "style_a.css";
@import "style_b.css";

次に、CSSの解釈に必要な「css-loader」と、CSSとして切り出す為に「mini-css-extract-plugin」をインストールします。

# プロジェクトルートへ移動
cd /path/to/project

# インストール
npm i -D css-loader mini-css-extract-plugin

# 実行結果
[demo@localhost src]$ npm i -D css-loader mini-css-extract-plugin
+ css-loader@2.1.0
+ mini-css-extract-plugin@0.5.0

webpack.config.js を以下に設定します。

webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
mode: "development",
entry: {
app: "./assets/js/index.js",
style: "./assets/css/index.css"
},
output: {
filename: "js/[name].js",
path: path.join(__dirname, 'htdocs'),
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css",
})
],
module: {
rules: [
// babel
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
]
}
}
]
},
// eslint
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: 'eslint-loader',
},
]
},
// CSS
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
]
}
]
}
};
  • 定数 MiniCssExtractPlugin に mini-css-extract-plugin を読み込んでいます。
  • エントリポイントをJSとCSSで2つ設定しています。ここでのプロパティ名がfilenameプロパティで定義されている [name] に入ります。つまり出力されるJSファイルは「htdocs/js/app.js」になります。
  • pluginsプロパティでMiniCssExtractPluginをインスタンス化し、出力ファイルを指定します。[name]にはエントリポイントで指定したプロパティ名がセットされるので、出力されるCSSファイルは htdocs/css/style.css になります。
  • rulesプロパティにCSSの指定を行っています。

最後に、出力したCSSファイルを読み込む記述をHTMLファイルに追記しておいます。

htdocs/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>webpack sample</title>
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<p>webpack sample</p>

<script src="js/app.js"></script>
</body>
</html>

一通りの設定が終わったのでコンパイルを回して動作確認を行います。

# プロジェクトルートへ移動
cd /path/to/project_root

# webpackでコンパイルを実行
npm run dev

2つのCSSファイルが統合され、htdocs/css 配下に style.css が生成されます。

htdocs
├─ css
│   └─
style.css
htdocs/css/style.css
body {
background-color: #666666;
}

p {
font-size: 16px;
color: #FFFFFF;
}

ブラウザから確認してみます。

CSS出力動作確認

出力されたCSSファイルが読み込まれ意図した通りの結果になった事を確認できました。

CSSファイルをminifyする

webpack4からは、webpack.config.js の mode プロパティに production を指定するか、webpackコマンドでのビルドの際に --mode production を付与する事で自動的にJSファイルがminifyされますが、CSSには適用されないので、個別に設定する必要があります。

CSSのminifyを行う為に「optimize-css-assets-webpack-plugin」を導入しますが、同時にJS側のminifyも動作するように「terser-webpack-plugin」も導入します。

optimize-css-assets-webpack-plugin
https://webpack.js.org/plugins/mini-css-extract-plugin/
https://github.com/NMFR/optimize-css-assets-webpack-plugin

terser-webpack-plugin
https://github.com/webpack-contrib/terser-webpack-plugin

# プロジェクトルートへ移動
cd /path/to/project_root

# インストール
npm i -D optimize-css-assets-webpack-plugin terser-webpack-plugin

webpack.config.js を以下に変更します。

webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
mode: "development",
entry: {
app: "./assets/js/index.js",
style: "./assets/css/index.css"
},
output: {
filename: "js/[name].js",
path: path.join(__dirname, 'htdocs'),
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css",
})
],
optimization: {
// production minify
minimizer: [
new OptimizeCSSAssetsPlugin(),
new TerserPlugin({
terserOptions: {
ecma: 6,
compress: true,
output: {
comments: false,
beautify: false
}
}
})
],
},
module: {
rules: [
// Babel
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
]
}
}
]
},
// ESLint
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: 'eslint-loader',
},
]
},
// CSS
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader'
]
}
]
}
};

インストールした2つを定数で読み込み、optimizationプロパティを追加しています。

コンパイルを回して動作確認を行います。productionモードで回します。

# プロジェクトルートへ移動
cd /path/to/project_root

# webpackでコンパイルを実行
npm run production

出力された htdocs/js/app.js と htdocs/css/style.css を確認すると、両ファイルがminifyされて出力されている事が確認できます。

SASSファイルをコンパイルする

スタイルシート言語であるSASSのコンパイルを行いCSSを出力します。

まずはSCSSファイルを作成し、styleを記述していきます。assetsディレクトリ配下にsassディレクトリを作成し、その配下に以下3つのSCSSファイルを作成します。

assets
├─ sass
│ ├─ index.scss
│ ├─ _style_a.scss
│ └─ _style_b.scss

それぞれのSCSSファイルにstyleを定義していきます。

_style_a.scss
body {
padding: 20px;
font-size: 18px;
}
_style_b.scss
$color_a: #dc143c;
$color_a_hover: #6495ed;

p {
a {
color: $color_a;
&:hover {
color: $color_a_hover;
}
}
}
index.scss
@import "style_a";
@import "style_b";

次に、SCSSファイルをロードしてCSSにコンパイル為に「sass-loader」と「node-sass」をインストールします。

sass-loader
https://github.com/webpack-contrib/sass-loader

node-sass
https://github.com/sass/node-sass

# プロジェクトルートへ移動
cd /path/to/project_root

# インストール
npm i -D sass-loader node-sass

webpack.config.js を以下に変更します。尚、今回はソースマップも有効にします。

webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require('terser-webpack-plugin');

const MODE = 'development';

const ENABLE_SOURCE_MAP = (MODE === 'development');


module.exports = {
mode: MODE,
entry: {
app: "./assets/js/index.js",
style: "./assets/sass/index.scss"
},
output: {
filename: "js/[name].js",
path: path.join(__dirname, 'htdocs'),
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css",
})
],
optimization: {
// production minify
minimizer: [
new OptimizeCSSAssetsPlugin(),
new TerserPlugin({
terserOptions: {
ecma: 6,
compress: true,
output: {
comments: false,
beautify: false
}
}
})
],
},
module: {
rules: [
// Babel
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
]
}
}
]
},
// ESLint
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: 'eslint-loader',
},
]
},
// SCSS
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
url: false,
sourceMap: ENABLE_SOURCE_MAP,
importLoaders: 2
},
},
{
loader: 'sass-loader',
options: {
sourceMap: ENABLE_SOURCE_MAP,
}
},
],
},
]
}
};

ソースマップをdevelopment時でのみ有効にする為に、出力オプション(development OR production)を定数MODEにセットし、その値でソースマップの有効・無効を定数ENABLE_SOURCE_MAPにセットしています。

コンパイルして動作確認を行います。

# プロジェクトルートへ移動
cd /path/to/project_root

# webpackでコンパイルを実行
npm run dev

htdocs/css 配下に style.css が生成されます。

htdocs/css/style.css
body {
padding: 20px;
font-size: 18px; }

p a {
color: #dc143c; }
p a:hover {
color: #6495ed; }

SCSSファイルがコンパイルされ、CSSファイルが書き出されている事が確認できました。

画像をbase64エンコードでバンドルする

CSSで画像を背景などに設定する場合がありますが、それらの画像をbase64エンコード(data URI scheme)してCSSファイルへ埋め込み出力します。

styleで画像を扱う場合は、CSSスプライトと言って必要な画像を1つにまとめる事によってリクエスト数を削減する手法が用いられますが、画像自体をbase64エンコードでCSSファイルに埋め込んでしまう事でもリクエスト数を削減できます。(データサイズと対応ブラウザに注意)

まずはファイルをbase64 URIに変換するwebpack用のローダーである「url-loader」をインストールします。

url-loader
https://github.com/webpack-contrib/url-loader

# プロジェクトルートへ移動
cd /path/to/project_root

# インストール
npm i -D url-loader

webpack.config.js を以下に変更します。

webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require('terser-webpack-plugin');

const MODE = 'development';

const ENABLE_SOURCE_MAP = (MODE === 'development');


module.exports = {
mode: MODE,
entry: {
app: "./assets/js/index.js",
style: "./assets/sass/index.scss"
},
output: {
filename: "js/[name].js",
path: path.join(__dirname, 'htdocs'),
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].css",
})
],
optimization: {
// production minify
minimizer: [
new OptimizeCSSAssetsPlugin(),
new TerserPlugin({
terserOptions: {
ecma: 6,
compress: true,
output: {
comments: false,
beautify: false
}
}
})
],
},
module: {
rules: [
// Babel
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
]
}
}
]
},
// ESLint
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: 'eslint-loader',
},
]
},
// SCSS
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
url: true,
sourceMap: ENABLE_SOURCE_MAP,
importLoaders: 2
},
},
{
loader: 'sass-loader',
options: {
sourceMap: ENABLE_SOURCE_MAP,
}
},

],
},
// image base64 encode
{
test: /\.(jpg|gif|png)$/,
loaders: 'url-loader'
},
]
}
};

rulesプロパティへ、画像ファイルに対してurl-loaderを用いる指定を行っています。

HTMLは以下に変更しています。

htdocs/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>webpack sample</title>
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<p>webpack sample <a href="">link</a></p>

<ul>
<li>Webpack</li>
<li>JavaScript</li>
<li>ES6</li>
<li>SCSS</li>
<li>Base64</li>
</ul>

<script src="js/app.js"></script>
</body>
</html>

新しいSCSSファイルを作成して画像を指定します。

assets/sass/_base64_sample.scss
ul {
li {
list-style-image : url("./images/sample_ico.png");
}
}

リストマークを画像にする指定になっています。

コンパイルを行います。

# プロジェクトルートへ移動
cd /path/to/project_root

# webpackでコンパイルを実行
npm run dev

生成された style.css を確認すると、画像ファイルがbase64エンコードされている事が確認できます。

htdocs/css/style.css
ul li {
list-style-image: url(data:image/png;base64,....

ブラウザから確認すると、正常に表示されている事が確認できます。

base64エンコード確認画面

まとめ

以上で作業は終了です。webpackでは他にも様々な処理を扱えるので試してみてください。