最近在批改一个我的项目的时候,发现了一系列的 Sass 的告警——由除号引起的告警:
目录
- 什么告警?
-
如何解决告警?
- 降级 sass 模块
- 更新业务语法
- 应用 sass-migrator
-
Dart Sass Vs Node Sass
- Dart Sass on Dart-VM 与 Dart Sass on NPM
什么告警?
告警的内容很简略,用 /
作为除法曾经在 Dart Sass 2.0.0 中被弃用了,作为一个 Sass 的根底语法,这次弃用属于 breaking change 了,因而目前编译时只是会抛出 warning 而不是 error,否则大量我的项目都无奈失常运行。
钻研了一下能够看到,Sass 官网特定用了一整个篇幅的文章,来论述为何要作出这个批改,次要的起因在于,/
在 Sass 中同时承当除号以及 CSS 分隔符的作用,例如:
Sass 代码
// 作为除号应用
.test_division {border-radius: ceil(28px / 2);
}
// 作为 CSS 分隔符应用
.test_operator {font: 12px/1.5 -apple-system, "SF UI Text", "PingFang SC", "Lucida Grande", "Microsoft YaHei", sans-serif;}
理论编译出的 CSS 代码
.test_division {border-radius: 14px;}
.test_operator {font: 8px -apple-system, "SF UI Text", "PingFang SC", "Lucida Grande", "Microsoft YaHei", sans-serif;}
示例中有两个 /
,一个用作除号,另一个是作为 font
属性中 font-size
和 line-height
的分隔符,能够看到作为除号应用的时候,/
个别不会呈现什么问题,然而作为分隔符应用的时候,/
很容易被重载为除号,实际上要实现分隔符的成果,通常须要这样编写:
.test_operator {font: #{12px/1.5} -apple-system, "SF UI Text", "PingFang SC", "Lucida Grande", "Microsoft YaHei", sans-serif;
}
应用了插值(Interpolation)语法,包裹了 12px/1.5
,插值的作用是仅解析 Sassscript,把 Sass 变量输入为理论的值,但不会进行运算,如果属性值比较复杂,则会导致编写的时候不大直观。
Sass 自身应用了 complex heuristics 的技术去判断 /
应该作为除号还是分隔符,complex heuristics 是须要回顾以后上下文的内容,来作出断定的,因而对于 Sass 来说存在肯定耗费。
综合来说,原有的 /
语法对于开发者会带来一些困扰,尤其是随着 CSS 有更多的属性应用到了分隔符(例如 grid
、hsl()
等语法),同时对于 Sass 的保护以及编译也会带来一些额定的耗费,所以 Sass 最终决定从新定义除法,新的语法也相当清晰:
@use "sass:math";
.test_division {border-radius: math.div(28px, 2);
}
新的语法基于 Sass 的 module 语法,引入了相干的运算模块后,就能够调用 math.div
代替原来的 /
,而 /
则只作为分隔符应用。
如何解决告警?
要解决告警,首先要晓得为何我的项目中会呈现这个告警,用到了这个语法的我的项目比拟多,但目前只有这个我的项目呈现了告警。
首先这个 breaking change 仅在 Dart Sass 的最新版本中才引入,Node Sass 的版本目前还没有跟上。另外该我的项目中是应用 "sass": "^1.30.0"
来申明 sass 模块的版本(即 Dart Sass 的 npm 包),从新执行 npm i
会导致装置上新版的 Dart Sass 从而呈现告警,因而解决方案也围绕 Dart Sass 版本去解决。
降级 sass 模块
删除 package-lock.json
与 node_modules
,把 package.json
中 sass 模块的版本改为 "sass": "~1.32.12"
,即版本号会少于 1.33.0
,这个版本的 Dart Sass 并未引入 slash as division 的 breaking change。
更新业务语法
即按下面提到的形式,把相干的告警内容改为用新的 math.div
语法代替,如果波及的业务量比拟大,更新起来会比拟费时。
应用 sass-migrator
sass-migrator 是 Sass 官网推出的迁徙工具,不便开发者对原有的业务代码进行最新版本的 Sass 适配。sass-migrator 并不是把相干的旧语法间接替换为最新的语法,而且采纳更巩固的形式,把代码平安地更新为合乎最新要求的语法,例如下面的例子:
Sass 代码
.test_division {border-radius: ceil(28px / 2);
}
sass-migrator 的装置与调用
npm i -g sass-migrator
sass-migrator division test.scss
解决后的 Sass 代码
.test_division {border-radius: ceil(28px * 0.5);
}
能够看到,sass-migrator 并没有把原有的 /
批改为最新的 math.div
语法,而是批改为用乘法代替。实际上跟 sass 基于 complex heuristics 进行剖析会把分隔符重载为除号一样,迁徙工具也无奈精确地判断每个 /
的作用,因而 sass-migrator 采纳了巩固的形式去适配最新的 Sass 规定。
Dart Sass Vs Node Sass
Node Sass 因为没有引入最新的 Sass 个性,因而并不会呈现这个告警,但并不倡议应用 Node Sass 代替曾经用 Dart Sass 编写的代码,次要是:
- Dart Sass 曾经是官网的首选,无论是新个性还是问题修复,Dart Sass 会有更强的时效性,放心新个性会为业务带来问题能够通过锁包进行管制。
- Node Sass 实际上曾经被官网定义为 deprecated,目前我的项目会保护一个次要版本,然而保护进度并不确定,并且明确没有打算再为 Node Sass 增加新个性,也不会适配 CSS 的新个性。
- Node Sass 基于 LibSass 开发,而 LibSass 依赖了的模块装置比拟麻烦,尤其是对于 Windows 的用户,它要求用户在 Windows 中必须装置 Python2 和 Visual Studio。
因而出于长期保护的思考,选用 Dart Sass 也是一个趋势。
Dart Sass on Dart-VM 与 Dart Sass on NPM
目前 Dart Sass 有两种实现,别离是:
- 基于 Dart-VM 的 Dart Sass
- 基于纯 JavaScript 的 Dart Sass
依据官网的介绍,独自运行的命令行版本,是基于 Dart-VM 运行的,得益于 Dart-VM 的高性能,这个版本的 Dart Sass 性能十分好,适宜用于编写脚本独自编译 Sass 文件。
而 NPM 中的 Dart Sass 则是纯 JavaScript 实现,因而能够很不便地用于前端我的项目构建。尽管 JavaScript 版本的 Dart Sass 性能比 LibSass 要差一些,然而对于款式代码的编译量来说,区别并不大。
上图是 Dart Sass on Dart-VM、Dart Sass on NPM、Node Sass 别离去编译 BootStrap 4 的耗时(来源于 Stack Overflow),能够看出 Dart Sass on NPM(即 Dart Sass JS) 比 Node Sass 还要慢很多(大略 3 倍的耗时),但实际上即便是 Bootstrap 这个体量,也只是 2 秒的耗时,思考到官网和社区都逐渐迁徙到 Dart Sass 了,因而新我的项目也倡议应用 Dart Sass。