加载 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-embeddedsassnode-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 变量依赖于环境时,这尤其有用
stringmodule.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: "$env: " + process.env.NODE_ENV + ";",
},
},
],
},
],
},
};
functionmodule.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和modernAPI 的 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 以获取一个工作示例。
我们欢迎所有贡献!如果您是新用户,请在提交问题或拉取请求之前花一些时间阅读我们的贡献指南。