直接换 node-sass 为 sass 不等于迁移完成——真正卡住构建的是 @import 语义变更、calc() 解析失败及残留 implementation 配置;需彻底清理依赖、升级匹配版本、重写 @import 为 @use、修正函数调用与深度选择器,并优化 includepaths 和 sourcemap。

直接换 node-sass 为 sass 不等于迁移完成——真正卡住构建的,是 @import 语义变更、calc() 解析失败、以及残留的 implementation 配置。
确认 node-sass 是否真被清干净
别信 package.json 里删了就完事。执行:
npm ls node-sass
如果输出非空,说明它还在依赖树里(比如被 element-ui 或旧版 vue-cli-service 暗中拉入)。同时跑:
npm ls sass
若两者共存,sass-loader 默认仍会 fallback 到 node-sass,除非你显式切断。
- 搜全项目:
grep -r "node-sass" . --include="*.js" --include="*.ts",重点检查vue.config.js、webpack.config.js、vue.config.js中是否还有implementation: require('node-sass') - 某些 UI 库的 scss 文件可能隐式依赖
node-sass的行为(如未加引号的url()),卸载后要验证样式是否正常渲染
sass-loader 版本必须匹配 sass@1.80
sass@1.80 要求 sass-loader@14.2.0+,而 Vue CLI 4.x 默认只带 sass-loader@10,强行升级会导致 this.getOptions is not a function 报错。
- Vue CLI 4 用户:先升级
@vue/cli-service到4.5.19+,再装sass-loader@14.2.1(不是@latest) - Webpack 5 用户:确保
sass-loader配置中删掉implementation字段——现代版本自动找sass,写死反而触发 fallback - 装完立刻清缓存:
rm -rf node_modules/.cache,否则 Webpack 可能复用旧 loader 缓存,继续用node-sass
@import 必须重写为 @use,否则 calc() / color-mix() 直接崩
node-sass 把 calc(100% / 3) 中的 / 当除法运算符,词法层就报错;sass@1.80 按 CSS 规范解析,但前提是模块系统启用——@import 不触发模块缓存,@use 才行。
-
@import "variables"→ 改成@use "variables" as v(文件需是_variables.scss,路径以./或../开头) -
percentage($val)失效 → 改用math.percentage($val)(percentage()是 libsass 特有,已移入sass:math) -
::v-deep .foo报错 → 确保有空格:::v-deep .foo(::v-deep.foo被当伪类名解析,无效) - 所有
/deep/和>>>全部删除,loader 层已不支持降级
编译慢?先砍掉 includePaths 和 sourceMap
用了 sass@1.80 还慢,大概率是配置在拖后腿:
-
includePaths: ["node_modules"]是 I/O 灾难——编译器会递归扫描整个node_modules查找@use目标,删掉或精确到具体路径(如["node_modules/bootstrap/scss"]) -
sourceMap: true在生产环境开启 → 关掉,生成映射耗时可占总编译时间 40%+ -
additionalData里写@use→ 每个.vue文件都触发独立模块解析,彻底废掉@use的缓存价值,应统一提至入口main.scss
真正难的不是换包,而是接受:LibSass 的“宽容”其实是放任非法 CSS;Dart Sass 的“报错”,才是规范本该有的样子。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











