加载 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
[!注意]
要在你的项目中启用 CSS 处理,你需要通过
npm i style-loader css-loader
安装 style-loader 和 css-loader。
sass-loader
要求你自己安装 Dart Sass、Node Sass(更多文档可在下方找到)或 Sass Embedded。
这使你能够控制所有依赖的版本,并选择要使用的 Sass 实现。
[!注意]
我们强烈建议使用 Sass Embedded 或 Dart Sass。
[!警告]
将 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",
],
},
],
},
};
最后,通过你喜欢的方式(例如,通过 CLI 或 npm 脚本)运行 webpack
。
style
(新 API,默认自 16 版本起)和 outputStyle
(旧 API)选项对于 production
模式,style
(新 API,默认自 16 版本起)和 outputStyle
(旧 API)选项默认为 compressed
,除非在 sassOptions
中另有指定。
import
和 use
at-rulesWebpack 提供了一种高级的文件解析机制。
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";
是一样的。
由于 Sass 实现不提供 URL 重写,所有链接的资产必须相对于输出。
css-loader
,所有 URL 必须相对于入口文件(例如 main.scss
)。css-loader
,URL 必须相对于你的 Web 根目录。你可能会对第一个问题感到惊讶,因为通常会期望相对引用根据它们所在的 `.sass`/.scss 文件解析(就像常规 `.css` 文件一样)。
幸运的是,这个问题有两个解决方案
使用 resolve-url-loader 添加缺失的 URL 重写。将其放置在加载器链中的 sass-loader
之前。
库作者通常会提供一个变量来修改资产路径。例如,bootstrap-sass 有一个 $icon-font-path
。
implementation
类型
type implementation = object | string;
默认值:sass
特殊的 implementation
选项决定使用哪个 Sass 实现。
默认情况下,加载器根据你的依赖解析实现。只需将所需的实现添加到你的 package.json
(sass
、sass-embedded
或 node-sass
包)并安装依赖项。
sass-loader
使用 sass
(`dart-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"
}
}
sass-loader
使用 sass-embedded
实现的示例
package.json
{
"devDependencies": {
"sass-loader": "^7.2.0",
"sass": "^1.22.10"
},
"optionalDependencies": {
"sass-embedded": "^1.70.0"
}
}
[!注意]
使用
optionalDependencies
意味着当在sass-embedded
不支持的操作系统上运行时,sass-loader
可以回退到sass
请注意 sass-loader
解析实现的顺序
sass-embedded
sass
node-sass
你可以通过使用 implementation
选项来指定特定的实现,该选项接受上述值之一。
object
例如,要始终使用 Dart Sass
,你可以传入
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
// Prefer `dart-sass`, even if `sass-embedded` is available
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`, even if `sass-embedded` is available
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](https://sass-lang.cn/dart-sass) 或 [Node Sass](https://github.com/sass/node-sass) 实现的选项。
[!注意]
对于
dart-sass
,charset
选项默认为true
。我们强烈不建议将其设置为false
,因为 webpack 不支持utf-8
以外的文件。
[!注意]
syntax
(新 API,默认自 16 版本起)和indentedSyntax
(旧 API)选项对于scss
扩展是scss
,对于sass
扩展是indented
,对于css
扩展是css
。
[!注意]
data
和file
等选项不可用,将被忽略。
ℹ 我们强烈不建议更改
sourceMap
(新 API,默认自 16 版本起)、outFile
(旧 API)、sourceMapContents
(旧 API)、sourceMapEmbed
(旧 API)和sourceMapRoot
(旧 API)选项,因为当sourceMap
选项为true
时,sass-loader
会自动设置这些选项。
[!注意]
在自定义导入器内部访问加载器上下文 可以通过
this.webpackLoaderContext
属性完成。
sass
(`dart-sass`) 和 node-sass
的选项略有不同。
使用前请查阅它们各自的文档
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: {
style: `compressed`,
loadPaths: ["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: (loaderContext) => {
// More information about available properties https://webpack.js.cn/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === "styles/foo.scss") {
return {
loadPaths: ["absolute/path/c", "absolute/path/d"],
};
}
return {
loadPaths: ["absolute/path/a", "absolute/path/b"],
};
},
},
},
],
},
],
},
};
sourceMap
类型
type sourceMap = boolean;
默认值:取决于 compiler.devtool
的值
启用/禁用源映射生成。
默认情况下,源映射的生成取决于 devtool
选项。除 eval
和 false
外,所有值都启用源映射生成。
ℹ 如果为
true
,sassOptions
中的sourceMap
(新 API,默认自 16 版本起)、outFile
(旧 API)、sourceMapContents
(旧 API)、sourceMapEmbed
(旧 API)和sourceMapRoot
(旧 API)将被忽略。
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
的 bug)。为了避免这种情况,你可以尝试将
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 变量依赖于环境时,这尤其有用
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.js.cn/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.js.cn/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-rules 将不起作用。你可以传入你自己的 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" | "modern-compiler";
默认值:对于 sass
(`dart-sass`) 和 sass-embedded
为 "modern"
,对于 node-sass
为 "legacy"
允许你在 legacy
和 modern
API 之间切换。你可以在这里找到更多信息。modern-compiler
选项启用支持共享资源的现代 API。
[!注意]
同时使用
modern-compiler
和sass-embedded
可以显著提高性能并缩短构建时间。我们强烈建议使用它们。我们将在未来的主要版本中默认启用它们。
[!警告]
legacy
和modern
API 的 Sass 选项有所不同。请查阅文档以了解如何迁移到现代选项。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
api: "modern-compiler",
sassOptions: {
// Your sass options
},
},
},
],
},
],
},
};
@debug
输出默认情况下,@debug
消息的输出是禁用的。将以下内容添加到 webpack.config.js 以启用它们
module.exports = {
stats: {
loggingDebug: ["sass-loader"],
},
// ...
};
对于生产构建,建议从你的 bundle 中提取 CSS,以实现 CSS/JS 资源的并行加载。
有四种推荐的方法可以从 bundle 中提取样式表
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 以获取一个工作示例。
我们欢迎所有贡献!如果您是新用户,请在提交问题或拉取请求之前花一些时间阅读我们的贡献指南。