sass-loader

免責事項 sass-loaderは、コミュニティメンバーによって管理されているサードパーティパッケージであり、webpackと同じサポート、セキュリティポリシー、またはライセンスを持たない可能性があり、webpackによって管理されていません。

npm node tests coverage discussion size

Sass/SCSSファイルをロードし、CSSにコンパイルします。

はじめに

まず、sass-loaderをインストールする必要があります。

npm install sass-loader sass webpack --save-dev

または

yarn add -D sass-loader sass webpack

または

pnpm add -D sass-loader sass webpack

sass-loaderを使用するには、Dart SassNode Sassのいずれかを自分でインストールする必要があります(詳細については以下を参照)、またはSass Embeddedをインストールする必要があります。

これにより、すべての依存関係のバージョンを制御し、使用するSassの実装を選択できます。

Dart Sassを使用することを強くお勧めします。

警告

Node SassYarn PnP機能では動作せず、@use ruleをサポートしていません。

警告

Sass Embeddedは実験段階であり、beta版であるため、一部の機能が動作しない場合があります

sass-loadercss-loaderおよびstyle-loaderと連鎖させて、すべてのスタイルをDOMにすぐに適用するか、mini-css-extract-pluginを使用して個別のファイルに抽出します。

次に、ローダーをWebpack構成に追加します。例えば

app.js

import "./style.scss";

style.scss

$body-color: red;

body {
  color: $body-color;
}

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          // Creates `style` nodes from JS strings
          "style-loader",
          // Translates CSS into CommonJS
          "css-loader",
          // Compiles Sass to CSS
          "sass-loader",
        ],
      },
    ],
  },
};

最後に、ご希望の方法でwebpackを実行します。

productionモードでのoutputStyle (古いAPI) とstyle (新しいAPI) オプション

productionモードでは、outputStyle (古いAPI) と style (新しいAPI) オプションは、sassOptionsで特に指定されていない限り、デフォルトでcompressedになります。

import at-rules の解決

Webpackは、ファイルを解決するための高度なメカニズムを提供します。

sass-loaderは、Sassのカスタムインポーター機能を使用して、すべてのクエリをWebpack解決エンジンに渡します。したがって、node_modulesからSassモジュールをインポートできます。

@import "bootstrap";

~の使用は非推奨であり、コードから削除できます (推奨) が、歴史的な理由から依然としてサポートしています。なぜ削除できるのでしょうか? ローダーはまず、@importを相対パスとして解決しようとします。解決できない場合、ローダーはnode_modules内で@importを解決しようとします。

モジュールパスに~を付加すると、webpackにnode_modulesを検索するように指示します。

@import "~bootstrap";

~/はホームディレクトリに解決されるため、~のみを前に付けることが重要です。CSSファイルとSassファイルには相対ファイルをインポートするための特別な構文がないため、Webpackはbootstrap~bootstrapを区別する必要があります。@import "style.scss"と記述するのは@import "./style.scss";と同じです。

url(...)に関する問題点

Sassの実装ではURLの書き換えが提供されていないため、リンクされたアセットはすべて出力に対して相対的である必要があります。

  • 生成されたCSSをcss-loaderに渡す場合、すべてのURLはエントリファイル(例:main.scss)に対して相対的である必要があります。
  • css-loaderに渡さずにCSSを生成するだけの場合は、Webルートに対して相対的である必要があります。

最初の問題によって混乱が生じるでしょう。相対参照は、指定された.sass/.scssファイルに対して解決されると予想するのが自然です(通常の.cssファイルのように)。

幸いなことに、この問題には2つの解決策があります。

  • resolve-url-loaderを使用して、不足しているURL書き換えを追加します。ローダーチェーンでsass-loaderの前に配置します。
  • ライブラリの作成者は通常、アセットパスを変更するための変数を提供します。例えば、bootstrap-sassには$icon-font-pathがあります。

オプション

implementation

type implementation = object | string;

デフォルト: sass

特別なimplementationオプションは、使用するSassの実装を決定します。

デフォルトでは、ローダーは依存関係に基づいて実装を解決します。必要な実装をpackage.jsonsassまたはnode-sassパッケージ)に追加し、依存関係をインストールするだけです。

sass-loaderローダーがsassdart-sass)実装を使用する例

package.json

{
  "devDependencies": {
    "sass-loader": "^7.2.0",
    "sass": "^1.22.10"
  }
}

sass-loaderローダーがnode-sass実装を使用する例

package.json

{
  "devDependencies": {
    "sass-loader": "^7.2.0",
    "node-sass": "^5.0.0"
  }
}

node-sasssassの両方がインストールされている場合に注意してください!デフォルトでは、sass-loadersassを優先します。この状況を回避するために、implementationオプションを使用できます。

implementationオプションは、モジュールとしてsassDart Sass)またはnode-sassを受け入れます。

object

たとえば、Dart Sassを使用するには、次のように渡します。

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

string

たとえば、Dart Sassを使用するには、次のように渡します。

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

sassOptions

type sassOptions =
  | import("sass").LegacyOptions<"async">
  | ((
      content: string | Buffer,
      loaderContext: LoaderContext,
      meta: any,
    ) => import("sass").LegacyOptions<"async">);

デフォルト: Sass実装のデフォルト値

Dart SassまたはNode Sass実装のオプションです。

charsetオプションは、dart-sassではデフォルトでtrueの値を持っています。webpackはutf-8以外のファイルをサポートしていないため、値をfalseに変更することは強く推奨しません。

indentedSyntaxオプションは、sass拡張子に対してtrueの値を持っています。

datafileなどのオプションは利用できず、無視されます。

outFilesourceMapContentssourceMapEmbedsourceMapRootオプションの変更は強く推奨しません。sourceMapオプションがtrueの場合、sass-loaderがこれらのオプションを自動的に設定するためです。

カスタムインポーター内のローダーコンテキストへのアクセスは、this.webpackLoaderContextプロパティを使用して行うことができます。

sassdart-sass)とnode-sassのオプションにはわずかな違いがあります。

使用する前にドキュメントを参照してください

object

Sass実装のセットアップにはオブジェクトを使用します。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              sassOptions: {
                indentWidth: 4,
                includePaths: ["absolute/path/a", "absolute/path/b"],
              },
            },
          },
        ],
      },
    ],
  },
};

function

ローダーコンテキストに基づいて異なるオプションを設定することにより、Sass実装をセットアップできます。

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              sassOptions: (content, loaderContext) => {
                // More information about available properties https://webpack.dokyumento.jp/api/loaders/
                const { resourcePath, rootContext } = loaderContext;
                const relativePath = path.relative(rootContext, resourcePath);

                if (relativePath === "styles/foo.scss") {
                  return {
                    includePaths: ["absolute/path/c", "absolute/path/d"],
                  };
                }

                return {
                  includePaths: ["absolute/path/a", "absolute/path/b"],
                };
              },
            },
          },
        ],
      },
    ],
  },
};

sourceMap

type sourceMap = boolean;

デフォルト: compiler.devtoolの値に依存します

ソースマップの生成を有効/無効にします。

デフォルトでは、ソースマップの生成はdevtoolオプションに依存します。evalおよびfalse値を除くすべての値でソースマップの生成が有効になります。

trueの場合、sassOptionssourceMapsourceMapRootsourceMapEmbedsourceMapContentsomitSourceMapUrlは無視されます。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              sourceMap: true,
            },
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true,
            },
          },
        ],
      },
    ],
  },
};

ℹ まれに、node-sassが無効なソースマップを出力する場合があります(これはnode-sassのバグです)。

これを回避するために、node-sassを最新バージョンに更新するか、sassOptions内でoutputStyleオプションをcompressedに設定してみてください。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              sourceMap: true,
              sassOptions: {
                outputStyle: "compressed",
              },
            },
          },
        ],
      },
    ],
  },
};

additionalData

type additionalData =
  | string
  | ((content: string | Buffer, loaderContext: LoaderContext) => string);

デフォルト: undefined

実際のエントリファイルの前にSass/SCSSコードをプリペンドします。この場合、sass-loaderdataオプションをオーバーライドするのではなく、エントリのコンテンツをプリペンドするだけです。

これは、Sass変数のいくつかが環境に依存している場合に特に便利です。

string

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              additionalData: "$env: " + process.env.NODE_ENV + ";",
            },
          },
        ],
      },
    ],
  },
};

function

同期
module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              additionalData: (content, loaderContext) => {
                // More information about available properties https://webpack.dokyumento.jp/api/loaders/
                const { resourcePath, rootContext } = loaderContext;
                const relativePath = path.relative(rootContext, resourcePath);

                if (relativePath === "styles/foo.scss") {
                  return "$value: 100px;" + content;
                }

                return "$value: 200px;" + content;
              },
            },
          },
        ],
      },
    ],
  },
};
非同期
module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              additionalData: async (content, loaderContext) => {
                // More information about available properties https://webpack.dokyumento.jp/api/loaders/
                const { resourcePath, rootContext } = loaderContext;
                const relativePath = path.relative(rootContext, resourcePath);

                if (relativePath === "styles/foo.scss") {
                  return "$value: 100px;" + content;
                }

                return "$value: 200px;" + content;
              },
            },
          },
        ],
      },
    ],
  },
};

webpackImporter

type webpackImporter = boolean;

デフォルト: true

デフォルトのWebpackインポーターを有効/無効にします。

これにより、場合によってはパフォーマンスが向上する可能性があります。エイリアスと~で始まる@importアットルールが機能しなくなるため、注意して使用してください。これを解決するために独自のimporterを渡すことができます(importer docsを参照)。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              webpackImporter: false,
            },
          },
        ],
      },
    ],
  },
};

warnRuleAsWarning

type warnRuleAsWarning = boolean;

デフォルト: true

@warnルールをWebpackの警告として扱います。

style.scss

$known-prefixes: webkit, moz, ms, o;

@mixin prefix($property, $value, $prefixes) {
  @each $prefix in $prefixes {
    @if not index($known-prefixes, $prefix) {
      @warn "Unknown prefix #{$prefix}.";
    }

    -#{$prefix}-#{$property}: $value;
  }
  #{$property}: $value;
}

.tilt {
  // Oops, we typo'd "webkit" as "wekbit"!
  @include prefix(transform, rotate(15deg), wekbit ms);
}

提示されたコードは、ログではなくwebpackの警告をスローします。

不要な警告を無視するには、ignoreWarningsオプションを使用できます。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              warnRuleAsWarning: true,
            },
          },
        ],
      },
    ],
  },
};

api

type api = "legacy" | "modern";

デフォルト: "legacy"

legacymodern APIを切り替えることができます。詳細についてはこちらを参照してください。

警告

「modern」APIは実験的であるため、一部の機能が動作しない場合があります(既知:組み込みのimporterが機能せず、エラーのあるファイルが最初の実行時に監視されません)。こちらに従うことができます。

警告

sassオプションは、modernおよびoldAPIで異なります。新しいオプションへの移行方法についてはドキュメントを参照してください。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            options: {
              api: "modern",
              sassOptions: {
                // Your sass options
              },
            },
          },
        ],
      },
    ],
  },
};

@debug出力を有効にする方法

デフォルトでは、@debugメッセージの出力は無効になっています。有効にするには、webpack.config.jsに以下を追加します。

module.exports = {
  stats: {
    loggingDebug: ["sass-loader"],
  },
  // ...
};

CSSを別ファイルに抽出する

プロダクションビルドの場合、CSS/JSリソースの並列ロードを後で使用できるように、バンドルからCSSを抽出することをお勧めします。

バンドルからスタイルシートを抽出するには、4つの可能性があります。

1. mini-css-extract-plugin

webpack.config.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          // fallback to style-loader in development
          process.env.NODE_ENV !== "production"
            ? "style-loader"
            : MiniCssExtractPlugin.loader,
          "css-loader",
          "sass-loader",
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: "[name].css",
      chunkFilename: "[id].css",
    }),
  ],
};

2. アセットモジュール

webpack.config.js

module.exports = {
  entry: [__dirname + "/src/scss/app.scss"],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [],
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        type: "asset/resource",
        generator: {
          filename: "bundle.css",
        },
        use: ["sass-loader"],
      },
    ],
  },
};

3. extract-loader (よりシンプルですが、css-loaderの出力に特化しています)

4. file-loader(非推奨--Webpack v4でのみ使用する必要があります)

webpack.config.js

module.exports = {
  entry: [__dirname + "/src/scss/app.scss"],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [],
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "file-loader",
            options: { outputPath: "css/", name: "[name].min.css" },
          },
          "sass-loader",
        ],
      },
    ],
  },
};

(出典:https://stackoverflow.com/a/60029923/2969615

ソースマップ

ソースマップの生成を有効/無効にします。

CSSソースマップを有効にするには、sass-loadercss-loaderにsourceMapオプションを渡す必要があります。

webpack.config.js

module.exports = {
  devtool: "source-map", // any "source-map"-like devtool is possible
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              sourceMap: true,
            },
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true,
            },
          },
        ],
      },
    ],
  },
};

Chrome内で元のSassファイルを編集したい場合は、優れたブログ記事があります。test/sourceMapで実行例を確認してください。

貢献

まだ読んでいない場合は、貢献ガイドラインをお読みください。

貢献

ライセンス

MIT