必须切换到sass(dart sass),因libsass自2020年10月停更,node-sass无法支持新语法、node 16+及apple silicon,且安装易失败、编译慢;迁移需三步:卸载node-sass、安装sass与新版sass-loader、webpack中显式指定implementation。

LibSass 编译失效不是配置问题,是底层已停更——node-sass 无法再编译新语法、无法在 Node 16+ 或 Apple Silicon 上可靠运行,必须切换到 sass(Dart Sass)。
为什么 node-sass 会突然报错或安装失败
错误现象常见于:npm install node-sass 卡住、node-gyp 编译失败、CI 流水线下载二进制超时、Unsupported engine 警告。根本原因是 LibSass 自 2020 年 10 月起停止维护,node-sass 只是它的封装,不再适配新 Node 版本或新 CPU 架构。
- Node 16+ 环境下,
node-sass@4.x直接拒绝安装;升级到@5.x又可能和sass-loader版本冲突 - Mac M1/M2/M3 芯片默认无预编译二进制,强制走本地编译,而系统已无 Python 2.7 支持
-
@use、@forward、sass:math等语法一写就报Invalid CSS after "@use",因为node-sass根本不识别
Webpack 项目中必须显式指定 implementation
即使装了 sass,如果 Webpack 的 sass-loader 配置没改,它仍可能 fallback 到残留的 node-sass 或报 Cannot find module 'node-sass'。关键动作不是“换包”,而是“切断旧链路”。
- 先执行
npm uninstall node-sass(不能留,否则 loader 会静默回退) - 安装
npm install sass sass-loader@latest --save-dev(sass-loader@12+才完整支持模块缓存) - 在 Webpack 的
module.rules中,sass-loader配置里加:implementation: require("sass") - Vue CLI 用户注意:
@vue/cli-service@4.x默认带sass-loader@10,必须手动升级;@vue/cli-service@5+才内置 Dart Sass 支持
@use 报错或不生效?检查路径与作用域规则
@use 不是 @import 的别名,它有严格路径限制和符号导出规则。很多“迁移后样式崩了”的问题其实出在这里,而非编译器本身。
-
@use "/styles/_mixins.scss"必然失败:以_开头的文件是私有文件,不能被@use直接引用;应重命名为mixins.scss或用@forward "mixins" as *导出 - 在 Vue 的
style标签lang="scss"中用additionalData注入@use,会导致每个组件都独立解析该模块,完全破坏缓存价值 -
@use "sass:math"在 Dart Sass 中可用,但node-sass会直接报错;迁移后需同步检查所有内置模块调用是否合规 - 除法运算如
100px / 2在 Dart Sass 中触发警告:WARNING: Using / for division is deprecated,应改用math.div(100px, 2)
深度选择器(/deep/、>>>)失效怎么办
这不是 Dart Sass 的 bug,而是 Vue 2 的 scoped style 机制与新编译器语法校验的冲突。/deep/ 和 >>> 是非标准伪选择器,LibSass 曾宽松放行,Dart Sass 严格执行 CSS 语法规范,遇到就报 SassError: expected selector。
- Vue 2 项目中,应统一替换为
::v-deep()函数写法:::v-deep(.child) { color: red; } - 更推荐方案:升级到
vue-loader@15.9+后,启用vue-style-loader的scoped模式自动转换,避免手写穿透 - 若项目暂无法升级 vue-loader,可在
sass-loader的additionalData中注入全局变量绕过,但属临时 hack,不宜长期依赖
真正难的不是换命令,而是识别哪些“习以为常”的写法其实是历史包袱——@import 全局展开、裸除法、私有文件直引、深度选择器硬写。Dart Sass 的严格,本质是在帮你提前暴露技术债。











