BETA

[webpack]webpack環境でSass(SCSS記法)を使えるようにする

投稿日:2020-06-25
最終更新:2020-06-25

Sass

Sassは今やCSSコーディングで必須のCSSメタ言語です。
Sassを使う事でCSSに変数が使えたりネスト(入れ子)が使えたりメリットが非常に多く、大規模なサイトになればなるほどSassの各機能を使う事で管理や修正がとても楽になります。

ここ数年はCSS設計を導入する事が増えましたが、中でもBEMはSassのネストと非常に相性が良いです。
この機にぜひCSS設計と一緒にSassを導入しましょう!

webpack×Sass

webpackは標準ではJavaScriptファイルのバンドルにしか対応していませんが、ローダーやプラグインといった拡張機能を導入する事でSassファイルを扱う事ができるようになります。

今回はSassをwebpackで扱えるsass-loaderを導入してプロジェクトでSassを扱えるようにします。

前提条件

  • OS
    • macOS Catalina v10.15.5
    • Windows10 Pro v1909
  • Node.js v12.18.1
  • npm v6.14.5
  • webpack v4.43.0
  • webpack-cli v3.3.12

なお、既にstyle-loadercss-loaderを使用している前提で解説します。

SassにはSASS記法とSCSS記法がありますが、今回はSCSS記法で解説します。
特段断りが無い限り、Sass=Sass(SCSS記法)でお伝えします。
なお詳細は後述しますが、ここで紹介するローダーはSASS記法/SCSS記法どちらも採用可能です。
あまりないとは思いますが、1つのプロジェクト.sassと.scssを混在させることも可能です(詳細はSASS記法で解説)。

sass-loaderのインストール

必要なローダーはsass-loadernode-sass、もしくはsassのどちらかです。

これはnode-sasssassのダウンロード数のトレンドです。
現状はnode-sassの方が人気ですね。

オリジナルのSassはruby製ですがnode-sassはLibSassでC++製、sassはDart SassでDart製。
今後の主流はDart Sassになっていく方向のようです。

  ruby-sass node-sass sass(dart-sass)
速度 遅い 早い 早い
言語 ruby C++ Dart
人気 ほぼみない 現在の主流 これから主流になるとみられている
GitHubスター 176 7,241 1,636

※2020年6月24日時点のGitHubスター数
GitHubスターの数を見ても現状はnode-sassですが、今回は徐々に人気が出てきているsass(dart-sass)を採用してみましょう。

$ npm i -D sass-loader sass fibers  

package.jsonが以下のように自動追記されます。

~略~  
"devDependencies": {  
    "css-loader": "^3.6.0",  
    "fibers": "^5.0.0",  
    "sass": "^8.0.2",  
    "sass-loader": "^8.0.2",  
    "style-loader": "^1.2.1",  
    ~その他略~  
}  

fibersは一緒に使うと処理速度の向上が見込めるとの事なので、一緒にインストールしておきましょう。

webpack.config.jsの追記

webpack.config.jsにSassが使えるように設定を書いていきます。

~略~  
module.exports = {  
    ~中略~  
    module: {  
        rules: [  
            {  
                test: /\.scss$/,    //SCSS記法の場合  
                use: [  
                    'style-loader',  
                    'css-loader',  
                    {  
                        loader: 'sass-loader',  
                        options : {  
                            implementation: require('sass'),  
                            sassOptions: {   
                                fiber: require('fibers')  
                            }  
                        }  
                    },  
                ]  
            }  
        ]  
    }  
}  

ローダーは下から順に実行されていくので

  1. sass-loaderでSassをCSSへ変換
  2. css-loaderでCSSをバンドル
  3. style-loaderでHTMLファイルに吐き出し
    という流れで処理されます。

テストファイルの作成

ここでは表示するHTMLファイル、SCSSファイル、エントリーポイントのJavaScriptファイルを作成していきます。

dist/index.html

<!DOCTYPE html>  
<html lang="ja">  
    <head>  
        <title>Sass(SCSS記法)</title>  
    </head>  
    <body>  
        <div class="mainArea">  
            <h1 class="mainArea__title">Sass(SCSS記法)のバンドルテスト</h1>  
            <p class="mainArea__text">SCSSファイルをwebpackで使ってみました!</p>  
        </div>  
        <script src="js/bundle.js"></script>  
    </body>  
</html>  

src/style.scss

$titleColor: red;  
$textColor: yellow;  

.mainArea {  
    background: #000;  

    &__title {  
        color: $titleColor;  
    }  

    &__text {  
        color: textColor;  
    }  
}  

ここではSCSSのネスト、変数を使っています。

src/index.js

import './style.scss';  

ビルド

準備ができたのでビルドしてみましょう!

$ npx webpack  


見事CSSがしっかり反映されていますね!

デベロッパーツールでソースを見ると、HTMLには書いていないはずのstyleタグがしっかり挿入されています。

コンパイル形式の選択

Sassには4種類のコンパイル方式が存在し、どの方式を選ぶかによって出力される.cssコードが異なります。

コンパイル形式 特徴 sass対応状況
nested ネスト通りに出力され最もファイルサイズが大きいフォーマット。 非対応
expanded ネストが解除され、通常のCSSライクなフォーマット。 対応
compact セレクター毎に1行にまとめて出力するフォーマット。 非対応
compressed すべてのセレクターを一行にまとめて出力するフォーマット。 対応

node-sassではnestedとcompactも使えますが、sassでは現状expandedとcompressedの2つしか使えません。
しかし基本的に開発ではexpanded、本番ではcompressedという事が多いので特段問題ないと思います。

~略~  
options : {  
    implementation: require('sass'),  
    sassOptions: {   
        fiber: require('fibers'),  
        outputStyle: 'compressed',    //expanded or compressed  
    }  
}  

expanded

.mainArea {  
  background: #000;  
}  
.mainArea__title {  
  color: red;  
}  
.mainArea__text {  
  color: yellow;  
}  

expandedは1セレクター毎にブロックで出力され、プロパティもブロック内で1行ずつ出力されます。
よく書籍やWebのCSS解説で見るようなお馴染みのレイアウトですね。
人間に読みやすいように適度にインデントが表現されるので、開発時はexpandedに設定すると良いと思います。

compressed

.mainArea{background:#000}.mainArea__title{color:red}.mainArea__text{color:#ff0}  

compressedは全てのCSSが1行で出力されます。
selector {の間やproperty: valueの間の半角スペース等も全て削除され、最も圧縮率が高い事が特徴です。
実際にWeb上に公開する場合、1KBでも小さい方が理想的なので本番の環境はcompressedに設定すると良いと思います。

CSSをインラインではなく外部ファイル出力する

現状コンパイルされたCSSはstyleタグとしてHTMLにインラインで出力されます。
これを外部ファイル化したい場合は、MiniCssExtractPluginを使います。

MiniCssExtractPluginのインストール

$ npm i -D mini-css-extract-plugin  

webpack.config.js

const path = require('path');  
const MiniCssExtractPlugin = require('mini-css-extract-plugin');    //追加  

〜中略〜  
module: {  
    rules: [  
        {  
            test: /\.scss$/,  
            use: [  
                {  
                    loader: MiniCssExtractPlugin.loader,    //追加  
                },  
                // 'style-loader',    //コメントアウト  
                'css-loader',  
                {  
                    loader: 'sass-loader',  
                    options: {  
                        implementation: require('sass'),  
                        sassOptions: {  
                            fiber: require('fibers'),  
                            outputStyle: 'compressed'  
                        }  
                    }  
                }  
            ]  
        }  
    ]  
},  
plugins: [  
    new MiniCssExtractPlugin ({    //追加  
        filename: 'style.css',  
    }),  
],  
〜略〜  

HTMLにstyleタグを挿入するstyle-loaderをコメントアウトして、代わりにMiniCssExtractPluginを使用しています。
filenameはそのまま出力するファイル名になります。
もちろん別途埋め込む先のHTMLにlinkタグを記述する必要があります。

SASS記法

ここまでは主にSCSS記法について扱ってきましたが、冒頭でお話した通りwebpackを利用してSASS記法の.sassも導入が可能です。

webpack.config.js

まずはwebpackで.sassファイルを扱えるように編集します。

~略~  
module: {  
    rules: [  
        {  
            //sassに対応させる  
                test: /\.sass$/,  
            // .sassと.scss両方に対応する場合は以下  
                test: /\.sass$|\.scss$/,  

こんな感じで.sassと.scss両対応はできますが、よほどの理由がない限り基本的にはどちらか1つに絞っておくべきかと思います(無駄な記載は第三者が見た時に混乱の元ですし・・・)。

.sass

$titleColor: red  
$textColor: yellow  

.mainArea  
    background: #000  

    &__title  
        color: $titleColor  

    &__text  
        color: $textColor  

index.js

import './style.sass';  

ビルド

以上でビルドすると無事cssファイルが生成されます。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@braveryk7の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう