今回はwebpackを使ってsassをcssにコンパイルする方法です。これまで紹介してきたnode-sassやgulpなどsassをcssにコンパイルする方法の中ではwebpackを使う方法が一番わかりにくいと思います。
私も記事にするにあたり再確認も兼ねて環境を構築していていろいろと学ぶことがありました。私自身の勉強のまとめとしても記事を書いていきます。
webpackってローダーやプラグインなどが増えると急に難易度が上がってきてもういいわってなってたことが多かったのですが、最近では以前よりローダーやプラグインへの理解が深まったおかげかwebpackへの抵抗が無くなってなってきました。
webpackはモジュールバンドラー
webpackは様々なリソース、例えばjavascript、css、画像などをひとまとめに束ねるモジュールバンドラーです。
webpackを使うと何がいいのか
依存性を解決できる
バンドルし一つのファイルにまとめることで依存性を解決することができます。html側であれを読み込んでからこれを読み込むなんてことを考えなくてよくなります。
リクエスト数を減らすことができる
複数のファイルを一つにすることでリクエスト数を減らすことができます。
webpackは4系を使用します
本記事ではwebpackの4系を使用します。webpack4系ではcliが必要になったり、modeオプションが追加されたり、設定ファイルが不要になったりと色々変更点があります。
webpackを使う環境を構築する
作業ディレクトリに移動してwebpackをインストールします。依存パッケージはまとめてインストールしても問題ありません。わかりやすくするためインストールを複数に分けています。npmを使う方は適宜コマンドを置き換えてください。
yarn init
yarn add webpack webpack-cli -D
mkdir src
mkdir src/scss
touch src/index.js
touch src/style.scss
touch webpack.config.js
簡単ですが上記がファイルディレクトリ構成です。あとで画像も追加予定です。webpack,config.jsがwebpackの設定ファイルで、src/index.jsがエントリーポイントのファイルです。sassはscss記法ですのでディレクトリ、ファイルをscssとしています。
sassをコンパイルするためエントリーポイントのindex.jsに読み込んでおきます。簡単な装飾ができるようにjavascriptでbody要素にclassを付与しておきます。
// src/index.js
import './scss/style.css';
document.body.classList.add('foo');
style.scssにはpiyoクラスに対して装飾をするためのコードを記述しておきます。変数でカラーを指定しておくことにします。
// src/scss/style.scss
$gray: #efefef;
.foo { background-color: $gray; }
webpackの設定ファイル作成する
エントリーポイントとsassの準備ができたので、sassをコンパイルするためwebpackの設定ファイルを作っていきます。まずは必要となるローダーやプラグインをインストールします。
webpackコマンドをnpm scriptに設定しておく
モジュールをバンドルするにはwebpackコマンドを使います。おなじみのnpm scriptにコマンドを登録しておきます。
...
"scripts": {
"build": "webpack",
"build:watch": "webpack -w"
},
...
watchはファイルの更新を監視して自動的にバンドルしてくれます。ビルドの速度も上がります。
htmlを自動で作成してくれるプラグインを利用する
webpackでバンドルしたファイルはhtmlで読み込みます。そのhtmlファイルを自動的に生成してくれるのがHtml Webpack Pluginです。手動で作成するよという方は不要です。
yarn add html-webpack-plugin -D
sassをコンパイルするためのローダーをインストールする
yarn add node-sass sass-loader css-loader style-loader -D
sassを読み込むために必要なローダーはsass-loaderです。sassをコンパイルするためnode-sassも一緒にインストールします。sassをコンパイルしたあとのcssを読み込むためにcss-loader、そしてstyle-loaderでstyle要素としてhtmlに反映します。
webpack.config.jsに設定を記述
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: __dirname + '/public'
},
module: {
rules: [
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
outputStyle: 'expanded'
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin()
]
}
順に説明していくと、modeプロパティでバンドルするモードを選択しています。debelopmentとproductionがあり開発時と本番用で異なる形式で出力します。
entryはエントリーポイントの指定でoutputでは出力ファイル、パスの指定をしています。
重要なのはmodulesでmodules内にルールを書いていきます。testに指定した正規表現にマッチしたモジュール(ファイル)に対してローダーを使用します。
例えば上記の設定ファイルでは.scssにマッチするファイルにsass-loader〜style-loaderを使います。このときローダーは下から順に使われます。
sass-loaderではoptionを指定するためオブジェクト形式での記述をしていますが、特に設定不要の場合はcss-loaderやstyle-loaderと同様に文字列での指定もできます。
webpackでビルドする
各種モジュールの用意と、webpackの設定ファイルの準備ができたのでwebpackコマンドでエントリーポイントのモジュールをビルドします。
yarn run build
ビルドが成功するとpublicディレクトリが生成され、publicディレクトリ内にはindex.htmlとbundle.jsが生成されます。ディレクトリ構成やファイル名はwebpack設定ファイルのoutputプロパティで設定します。
index.htmlはhtml-webpack-pluginが自動的に生成してくれます。自動的に生成されるhtmlはwebpack設定ファイルpluginsプロパティでhtml-webpack-pluginのインスタンス作成時にオプションを設定することで編集できます。詳しくはリポジトリをチェックしてください。
sassがコンパイルできているかを確認する
public/index.htmlをブラウザで開いてsassがコンパイルできているか確認します。webpack設定ファイルでは各種ローダーを使って最終的にstyle-loaderでstyle要素として反映するとしていましたので、head要素内にstyle要素でcssが書き込まれているかを確認します。
style要素でcssが反映されていることを確認しました。webpackを使ってsassのコンパイルをすることができました。
sass内で画像を使う方法と、style要素ではなくcssファイルとする方法も一緒に書こうと思っていたのですが、長くなってしまったので別の記事にします。