ウェブのフロントエンドエンジニア開発で人気を集めるモジュールバンドラーのwebpack(ウェブパック)。webpackにはJavaScriptファイルのバンドルだけではなく、スタイルシート(CSSやSass)のバンドルもできます。ICS MEDIAの記事「最新版で学ぶwebpack 4入門」では、webpackの基本的な使い方を解説しましたが、この記事ではスタイルシートに焦点をあてて解説します。
※webpackを利用するには事前にNode.jsをインストールしておいてください。この記事では2018年3月現在最新のNode.js v9.7、npm 5.6と、webpack 4.1をもとに解説しています。
☞︎この記事で説明していること
☞︎CSSをバンドルする利点
webpackでは、JavaScriptだけではなくスタイルシート、画像、ウェブフォント等あらゆるリソースをモジュールとして取り扱えます。JavaScriptファイル以外のファイルを扱うには、webpackのLoader機能を用います。
さまざまなファイルをバンドルする利点は読み込みの高速化が挙げられます。HTTP/1.1接続ではブラウザとウェブサーバーの同時接続数が限られるため、複数のファイルの転送に時間がかかります。複数のJSファイルを一つにまとめてしまうことが一般的な解決案として知られています。
手前ミソですが、webpack 4を利用して制作したウェブサイト「CreateJS入門サイト」を紹介します。スタイルシートで画像もバンドルしているため、リクエスト数が少なくなりページの表示高速に役立ちました。ブラウザキャッシュのない状態でも300ミリ秒をきるほど高速に読み込みできています。

☞︎webpack+CSSの構成を作成しよう
CSSファイルの読み込み例を紹介します。サンプルは次のリンクにあるので、手順がわからなければ参照ください。
モジュールのインストール
前回の記事「最新版で学ぶwebpack 4入門」を済まし、プロジェクトフォルダーでコマンド「npm init -y
」を打ち込んだ状態から解説をはじめます。

CSSの読み込みに必要なローダーは、Style LoaderとCSS Loaderなので、この2つのプラグインをプロジェクトフォルダーにインストールします。コマンドラインで次のコマンドを入力ください。
npm i -D webpack webpack-cli style-loader css-loader |
設定ファイル
続いて、webpack.config.js
ファイルに次の設定を追記します。本来は細かいオプションを設定できますが、最低限の内容としては次のコードとなります。CSSのバンドルには「style-loader」と「css-loader」の二種類が必要だと覚えてください。
▼webpack.config.js (簡略版)
{loader: 'css-loader' , options: {url: false }}, |
拡張子が.css
のファイルに対して、use
配列で指定したLoaderが後ろから順番に適用されます。処理を図示すると次のような流れになります。

とりあえずwebpackを動かすために最小限の構成で説明しています。現場で使えるwebpack.config.jsファイルの書き方は後述します。
コンテンツ側のソースコード
src
フォルダー内にindex.js
とstyle.css
の2つのファイルを格納します。index.js
ファイルにはimport
文を用いて、CSSファイルを読み込むように記述します。
▼src/index.js
ビルド
npx webpack
コマンドを使ってビルドすると、ビルドされたdist/main.js
の中にCSSコードが埋め込まれます。

▲ビルドコマンドによってmain.jsファイルにバンドルされる
HTML側でdist/main.js
ファイルを読み込むと、スタイルが適用されます。JSファイルしか読み込んでいない状態ですが、main.jsファイルには自動的にCSSに展開される機能が入っているためです。

▲ビルドコマンドによってmain.jsファイルにバンドルされる
実戦向きのwebpack.config.jsファイル
制作の現場ではソースマップの出力は必須です。ソースマップとは変換前のコードの情報を残すことで開発時に役立てることができる機能です。変換前後ではコードの形が大きく変わってしまうため、元のコードの何行目が影響しているのかわかりやすくする効果があります。

webpack.config.jsファイルのコードが長くなりますが、慣れてきたら次のような設定をするといいでしょう。webpackの仕様として、mode
値がdevelopment
であってもCSSのソースマップは自動的に有効にはなりません。逆に、mode
値がproduction
であってもCSSのソースマップは自動的に無効にはなりません。そのため、ソースマップの有効無効は自前の変数で管理しています。
▼webpack.config.js (現場で利用する設定例)
const MODE = 'development' ; |
const enabledSourceMap = (MODE === 'development' ); |
sourceMap: enabledSourceMap, |
☞︎中間言語の変換 – webpack+Sassの構成を作成しよう
フロントエンド開発では、Sassなどの中間言語を使うことが多いでしょう。webpackではこれらの中間言語を変換できます。アンケートをしてみたところ、多くのCSSコーダーはSassを利用していることがわかります。
https://twitter.com/clockmaker/status/970487589303042048
SassのSCSSファイルを読み込む手順を解説します。サンプルは次のリンクにあるので、手順がわからなければ参照ください。

▲これから説明するサンプル。ビルドコマンドによってmain.jsファイルにバンドルする
モジュールのインストール
Sassの読み込みに必要なローダーは、sass-loaderです。また、Sass LoaderはSassのコンパイル用モジュールnode-sassに依存しているので、あわせてインストールします。コマンドラインで次のコマンドを入力します。
npm i -D webpack webpack-cli sass-loader node-sass style-loader css-loader |
設定ファイル
続いて、webpack.config.js
ファイルに次の設定を追記します。
▼webpack.config.jsファイル
const MODE = 'development' ; |
const enabledSourceMap = (MODE === 'development' ); |
sourceMap: enabledSourceMap, |
sourceMap: enabledSourceMap, |
拡張子が.scss
のファイルに対して、use
配列で指定したLoaderが後ろから順番に適用されます。処理を図示すると次のような流れになります。

コンテンツ側のソースコード
ローダーを用いてSassを読み込むには、エントリーポイント内でimport
文を用いて次のように記述します。src
フォルダー内にindex.js
ファイルとstyle.css
ファイルを格納しているとして解説します。
▼src/index.js
ビルド
webpack
コマンドを使ってビルドすると、webpackはSassをコンパイルします。

▲ビルドコマンドによってmain.jsファイルにバンドルされる。このサンプルでは、画像は取り込んでいないのがポイント。
☞︎Sass内の画像もバンドルする方法
webpackでは画像もJSファイルにバンドルできます。画像はBase64文字列として変換され、コンパイル後のJSファイルに含まれます。何でもかんでもJSファイルにするのは違和感があるかもしれませんが、HTTP/1.1環境下でリクエスト数を極限まで下げるには一つの最適解だと思います。
サンプルは次のリンクにあるので、手順がわからなければ参照ください。

▲これから説明するサンプル。ビルドコマンドによってmain.jsファイルにバンドルする
モジュールのインストール
基本的には先述のSassの手順と同じですが、url-loader
モジュールを追加でインストールします。
npm i -D webpack webpack-cli sass-loader node-sass style-loader css-loader url-loader |
設定ファイル
その上で、webpackの設定ファイルには次のように指定します。JPGやPNGなどの画像形式の場合にurl-loader
が適用されるように指定しています。
▼webpack.config.js
const MODE = 'development' ; |
const enabledSourceMap = (MODE === 'development' ); |
sourceMap: enabledSourceMap, |
sourceMap: enabledSourceMap, |
test: /\.(gif|png|jpg|eot|wof|woff|woff2|ttf|svg)$/, |
拡張子が.scss
のなかでURL参照をしている画像ファイルがあれば、url-loaderが適用されます。処理を図示すると次のような流れになります。

エントリーポイントのsrc/index.js
の内容は前述のSassのサンプルと同じです。
ビルド
webpack
コマンドを使ってビルドすると、webpackはSassをコンパイルします。すると、画像も取り込まれてdist/main.js
ファイルが生成されます。

▲ビルドコマンドによってmain.jsファイルにバンドルされる。このサンプルでは、画像も取り込んでいるのがポイント。
☞︎画像をバンドルしない場合/一部だけバンドルする場合
CSSの場合、画像の取り扱いがポイントです。url-loaderだと一括で全てのファイルを埋め込みますが、逆に画像を埋め込みたくないという方もいるでしょう。そのやり方を「file-loaderのサンプル」にまとめてますので参照ください。file-loaderを使うのがポイントです。
容量の閾値でバンドル有無を制御する方法
高度なテクニックとして、一定のサイズまでは画像をバンドルして、閾値を超えた場合は埋め込まず外部参照にするといった柔軟な設定もできます。

▲画像ファイルの容量で埋め込み有無を分岐することも可能
JavaScriptに画像をバンドルすると①JSファイルの評価時間の増大 ②本来のファイル容量に比べてBase64化することで1.33倍に大きくなるといったデメリットがあります。ただし、サーバーリクエスト処理のコストに比べて①②のほうが小さい場合もあります。容量の大小で制御するのは一つの現実解でしょう。その設定方法は「url-loaderでlimitを設定したサンプル」にまとめたので参照ください。
☞︎まとめ
JavaScriptだけではなくCSSもwebpackで一元管理すると、webpackの周辺技術をふんだんに使えるため開発が楽になります。例えば、CSSの編集で、webpack-dev-serverでローカルサーバーを立てれるのはとても便利です。webpackの設定ファイルははじめはややこしいかもしれませんが、コピペで動かして少しずつ理解していくといいでしょう。書き慣れてくると、痒いところまで手がとどくのでwebpackの柔軟性に利点を感じるようになってきます。
ウェブ制作の現場では、CSSにベンダープレフィックスを付与することも多いでしょう。そのときにはAutoPrefixerなどPostCSSの技術を利用します。この記事は「PostCSSを取り込む方法 – Qiita」に続きます。
☞︎連載記事一覧
- 導入編
- ECMAScript 2015+編
- スタイルシート編
- その他