sass-loader 编译慢的核心原因是@import递归解析和作用域检查导致指数级性能下降;应改用@use、禁用sourcemap、清理additionaldata,并切换至dart sass实现。

默认配置下 sass-loader 编译慢,核心原因是它在解析阶段做了太多事——尤其是 @import 递归和作用域检查,文件一多就指数级拖慢。光换 loader 或加缓存没用,得从输入、解析、输出三层动手。
为什么 sass-loader 越来越慢?
不是 CPU 不够,是 Sass 解析器本身设计导致的:每遇到一个 @import 就要重新加载、词法分析、作用域合并;变量/mixin 的可见性检查也随文件数增长而变重。PostCSS 没这问题,因为它不解析逻辑,只做字符串/AST 变换。
- 项目里有 20+ 个
@import的 SCSS 文件?编译时间可能翻 3 倍以上 - 用了
@use但混着@import?Sass 会回退到旧解析模式,失去模块化优势 - 全局
additionalData注入了大段 mixin 或变量?每次编译都重复解析一遍
禁用 @import,改用 @use + 显式路径
@import 是 Sass 旧语法,无法做静态分析,loader 必须全量解析所有依赖;@use 支持 tree-shaking 和作用域隔离,Webpack 能提前判断哪些文件真被引用。
- 把
_variables.scss改成variables.scss(去掉下划线),否则@use "variables"会报错 - 路径必须写全:
@use "@/styles/mixins" as *;,不能省略@/或用相对路径../mixins - 避免在
additionalData里写@use—— 它会被注入到每个文件开头,导致重复解析
关掉 sourceMap + 清理 additionalData
sourceMap 在生产构建中不仅没调试价值,还会让 sass-loader 多读一次 .map 文件并嵌入 base64 内容;additionalData 里的注释、未用变量、@debug 全部照单全收进输出 CSS。
- 明确设
sourceMap: false,别依赖sass包的默认值(Dart Sass@1.80+ 默认true) - 把全局变量抽成独立文件,用
@use引入,而不是拼字符串塞进additionalData - 检查
additionalData是否含@warn或条件块,这些在compressed模式下会被静默丢弃,上线后“消失”难排查
用 implementation 指向 Dart Sass 并启用现代 API
node-sass 已停更,Dart Sass 是唯一持续更新的实现,且自带性能优化(比如 faster import resolution、lazy evaluation)。但 webpack 默认不启用它的新 API,需手动指定。
- 安装时只留
sass:npm uninstall node-sass && npm install sass - 在
sass-loader的options里加:implementation: require('sass') - 确保
sass-loader≥ v12.6,否则implementation参数会被忽略
真正卡住编译的,往往不是某一行代码写错了,而是 Sass 解析器在反复 resolve 同一个路径、或为没用上的 mixin 做作用域检查——这些动作看不见,但占了 70% 以上时间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











