关于sass:从-Sass-Breaking-Change-Slash-as-Division-说起

121次阅读

共计 3134 个字符,预计需要花费 8 分钟才能阅读完成。

最近在批改一个我的项目的时候,发现了一系列的 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-sizeline-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 有更多的属性应用到了分隔符(例如 gridhsl() 等语法),同时对于 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.jsonnode_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 编写的代码,次要是:

  1. Dart Sass 曾经是官网的首选,无论是新个性还是问题修复,Dart Sass 会有更强的时效性,放心新个性会为业务带来问题能够通过锁包进行管制。
  2. Node Sass 实际上曾经被官网定义为 deprecated,目前我的项目会保护一个次要版本,然而保护进度并不确定,并且明确没有打算再为 Node Sass 增加新个性,也不会适配 CSS 的新个性。
  3. 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。

正文完
 0