天天看点

Prettier 3.0 如期发布:高调宣称支持 ESM!

作者:高级前端进阶

大家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。

Prettier 3.0 如期发布:高调宣称支持 ESM!

今天给大家带来的主题是 Prettier 3.0 版本的发布,一起聊聊在该版本带来的核心更新。话不多说,直接进入正题!

1.Prettier 3.0概览

Prettier 是一个代码格式化程序,它通过解析代码并使用自己的规则重新自动打印输出代码(考虑最大行长度)来强制执行一致的样式,并在必要时包装代码。Prettier 是一个离大多数开发者最近的一个库,在 Github 上有超过 46.2k 的star、4k 的fork、代码贡献者 640+,妥妥的优质开源项目。

Prettier 3.0 如期发布:高调宣称支持 ESM!

目前官方宣称,Prettier 3.0 已将所有源代码迁移为使用 ECMAScript 模块,这一变化显著改善了 Prettier 团队的开发体验。 但是,开发者依然可以将 Prettier 库用作 CommonJS。

Prettier 3.0 的更新带来了几项重大更改,比如:

  • Markdown 中拉丁字符和中文或日文字符之间不再插入空格
  • trailingComma 的默认值已更改为“all”
  • 支持使用 ECMAScript 模块和异步解析器编写的插件
  • 许多格式改进和错误修复等等

2.Prettier 3.0 主要更改介绍

2.1 改进中文、日文和韩文的空白处理

以前,Prettier 会在中文或日文与西文字符(字母和数字)之间插入空格。 虽然有些人喜欢这种风格,但它并非标准,而且实际上违反了官方指导方针。 Prettier 团队认为在这种情况下强制执行特定样式不是 Prettier 的工作,因此从 Prettier 3.0 开始不再插入空格,而保留现有的空格。

如果开发者需要一个工具来强制执行间距样式,可以考虑 textlint-ja 或 lint-md (规则 space-round-alphabet 和 space-round-number)。

这一变化的棘手部分是中文或日文与西方字符之间的模糊换行。 当 Prettier 展开文本时,它需要决定是简单地删除这样的换行符还是用空格替换。 为此,Prettier 检查周围的文本并推断出首选的样式。

<!-- Input -->
漢字
Alphabetsひらがな12345カタカナ67890

漢字 Alphabets ひらがな 12345 カタカナ 67890

<!-- Prettier 2.8 -->
漢字 Alphabets ひらがな 12345 カタカナ 67890

漢字 Alphabets ひらがな 12345 カタカナ 67890

<!-- Prettier 3.0 -->
漢字Alphabetsひらがな12345カタカナ67890

漢字 Alphabets ひらがな 12345 カタカナ 67890           

2.2 支持带有异步解析器的插件

Prettier 3.0 插件中的 parse 函数现在可以返回 Promise。

为了支持嵌入式语言的异步解析器,Prettier 必须对插件 API 进行重大更改。 也就是说,打印机的 embed 方法现在必须匹配全新的签名,而与以前的版本不兼容。 如果插件开发者并未定义 embed,则无需担心。

另外,打印机的 preprocess 方法现在可以返回一个 Promise。

2.3 支持 ESM 中的配置文件

支持 ESM 中的配置文件,支持的配置文件名如下:

  • prettier.config.js(与 package.json 中的 {"type": "module"} 一起使用)
  • .prettierrc.js(同上)
  • prettier.config.mjs
  • .prettierrc.mjs.
export default {
  trailingComma: "es5",
  tabWidth: 4,
  semi: false,
  singleQuote: true,
};           

共享 Prettier 配置很简单,开发者只需发布一个导出配置对象的模块(例如 @company/prettier-config),并在 package.json 中引用它即可,而且目前共享配置也已经支持 ESM:

{
  "name": "my-cool-library",
  "version": "9000.0.1",
  "prettier": "@company/prettier-config"
}           

如果不想使用 package.json,则可以使用任何受支持的扩展来导出字符串,例如.prettierrc.json:

"@company/prettier-config";           

2.4 将 TrailingComma 的默认值更改为 all

从 2.0 版本开始,Prettier 将 TrailingComma 的默认值更改为 es5。

Internet Explorer 是最后一个不允许在函数调用中使用尾随逗号的浏览器,已于 2022 年 6 月 15 日不再受支持。因此,可以将 TrailingComma 的默认值更改为 all。

如果仍首选旧行为,请使用 下面配置 Prettier。

{ "trailingComma": "es5" }           

2.5 从 babel 解析器中删除 Flow 语法支持

由于历史原因,当解析器选项设置为 babel 时,Prettier 过去常常识别 JS 文件中的 Flow 语法,即使该文件不包含 @flow pragma。 这种支持是有限的并且对性能不利,因此在 Prettier 3.0 中已被删除。

如果使用 babel 解析器的 Prettier 找到 @flow pragma 或文件具有 .js.flow 扩展名,它仍然会自动切换到 Flow 语法。

2.5 删除对 Flow 评论的支持

作为一种预处理器,Flow comments 又名注释类型在 token 级别上进行处理,并且在一般情况下不能在 AST 中表示。 Flow 构建 AST 时就好像这些特殊注释标记不存在一样。 例子:

/*:: if */ x + y;           

这被解析为 if (x) +y,支持 Flow 则解析为 x + y; 如果不支持 Flow 则由 JS 解析器执行。

此前,对于某些特殊情况,Prettier 尝试检测是否使用了此语法并保留它。 为了解决无法解决的问题,这种有限的支持很脆弱并且充满了错误,因此已被删除。 现在,如果解析器选项设置为 flow 或 babel-flow,Flow 注释将像普通代码一样被解析和重新打印。 如果使用不支持 Flow 的解析器,它们将被视为普通注释。

// Input
let a /*: foo */ = b;
// Prettier 2.8
let a /*: foo */ = b;
// Prettier 3.0 with --parser flow
let a: foo = b;
// Prettier 3.0 with --parser babel
let a /*: foo */ = b;           

2.7 当 --trailing-comma=es5 时打印类型参数和元组类型中的尾随逗号

// Input
type Foo = [
  {
    from: string,
    to: string,
  } // <- 1
];
type Foo = Promise<
  | { ok: true, bar: string, baz: SomeOtherLongType }
  | { ok: false, bar: SomeOtherLongType } // <- 2
>;

// Prettier 2.8
type Foo = [
  {
    from: string,
    to: string,
  } // <- 1
];
type Foo = Promise<
  | { ok: true, bar: string, baz: SomeOtherLongType }
  | { ok: false, bar: SomeOtherLongType } // <- 2
>;

// Prettier 3.0
type Foo = [
  {
    from: string,
    to: string,
  } // <- 1
];
type Foo = Promise<
  | { ok: true, bar: string, baz: SomeOtherLongType }
  | { ok: false, bar: SomeOtherLongType } // <- 2
>;           

2.8 添加纯 css 解析器

以前,当传递 --parser=css 时,Prettier 尝试使用 postcss-scss 和 postcss-less 解析内容。 这导致了混乱,并且使得语法错误难以发现,现在 --parser=css 仅适用于普通 CSS 语法。

如果开发者对 .less/.scss 文件使用 parser="css",请将其更新为正确的解析器或删除解析器选项,以便让 Prettier 通过文件扩展名自动检测解析器。

/* Input */
/* Less Syntax with `--parser=css` */
a {.bordered();}

/* Prettier 2.8 */
/* Less Syntax with `--parser=css` */
a {
  .bordered();
}

/* Prettier 3.0 */
SyntaxError: (postcss) CssSyntaxError Unknown word (2:4)
  1 | /* Less Syntax with `--parser=css` */
> 2 | a {.bordered();}           
/* Input */
/* Scss Syntax with `--parser=css` */
::before {content: #{$foo}}

/* Prettier 2.8 */
/* Scss Syntax with `--parser=css` */
::before {
  content: #{$foo};
}

/* Prettier 3.0 */
SyntaxError: (postcss) CssSyntaxError Unknown word (2:22)
  1 | /* Scss Syntax with `--parser=css` */
> 2 | ::before {content: #{$foo}}           

2.9 删除对“逗号分隔接口”语法的支持

//Input
type Type1 implements A, B {a: a}

//Prettier 2.8
type Type1 implements A, B {
  a: a
}

//Prettier 3.0
SyntaxError: Syntax Error: Unexpected Name "B". (1:26)
> 1 | type Type1 implements A, B {a: a}           

2.10 其他更新

除了以上的核心变更外,Prettier 3.0还带来了以下更新,比如:

  • 放弃对 Node.js 10 和 12 的支持
  • 将大量公共 API 更改为异步,比如:format、formatWithCursor、formatAST、check、getSupportInfo、clearConfigCache,移除 prettier.resolveConfig.sync、prettier.resolveConfigFile.sync、prettier.getFileInfo.sync 等等支持
  • Npm 包文件结构已更改
  • 更新 prettier.doc

其他更多更新可以查看文末资料,本文不再过多展开。

3.本文总结

本文主要和大家探索 Prettier 3.0 版本的发布,一起聊聊在该版本带来的核心更新。

因为篇幅有限,关于 Prettier 3.0 的用法和特性文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏,您的支持是我不断创作的动力。

参考资料

https://prettier.io/docs/en/configuration.html#sharing-configurations

https://prettier.io/blog/2023/07/05/3.0.0.html#javascript

https://www.reddit.com/r/javascript/comments/7xqvae/using_prettier_to_format_your_javascript_code/

https://github.com/prettier/prettier

https://unifiedjs.com/

继续阅读