scssのコンパイル|webpack

導入

webpack自体の導入は前項を参照。

scssをコンパイルするにはいくつかのローダーを導入する必要がある。

ローダー

webpackでは本来js形式のファイルしか取り扱うことができないため、scssやcssを扱う場合にはそのファイル形式用の追加プログラムがそれぞれ必要で、それらをローダーと呼ぶ。

style-loader

<head>内にインラインCSSを出力する

css-loader

cssを扱うローダー

sass-loader

sassを扱うローダー

npmインストール

$ npm install --save-dev style-loader
$ npm install --save-dev css-loader
$ npm install --save-dev sass-loader sass

webpackのconfig設定

webpack.config.jsを作成してローダーを設定

const PATH = require('path');

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    path: PATH.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  module: {
    rules: [
      {
        test: /\.scss$/i,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'sass-loader',
            options: {
              sassOptions: {
                outputStyle: 'expanded',
              },
            },
          },
        ]
      },
    ]
  }
};

エントリーポイントに設定

エントリーポイントとなるjs(本稿ではsrc/index.js)に以下の記述を追加。

// styleのimport
import "./sass/style.scss";

scssの準備

本稿ではsrc/sass/style.scssとして準備。

@importも使えるので、サンプルとして今回はこんな感じで。

src

sass

style.scss

foundation

base.scss

@import "foundation/base";
html {
    font-size: 10px;
}
body {
    font-size: 1.4rem;
}

ビルド

$ npm run build

ここまででコンパイルは完了です。

以下、書き出された<head>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="main.js"></script><style>html {
  font-size: 10px;
}

body {
  font-size: 1.4rem;
}</style>
</head>

改行とか変なのは、バンドルされた全部が本来ならずらーっと並ぶ感じだから?scssファイルの中での改行がHTMLソースに反映されている感じか。minifyすればぎっしりなるのかも。

CSSを別ファイルにする場合

ここまでの状態だとCSSはインラインで<style>に書き出されますが、MiniCssExtractPluginプラグインを入れることでcssファイルとして別に書き出すことが可能です。

npmインストール

$ npm install --save-dev mini-css-extract-plugin

webpack設定

webpack.config.jsを改修。

上記からの変更点にコメントしています。

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

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    path: PATH.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  module: {
    rules: [
      {
        test: /\.scss$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,//←style-loaderから変更
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'sass-loader',
            options: {
              sassOptions: {
                outputStyle: 'expanded',
              },
            },
          },
        ]
      },
    ]
  },
  //プラグインの記述を追加
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/style.css',
      ignoreOrder: true,
    })
  ]
};

これでビルドすれば、指定したパスに指定したファイル名で書き出されます。(ここではdist/css/style.css

htmlへの追加

cssは別ファイルとして書き出されるので、htmlに読み込みの記述を入れてやる必要があります。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="main.js"></script>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    テスト
</body>
</html>

これで書き出されたファイルが読み込まれます。

なんか他にも色々できそうですが、長くなるのでエントリを分けます。

参考にしたページ