迁移器 Migrator

Sass 迁移器会自动更新您的 Sass 文件,帮助您升级到最新、最好的语言版本。其每个命令都会迁移一项功能,让您尽可能地控制更新的内容和时间。

Usage

要使用 Sass 迁移器,请告诉它您要运行哪个迁移以及要迁移哪些 Sass 文件:

bash
sass-migrator <migration> <entrypoint.scss...>

默认情况下,迁移器只会更改您在命令行上明确传递的文件。传递 --migrate-deps 选项 会告知迁移器还更改使用 @use 规则@forward 规则@import 规则 加载的所有样式表。如果您想进行测试运行以查看将进行哪些更改而不实际保存它们,您可以传递 [--dry-run](/cli/migrator#dry-run) [--verbose](/cli/migrator#verbose)(或简称为 -nv)。

bash
$ cat style.scss
$body-bg: #000;
$body-color: #111;

@import "bootstrap";

@include media-breakpoint-up(sm) {
  .navbar {
    display: block;
  }
}
$ sass-migrator --migrate-deps module style.scss
$ cat style.scss
@use "bootstrap" with (
  $body-bg: #000,
  $body-color: #111
);

@include bootstrap.media-breakpoint-up(sm) {
  .navbar {
    display: block;
  }
}

Installation

您可以从与安装 Dart Sass 相同的大多数位置安装 Sass 迁移器:

Standalone

您可以在 Windows、Mac 或 Linux 上安装 Sass 迁移器,方法是从 GitHub 下载适合您操作系统的软件包并 将其添加到您的 PATH

npm

如果您使用 Node.js,您也可以通过运行以下命令使用 npm 安装 Sass 迁移器

npm install -g sass-migrator

Chocolatey

如果您在 Windows 上使用 Chocolatey 包管理器,您可以通过运行以下命令安装 Sass 迁移器

bash
choco install sass-migrator

Homebrew

如果您在 Mac OS X 上使用 Homebrew 包管理器,您可以通过运行以下命令安装 Dart Sass

bash
brew install sass/sass/migrator

全局选项

这些选项适用于所有迁移器。

--migrate-deps

此选项(缩写为 -d)告诉迁移器不仅要更改在命令行上明确传递的样式表,还要更改它们使用 @use 规则@forward 规则@import 规则 所依赖的任何样式表。

bash
$ sass-migrator module --verbose style.scss
Migrating style.scss
$ sass-migrator module --verbose --migrate-deps style.scss
Migrating style.scss
Migrating _theme.scss
Migrating _fonts.scss
Migrating _grid.scss

⚠️ Heads up!

模块迁移器 假定使用 @use 规则@forward 规则 所依赖的任何样式表都已迁移到模块系统,因此即使传递了 --migrate-deps 选项,它也不会尝试迁移它们。

--load-path

此选项(缩写为 -I)告诉迁移器应在其中查找样式表的 加载路径。它可以多次传递以提供多个加载路径。较早的加载路径将优先于较晚的加载路径。

从加载路径加载的依赖项被视为第三方库,因此即使传递了 --migrate-deps 选项,迁移器也不会迁移它们。

--dry-run

此标志(缩写为 -n)告诉迁移器不要将任何更改保存到磁盘。相反,它会打印将要更改的文件列表。这通常与 --verbose 选项 配对,以打印将要进行的更改的内容。

bash
$ sass-migrator module --dry-run --migrate-deps style.scss
Dry run. Logging migrated files instead of overwriting...

style.scss
_theme.scss
_fonts.scss
_grid.scss

--no-unicode

此标志指示 Sass 迁移器仅将 ASCII 字符作为错误消息的一部分发送到终端。默认情况下,或者如果传递了 --unicode,迁移器将为这些消息发出非 ASCII 字符。此标志不会影响 CSS 输出。

bash
$ sass-migrator --no-unicode module style.scss
line 1, column 9 of style.scss: Error: Could not find Sass file at 'typography'.
  ,
1 | @import "typography";
  |         ^^^^^^^^^^^^
  '
Migration failed!
$ sass-migrator --unicode module style.scss
line 1, column 9 of style.scss: Error: Could not find Sass file at 'typography'.
1 │ @import "typography";
  │         ^^^^^^^^^^^^
Migration failed!

--verbose

此标志(缩写为 -v)指示迁移器将额外信息打印到控制台。默认情况下,它只打印已更改文件的名称,但当与 --dry-run 选项 结合使用时,它还会打印这些文件的新内容。

bash
$ sass-migrator module --verbose --dry-run style.scss
Dry run. Logging migrated files instead of overwriting...
<==> style.scss
@use "bootstrap" with (
  $body-bg: #000,
  $body-color: #111
);

@include bootstrap.media-breakpoint-up(sm) {
  .navbar {
    display: block;
  }
}
$ sass-migrator module --verbose style.scss
Migrating style.scss

迁移

除法

此迁移将使用 / 作为除法 的样式表转换为使用内置的 math.div 函数。

--pessimistic

默认情况下,迁移器将 / 操作转换为 math.div,即使它不确定在评估时是否为除法。只有当它可以静态确定它们正在执行其他操作时(例如当不涉及 SassScript 时,或者当其中一个操作数是字符串时),它才会保持原样。math.div 函数当前与 / 运算符的功能相同,因此这样做是安全的,但如果运行时 math.div 的参数之一不是数字,可能会导致新的警告。

如果您想避免这种行为,可以传递 --pessimistic 标志。使用此标志,迁移器将仅转换它确定执行除法的 / 操作。这将防止任何不必要的 math.div 转换,但如果无法静态确定,则可能会留下一些未迁移的除法。

模块

此迁移将转换使用旧 @import 规则 加载依赖项的样式表,以便它们通过 @use 规则 使用 Sass 模块系统。它不是简单地将 @import 更改为 @use,而是智能地更新样式表,以便它们继续以与以前相同的方式工作,包括:

  • 为来自其他模块的成员(变量、混合和函数)的使用添加命名空间。
  • 为使用成员但不导入它们的样式表添加新的 @use 规则。
  • 将覆盖的默认变量转换为 with 子句
  • 自动从其他文件使用的成员中删除 -_ 前缀(否则它们将被视为 private 并且只能在声明它们的模块中使用)。
  • 嵌套导入 转换为使用 meta.load-css() mixin

⚠️ 注意!

由于模块迁移器可能需要修改成员定义和成员名称,因此必须使用 --migrate-deps 选项 运行它,或者确保将包或应用程序中的所有样式表传递给它。

bash
$ cat style.scss
$body-bg: #000;
$body-color: #111;

@import "bootstrap";

@include media-breakpoint-up(sm) {
  .navbar {
    display: block;
  }
}
$ sass-migrator --migrate-deps module style.scss
$ cat style.scss
@use "bootstrap" with (
  $body-bg: #000,
  $body-color: #111
);

@include bootstrap.media-breakpoint-up(sm) {
  .navbar {
    display: block;
  }
}

加载依赖项

模块迁移器需要能够读取其正在迁移的样式表所依赖的所有样式表,即使未传递 --migrate-deps 选项。如果迁移器无法找到依赖项,您将收到错误。

bash
$ ls .
style.scss  node_modules
$ sass-migrator module style.scss
Error: Could not find Sass file at 'dependency'.
  ,
1 | @import "dependency";
  |         ^^^^^^^^^^^^
  '
  style.scss 1:9  root stylesheet
Migration failed!
$ sass-migrator --load-path node_modules module style.scss

如果您在编译样式表时使用 加载路径,请确保使用 --load-path 选项 将其传递给迁移器。

遗憾的是,迁移器不支持自定义导入器,但它确实内置了对通过在 node_modules 中搜索来解析以 ~ 开头的 URL 的支持,类似于 Webpack 支持的功能

--remove-prefix

此选项(缩写为 -p)采用标识符前缀,在迁移时从所有变量、混合和函数名称的开头删除它们。不以此前缀开头的成员将保持不变。

@import 规则 将所有顶级成员放在一个全局范围内,因此当它是加载样式表的标准方式时,每个人都会倾向于为所有成员名称添加前缀,以避免意外重新定义其他样式表。模块系统解决了这个问题,因此现在自动删除那些不必要的旧前缀非常有用。

bash
$ cat style.scss
@import "theme";

@mixin app-inverted {
  color: $app-bg-color;
  background-color: $app-color;
}
$ sass-migrator --migrate-deps module --remove-prefix=app- style.scss
$ cat style.scss
@import "theme";

@mixin inverted {
  color: theme.$bg-color;
  background-color: theme.$color;
}

当您传递此选项时,迁移器还将生成一个 仅导入样式表,该样式表 转发 所有添加前缀的成员,以保留导入库的用户的向后兼容性。

此选项可以多次传递,也可以使用逗号分隔的多个值传递。每个前缀都将从具有它的任何成员中删除。如果成员与多个前缀匹配,则将删除最长的匹配前缀。

--forward

此选项告诉迁移器使用 @forward 规则 转发哪些成员。它支持以下设置:

  • none(默认)不转发任何成员。
  • all 转发除原始样式表中以 -_ 开头的成员之外的所有成员,因为在引入模块系统之前,这通常用于标记包私有成员。
  • prefixed 仅转发以传递给 --remove-prefix 选项 的前缀开头的成员。此选项只能与 --remove-prefix 选项结合使用。

在命令行上明确传递的所有文件都将转发由这些文件使用 @import 规则传递加载的成员。使用 --migrate-deps 选项 加载的文件不会转发任何新成员。此选项在迁移 Sass 库时特别有用,因为它可确保该库的用户仍能访问其定义的所有成员。

bash
$ cat _index.scss
@import "theme";
@import "typography";
@import "components";
$ sass-migrator --migrate-deps module --forward=all style.scss
$ cat _index.scss
@forward "theme";
@forward "typography";
@forward "components";

命名空间

此迁移允许您轻松更改样式表中 @use 规则的 命名空间。如果模块迁移器为解决冲突而生成的命名空间不理想,或者您不想使用 Sass 根据规则的 URL 确定的默认命名空间,则此功能很有用。

--rename

您可以通过将表达式传递给 --rename 选项来告诉迁移器您希望它更改哪个命名空间。

这些表达式的形式为 <old-namespace> to <new-namespace>url <rule-url> to <new-namespace>。在这些表达式中,<old-namespace><rule-url>正则表达式,分别与现有命名空间的整个部分或 @use 规则的 URL 匹配。

对于简单的用例,这看起来就像 --rename 'old to new',它会将命名空间为 old@use 规则重命名为 new

但是,您也可以这样做来完成更复杂的重命名。例如,假设您之前有一个如下所示的样式表:

bash
@import "components/button/lib/mixins";
@import "components/input/lib/mixins";
@import "components/table/lib/mixins";
// ...

由于所有这些 URL 在迁移到 @use 规则时都会具有默认命名空间 mixins,因此模块迁移器最终可能会生成类似以下内容:

bash
@use "components/button/lib/mixins" as button-lib-mixins;
@use "components/input/lib/mixins" as input-lib-mixins;
@use "components/table/lib/mixins" as table-lib-mixins;
// ...

这是有效代码,因为命名空间不冲突,但它们比需要的要复杂得多。URL 的相关部分是组件名称,因此我们可以使用命名空间迁移器将该部分提取出来。

如果我们使用 --rename 'url components/(\w+)/lib/mixins to \1' 运行命名空间迁移器,我们最终会得到:

bash
@use "components/button/lib/mixins" as button;
@use "components/input/lib/mixins" as input;
@use "components/table/lib/mixins" as table;
// ...

此处的重命名脚本表示查找所有 URL 类似于 components/(\w+)/lib/mixins@use 规则(正则表达式中的 \w+ 表示匹配任何一个或多个字符的单词)。输出子句中的 \1 表示替换正则表达式中第一组括号的内容(称为 group)。

如果您希望应用多个重命名,可以多次传递 --rename 选项,或用分号或换行符分隔它们。只有适用于给定规则的第一个重命名才会被使用,因此您可以传递类似 --rename 'a to b; b to a' 的内容来交换命名空间 ab

--force

默认情况下,如果两个或多个 @use 规则在迁移后具有相同的命名空间,则迁移器将失败,并且不会进行任何更改。

在这种情况下,您通常需要调整 --rename 脚本以避免产生冲突,但如果您希望强制迁移,则可以传递 --force

使用 --force,如果遇到任何冲突,第一个 @use 规则将获得其首选命名空间,而具有相同首选命名空间的后续 @use 规则将添加数字后缀。