入門者/初心者にもわかるwebpack 4の基礎(CSS Loader編)

先日公開した入門者/初心者にもわかるwebpackの基礎の続きです。今回は、webpack.config.jsの設定方法、CSSスタイルシートをwebpackを使ってjsファイルにまとめるために必要なLoader(ローダー)について説明を行います。本文書を読み終えるとwebpackのLoaderとは何をするのか理解することができます。
目次
前準備
動作確認を行うためにはnpmのインストールが事前に行われている必要があります。またnpmでwebpack, webpack-cliをインストールし、package.jsonのscriptsに以下のwebpackコマンドの設定が完了している環境で動作確認を行っています。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --mode development",
"build": "webpack --mode production"
},
上記の設定がわからない場合は下記の文書を事前にお読みください。
webpack.config.jsの設定方法
前回はコマンドラインのみでwebpackを行いファイルをまとめる機能の動作確認を行ったので今回はwebpackの設定ファイルであるwebpack.config.jsの設定について確認を行っていきます。

webpack.config.jsの作成
空のwebpack.config.jsファイルを作成します。
mac $ touch webpack.config.js
作成したwebpack.config.jsファイルに下記の内容を記述してください。
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
entryでは元になるindex.jsファイルを指定し、webpack実行後にdistディレクトリの下に作成されるbundle.jsファイルをoutputで指定しています。

webpack.config.jsファイルの1行目では、requireでnode.jsのpathモジュールの読み込みを行っています。
__dirnameでスクリプトが存在するディレクトリを出力する変数です。pathモジュールのresolveメソッドに__dirnameとdistを入れることでpathには/distが設定されることになります。
pathモジュールはファイルパスを効率よく扱うためのユーティリティツールです。
[path.resolveの使い方]
path.resolve(‘/foo/bar’, ‘./baz’);
// Returns(上記の実行で戻される値): ‘/foo/bar/baz’
index.jsにconsole.log(‘Hellow World”)など簡単なコードを記述した後にwebpackコマンドを実行しwebpack.config.jsの記述に誤りがないか確認を行います。エラーがでなければ設定ファイルの記述に誤りはありません。
console.log('Hello World');
mac $ npm run dev
> test@1.0.0 dev /Users/mac/Document/test
> webpack --mode development
Hash: 242e97791fa2548e7e72
Version: webpack 4.31.0
Time: 95ms
Built at: 2019-05-18 20:51:59
Asset Size Chunks Chunk Names
bundle.js 3.8 KiB main [emitted] main
Entrypoint main = bundle.js
[./src/index.js] 27 bytes {main} [built]
webpackの設定ファイルでの設定はこれで終わりではなくここから個別機能の設定を記述していくことになります。
CSSスタイルシートをまとめる
前回の文書では複数のJavaScriptファイルがwebpackを使って1つにまとめられることを確認しました。今回は、web開発ホームページ制作の初心者にとっても馴染みの深いCSSスタイルシートをwebpackを使ってJavaScriptファイルにまとめる方法を確認します。
webpackのLoader(ローダー)とは
webpackはJavaScriptファイルのみそのままの状態で取り扱うことができます。そのためJavaScriptファイル以外の他の言語で書かれたプログラムをwebpackで扱う場合にはLoader(ローダー)を使用する必要があります。
css-loader, style-loaderのインストール
CSSスタイルシートをwebpackで扱えるようにするためには、css-loaderとstyle-loaderが必要になります。
css-loaderは、CSSスタイルシートをJavaScriptファイルに埋め込むため(load)に利用されます。style-loaderは、JavaScriptファイルに埋め込まれたCSSの情報をhtmlのstyleタグに加える際に利用されます。
npm installでこの2つのパッケージのインストールを行います。
mac $ npm install css-loader style-loader --save-dev
npm WARN test@1.0.0 No description
npm WARN test@1.0.0 No repository field.
+ style-loader@0.23.1
+ css-loader@2.1.1
added 16 packages from 47 contributors and audited 5351 packages in 5.631s
found 0 vulnerabilities
npmの理解に不安がある人は下記の文書が参考になります。
CSSスタイルシートの作成
CSSによるスタイリングを行うclassを設定するためにdivタグをindex.htmlに追加します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>webpack</title>
<script src="dist/bundle.js"></script>
</head>
<body>
<div class="first-header">
<h1>CSS Loadersを理解する</h1>
</div>
</body>
</html>
追加したdivのfirst-headerクラスにCSSでスタイリングを行います。style.cssをsrcディレクトリの下に作成して下記のスタイルを書き込みます。
.first-header{
background-color: red;
color:white;
padding:20px;
}
webpack.config.jsへのcss-loaderの追加
css-loader, style-loaderに関する設定はwebpack.config.jsで行います。 webpack.config.jsにmodule句を追加しルールを設定する必要があります。
拡張子にcssがついたファイルのみにstyle-loader, css-loaderを適用させるためtestを追加しています。useにはstyle-loaderとcss-loaderを追加しますが追加した順番も重要です。後ろのcss-loaderから実行されcss-loaderの処理後にstyle-loaderが実行されます。
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
}
}
index.jsでのcssファイルのimport
index.jsファイルで、cssファイルのimportを行う必要があります。importに指定するファイルは先ほど作成したstyle.cssです。今回は動作確認のためstyle.cssのimportとconsole.logしか記述していませんが、通常はJavaScriptで行いたいその他の処理もここに記述します。
import './style.css';
console.log('Hello World');
webpackの実行
ここまでの設定で、CSSファイルをbundle.jsファイルにまとめる準備が揃ったので、webpackを実行します。実行ログにはstyle.cssファイルに関する情報も表示されています。
mac $ npm run dev
> test@1.0.0 dev /Users/mac/Document/test
> webpack --mode development
Hash: 648c307f5d3ae6734ccf
Version: webpack 4.31.0
Time: 193ms
Built at: 2019-05-18 17:09:47
Asset Size Chunks Chunk Names
bundle.js 23.6 KiB main [emitted] main
Entrypoint main = bundle.js
[./node_modules/css-loader/dist/cjs.js!./src/style.css] 215 bytes {main} [built]
[./src/index.js] 50 bytes {main} [built]
[./src/style.css] 1.06 KiB {main} [built]
+ 3 hidden modules
ブラウザでindex.htmlを開くとdivタグへ設定したスタイリングが反映されていることが確認できます。また、Chromeの開発ツールでみるとスタイルタグがhtmlに追加されていることも確認することができます。

bundle.jsの中身の確認
webpackによって生成されたbundle.jsの中身を確認してスタイル設定が埋め込まれているのか確認を行います。bundle.jsファイルを開いてclass名のfirst-headerを検索するとファイルの中にfirst-headerの文字列を見つけることができます。
[module.i, \".first-header{\\n\\tbackground-color: red;\\n\\tcolor:white;\\n\\tpadding:20px;\\n}\",
css-loaderを使うことでcssスタイルシートの内容がJavaScriptファイルに埋め込まれbundle.jsにまとめられていることがわかります。
sass-loaderの追加
webpackはSassをCSSへと変換する機能を追加することができます。CSSへの自動変換機能を利用するためにはsass-loaderが必要になります。webpackの一連の処理に自動変換の機能を追加することでSassからCSSへの変換する作業の手間を減らすことができます。
Sassとは
CSSをより効率的に記述するために開発されたメタ言語です。CSSプリプロセッサとも呼ばれます。メタ言語、CSSプリプロセッサは馴染みのない単語かもしれませんが聞き覚えのない人はぜひこの機会に覚えてください。
Sassの詳しい設定方法はここでは省いていますが、Sassの主な機能の一つである変数を通してどのようにCSSの効率化につながるのかだけ確認しておきます。
下記のように変数名を$+任意の名前とし値を指定すると変数として利用することができます。このように変数を設定することでメリットが生まれます。例えばホームページの配色を設定する度にRGBの確認をすることなく変数名である$main_colorを覚えているだけで正しい色を設定することができます。
$main_color: #FF0000;
$sub_color: #FFFFFF;
.first-header{
background-color: $main_color;
color: $sub_color;
padding:20px;
}

sass-loader, node-sassのインストール
sass-loaderを利用するためにはnpmでsass-loaderとnode-sassの2つのパッケージをインストールする必要があります。
mac $ npm install sass-loader node-sass --save-dev
webpack.config.jsへのsass-loaderの追加
sass-loaderのインストールが完了したら、webpack.config.jsにsass-loaderの情報を追加する必要があります。
[CSSからの変更点]
- testの値をcssからscssに変更。
- useの配列にsass-loaderの追加
これまでは拡張子がcssのものにuseのローダーが適用されていましたが、下記設定ではscssの拡張子を持つファイルのみ適用されます。
test:/\.scss$/
use:['style-loader','css-loader','sass-loader']
useの後ろ側にsass-loaderを追加したのは、css-loaderでcssをJavaScriptに埋め込む前にsass-loaderによりscssをcssに変換しておく必要があるためです。

webpack.config.jsファイルはsass-loaderの追加により以下のようになりました。
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module:{
rules:[
{
test:/\.scss$/,
use:['style-loader','css-loader','sass-loader']
}
]
}
}
scssだけではなくsassも適用させたい場合はtestは下記のように変更を行います。
test: /\.(sass|scss)$/,
Sassファイルの作成
Sassファイルは下記のように作成します。ファイルはsrcディレクトリの下に保存し、拡張子は.scssにしてください。
$main_color: #FF0000;
$sub_color: #FFFFFF;
.first-header{
background-color: $main_color;
color: $sub_color;
padding:20px;
}
index.jsファイルの更新
先ほどまではstyle.cssファイルをimportしていましたが、今回はstyle.scssファイルをimportします。
import './style.scss';
console.log('Hello World');
index.htmlファイルは下記の内容で作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>webpack</title>
<script src="dist/bundle.js"></script>
</head>
<body>
<div class="first-header">
<h1>SCSS Loadersを理解する</h1>
</div>
</body>
</html>
ここまでの設定でCSSからScssへの変更は完了です。
webpackの実行
npm run devコマンドでwebpackを実行します。
mac $ npm run dev
> test@1.0.0 dev /Users/reffect/Document/test
> webpack --mode development
Hash: 2eef2c1dd5a3d2dfc352
Version: webpack 4.31.0
Time: 2117ms
Built at: 2019-05-21 14:39:51
Asset Size Chunks Chunk Names
bundle.js 23.9 KiB main [emitted] main
Entrypoint main = bundle.js
[./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./src/style.scss] 225 bytes {main} [built]
[./src/index.js] 51 bytes {main} [built]
[./src/style.scss] 1.18 KiB {main} [built]
+ 3 hidden modules
実行後、ブラウザでindex.htmlファイルを確認してください。Scssで変数だった値が展開されて.first-classクラスに適用されていることを確認することができます。

まとめ
webpackでは、Loaderの使うことでJavaScript以外のファイルも扱えることを理解することができました。これ以外にもさまざまなLoaderが存在しLoader毎の機能を理解していく必要があります。今回は、WEB開発初心者にとって身近なCSS、SCSSを使うことでwebpackのLoaderがどんな処理をするためにあるのかがわかってもらえたかと思います。