背景
后台项目使用 scss 文件来编写项目的样式文件,并使用antd-scss-theme-plugin
这个插件来使用 sass 变量设置antd 3
组件库的主题(antd 3
官方使用 less 变量实现)。
该antd-scss-theme-plugin
已经停止维护,其依赖的也已经停止维护的scss-to-json
包指定了node-sass^3.1.2, ^4.0.0
为 sass 编译器。
而node-sass
作为一个已经停止更新的包,因为与sass-loader
和node
版本强绑定一直为社区诟病。官方已经停止更新并推荐使用dart-sass
,其兼容node-sass
的所有 api,并且得到了更好的维护和支持。
再看看JY们在一篇不久前发布的文章 又报gyp ERR!为什么有那么多人被node-sass 坑过?node-sass: Command failed 评论区的吐槽:
在我的开发过程中,也是苦node-sass
久矣,本地安装项目依赖会因为各种问题(主要是node
版本、网络等)导致node-sass
安装失败,严重影响开发效率😡。所以我决定将项目的node-sass
切换到dart-sass
上。
对比
- 维护和支持:
dart-sass
是 Sass 官方推荐的编译器,得到了更好的维护和支持; - 性能:虽然
node-sass
在某些情况下编译速度更快,但dart-sass
在不断的更新中已经显著提高了性能,并且更加稳定; - 跨平台兼容性:
dart-sass
不依赖于本地编译,因此在不同的操作系统上的一致性和兼容性更好; - 发展:Sass 团队明确表示,未来的功能和改进将主要集中在
dart-sass
上。
变更
因为是scss-to-json
这个包指定使用的node-sass
,所以尝试fork
该npm
包修改后发布私包,在该包Github
的issue
中,发现了scss-json
这个项目兼容了scss-to-json
的api
并且使用dart-sass
作为编译器,完美符合我的需求。
于是我fork
了antd-scss-theme-plugin
,并指定使用scss-json
替代scss-to-json
来编译scss
文件。重新安装依赖后,项目可以正常编译运行。但是dart-sass
在1.79.1
版本后会提示^2.0
版本将会废弃部分项目中已经在使用的api
sass - npm (npmjs.com),虽然不影响项目运行,但是控制台有太多警告,影响开发体验。所以我锁定了dart-sass
的版本在scss-json
这个包中指定的sass
最低版本1.50.1
上,来解决本地运行警告问题。
使用compileString
替代renderSync
使符合dart-sass
写法,并优化字符串操作方法获得有限的性能提升。
var sass = require("sass");
// var cssmin = require("cssmin");
// var s = sass.renderSync({ data: scssString });
// return cssmin(String(s.css))
var s = sass.compileString(scssString,{ style: "compressed", charset: false })
return s.css
这样项目就成功地从node-sass
切换到了dart-sass
,使用多个版本的node
都可以成功安装运行✅。
运行对比
最后
虽然,dart-sass
可以完美兼容node-sass
的所有api
,但是对于大型项目,node-sass
还是有着 ta 的性能优势。官方也发布了嵌入式 Sass(embedded-sass)来解决该性能问题,但目前我并没有发现社区有很多关于embedded-sass
的使用经验,且我们的后台项目在切换到dart-sass
后也没有明显的性能问题,所以暂时不考虑升级到embedded-sass
上。
加更
我尝试了使用sass-embedded
来作为scss-json
中的 sass 编译器,在直接替换未进行任何代码改动的情况下,项目本地冷启动从原本的2-4
分钟延长到了6-7
分钟,生成物(含sourcemap
)从40MB
增大到了48MB
😥。暂时还是不考虑引入了…