JavaScript PR

【Node.js】npmからDartSassを使う【LibSassは非推奨になった】

記事内に商品プロモーションを含む場合があります

こんにちは、おぐらです。
過去にSassのコンパイルについてまとめた記事を投稿しましたが、最近になってSassに動きがあったので再度作成しました。

この記事はDartSassをnpmから使う方法を簡単にまとめた記事です。
npmから使うことに焦点を当てているので、DartSassの詳しい書き方などには触れていません。

npmでNodeSassパッケージを使っている人や、これからnpmを使ってSassのプロジェクトをはじめる人にオススメです。

npmからDartSassを使う

まずはなぜ使うのかを話します。
それから簡単な使い方をみていきましょう。

LibSassは非推奨になった

2020年10月にSassの公式からLibSassは非推奨と正式にリリースがありました。
LibSassによってつくられているNodeSassパッケージも含まれます。

Sass公式は主なポイントとして次の4つをあげています。

  • 新しいSassプロジェクトにLibSassを使うことを推奨しません。 代わりにDartSassを使用してください。
  • 既存のすべてのLibSassユーザーが最終的にDartSassに移行する計画を立て、すべてのSassライブラリが最終的にLibSassのサポートを終了する計画を立てることをオススメします。
  • 新しいCSS機能との互換性など、LibSassに新しい機能を追加する予定はありません。
  • LibSassとNodeSassは、主要なバグやセキュリティの問題の修正、最新のNodeバージョンとの互換性の維持など、ベストエフォートベースで無期限に維持され続けます。

明確に代わりにDartSassを使ってくれと書かれていますね。
今後もLibSassを使っていくには問題が多かったようです。

npmでDartSassをインストール

まずは簡単な例としてプロジェクトを作成します。
プロジェクトを作成したらDartSassパッケージをインストール。

紛らわしいですが、DartSassインストール時のパッケージ名はsass。
間違えないようにしましょう。

npm init
npminstall sass --save-dev

 

プロジェクト直下にsrcディレクトリを作成、その中にapp.scssを配置しておきます。
コンパイルできることを確認するためだけなので、内容はシンプルです。

// src/app.scss
@use "sass:map";

$sizes: (
  sm: 100px,
  md: 200px,
  lg: 300px,
);

.hoge { 
  width: map.get($sizes, sm);
}

 

yarnの場合は適宜変更してください。

コマンドからコンパイル

1番手っ取り早いのはコマンドでコンパイルする方法でしょう。
ターミナルからsassコマンドを使います。

// sass [output.css] 
npx sass src/app.scss dist/app.css

 

1つ以上のファイルをコンパイルするときはMany-to-many Modeを使います。

npx sass hoge.scss:hoge.css piyo.scss:piyo.css

 

ディレクトリ対ディレクトリも可能です。

npx sass src:public/css

 

オプションを渡すこともできます。
よく使うものだとウォッチモードでファイルを監視したり、コンパイルのスタイルを変更したりでしょうか。

// compressedスタイルでコンパイルする
npx sass src/app.scss dist/app.css --style=compressed

// watchモードでファイルの更新を監視する
npx sass src/app.scss dist/app.css --watch

 

オプションはヘルプオプションを渡せば確認できます。
ヘルプを見る限りstyleは2種類しかなさそうですね。

npx sass --help // -hと省略可能です

 

例ではnpxを使ってますが、npm-scriptsに指定してもらっても大丈夫です。

NodeSassパッケージと互換性あり

JavaScriptpから使おうとした場合、一部を除いてnode-sassパッケージと同じように使えます。
次はrenderとrenderSyncを使った例です。

const sass = require('sass');
sass.render({ file: './src/app.scss' }, (err, result) => { // Do something });
const data = sass.renderSync({file: './src/app.scss'});

 

renderはコールバックの引数resultに、renderSyncは戻り値としてコンパイルしたデータを受け取ります。
File systemモジュールを使ってよしなにファイルにしてあげるなどしてください。

render関数はコールバックオーバーヘッドの関係で、renderSync関数と比較してパフォーマンスが落ちます。
対策としてfibersを使うことでパフォーマンス改善できると記されています。

const sass = require('sass');
const Fiber = require("fibers");
sass.render({ file: './src/app.scss', fiber: Fiber, }, (err, result) => { // Do something });

 

コンパイル時間を比較すると確かにrenderSyncはかなり速いですね。
renderもfibersを使うことで半分以下になったので使ったほうがいいですね。

応用編

応用編としてwebpackでも使う方法を簡単にまとめておきます。
といってもsass-loaderを使うことに変わりは無くて、コンパイル用に用意するパッケージをDartSassにするだけです。

webpackでバンドルする

webpackを使うためのパッケージをインストールします。
はじめつくったプロジェクトに追加するので、DartSassとfibersはすでにインストール済みとします。

npm install webpack webpack-cli sass-loader css-loader style-loader --save-dev

 

エントリーファイルのindex.jsをsrcディレクトリに作成して、app.scssをインポートしておきます。

// ./src/index.js
import './app.scss';

 

続いてwebpackの設定ファイルを作成。
プロジェクトルートにwebpack.config.jsを追加します。

const path = require("path");
module.exports = {
  entry: path.join(__dirname, "src"),
  output: { filename: "bundle.js", path: path.resolve(__dirname, "dist") },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
    ],
  },
};

 

そして確認用としてdistにindex.htmlを追加。
バンドルしたJavaScriptファイルを読み込みます。

最後にビルドしましょう。

npx webpack

 

style要素として出力されてます。

上記はとても簡単な例です。
ほかのローダーも組み合わせることでさらに柔軟にバンドルできます。

CSSファイルを個別ファイルにする

CSSはファイルを別にしたい場合もあるでしょう。
webpackのMiniCssExtractPluginを使うことで解決できます。

webpack.config.jsにプラグインを追加する記述を追加。
最終的にstyle-loaderではなく、MiniCssExtractPluginを使うことでCSSファイルとして出力できます。

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
  entry: path.join(__dirname, "src"),
  output: { filename: "bundle.js", path: path.resolve(__dirname, "dist") },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
    ],
  },
  resolve: { extensions: [".js"] },
  plugins: [new MiniCssExtractPlugin({ filename: "app.css" })],
};

NodeSassがプロジェクト内にある場合

NodeSassがプロジェクトに含まれている場合、DartSassを使うことを明示的にwebpackに伝えます。
webpack.config.jsに追加するだけで簡単にできますよ。

module: {
  rules: [
    {
      test: /\.s[ac]ss$/i,
      use: [
        "style-loader",
        "css-loader",
        {
          loader: "sass-loader",
          options: { implementation: require("sass") },
        },
      ],
    },
  ],
},

 

上記はmoduleのところだけを抜粋しています。
今までNodeSassを使ってきてDartSassに移行する時必要かもしれませんね。

プロジェクトにfibersをインストールしていれば自動で注入してくれます。
逆に自動注入をしたくない場合は明示的に設定が必要です。

{
  loader: "sass-loader",
  options: { implementation: require("sass"), sassOptions: { fiber: false } },
},

これからはじめる人はDartSassを使おう

これからSassを学ぶ、プロジェクトをはじめるならDartSassを使いましょう。
LibSassは非推奨になり、メンテナンスは続けられますが、今後追加される新しい機能などとの互換
性はありません。

npmのNodeSassパッケージもLibSassでできているので、これからは使わないようにしましょう。
面倒ですがわたしもNodeSass使ってるプロジェクトをDartSassに移行します。

参考リンク