載入 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 Sass、Node Sass(更多文件說明如下)或 Sass Embedded。
這讓您可以控制所有依賴項目的版本,並選擇要使用的 Sass 實作。
注意
我們強烈建議使用 Dart Sass。
警告
警告
Sass Embedded 仍處於實驗階段,且為
beta
版,因此某些功能可能無法使用
將 sass-loader
與 css-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
模式,除非在 sassOptions
中另行指定,否則 outputStyle
(舊 API)和 style
(新 API)選項預設為 compressed
。
import
at 規則Webpack 提供了一個 進階機制來解析檔案。
sass-loader
使用 Sass 的自訂匯入功能,將所有查詢傳遞給 Webpack 解析引擎。因此,您可以從 node_modules
匯入 Sass 模組。
@import "bootstrap";
使用 ~
已被棄用,可以從您的程式碼中移除(我們建議這麼做),但我們基於歷史原因仍支援它。為什麼您可以移除它?載入器會先嘗試將 @import
解析為相對路徑。如果無法解析,載入器會嘗試在 node_modules
中解析 @import
。
使用 ~
為模組路徑加上前置字元,告訴 webpack 在 node_modules
中搜尋。
@import "~bootstrap";
重要的是,僅使用 ~
作為前置字元,因為 ~/
會解析為家目錄。Webpack 需要區分 bootstrap
和 ~bootstrap
,因為 CSS 和 Sass 檔案沒有用於匯入相對檔案的特殊語法。撰寫 @import "style.scss"
與 @import "./style.scss";
相同。
url(...)
的問題由於 Sass 實作不提供 網址改寫,所有連結的資產都必須相對於輸出。
css-loader
,所有網址都必須相對於進入檔案(例如 main.scss
)。css-loader
,它必須相對於您的網路根目錄。您會受到第一個問題的影響。自然會希望相對於指定 .sass
/.scss
檔案的相對參照得到解析(就像在一般的 .css
檔案中一樣)。
感謝有兩個解決方案可以解決此問題
sass-loader
之前。$icon-font-path
。implementation
類型
type implementation = object | string;
預設:sass
特殊的 implementation
選項決定要使用哪一種 Sass 實作。
預設情況下,loader 會根據您的依賴項解析實作。只要將需要的實作新增到 package.json
(sass
或 node-sass
套件) 並安裝依賴項即可。
sass-loader
loader 使用 sass
(dart-sass
) 實作的範例
package.json
{
"devDependencies": {
"sass-loader": "^7.2.0",
"sass": "^1.22.10"
}
}
sass-loader
loader 使用 node-sass
實作的範例
package.json
{
"devDependencies": {
"sass-loader": "^7.2.0",
"node-sass": "^5.0.0"
}
}
當安裝了 node-sass
和 sass
時,請小心處理這種情況!預設情況下,sass-loader
會偏好 sass
。為了避免這種情況,您可以使用 implementation
選項。
implementation
選項接受 sass
(Dart 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 實作的預設值
注意
charset
選項在dart-sass
中預設為true
,我們強烈建議不要將值變更為false
,因為 webpack 不支援utf-8
以外的檔案。
注意
indentedSyntax
選項在sass
副檔名中為true
。
注意
data
和file
等選項不可用,且會被忽略。
ℹ 我們強烈建議不要變更
outFile
、sourceMapContents
、sourceMapEmbed
、sourceMapRoot
選項,因為當sourceMap
選項為true
時,sass-loader
會自動設定這些選項。
注意
可以在自訂匯入器內使用
this.webpackLoaderContext
屬性存取 loader context。
sass
(dart-sass
) 和 node-sass
選項之間有些微差異。
請在使用前參閱文件
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
允許透過設定不同的選項,根據 loader context 設定 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.dev.org.tw/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
值之外,所有值都會啟用原始碼地圖產生。
ℹ 如果
sourceMap
、sourceMapRoot
、sourceMapEmbed
、sourceMapContents
和omitSourceMapUrl
來自sassOptions
為true
,將會被忽略。
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-loader
不會覆寫 data
選項,而只是預先加入進入的內容。
當你的某些 Sass 變數取決於環境時,這特別有用
字串
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: "$env: " + process.env.NODE_ENV + ";",
},
},
],
},
],
},
};
函式
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.dev.org.tw/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.dev.org.tw/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
at 規則將無法運作。你可以傳遞自己的 importer
來解決這個問題 (請參閱 importer 文件
).
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"
讓您在 legacy
和 modern
API 之間切換。您可以在 這裡 找到更多資訊。
警告
「現代」API 仍處於實驗階段,因此某些功能可能無法使用(已知:內建
importer
無法使用,且在初始執行時不會監控有錯誤的檔案),您可以追蹤 這裡 的資訊。
警告
sass 選項在
modern
和old
API 中有所不同。請參閱 文件,了解如何轉移到新選項。
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 資源。
有四種可能性可以從套件中萃取樣式表
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",
}),
],
};
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"],
},
],
},
};
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 原始碼對應,您需要將 sourceMap
選項傳遞給 sass-loader
和 css-loader。
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 以取得執行中的範例。
如果您尚未閱讀我們的貢獻指南,請花點時間閱讀。