JavaScript 的标准化速度在过去几年明显加快。TC39(ECMA-262 技术委员会)现在每年发布一个新版本的 ECMAScript 规范,每年都有新的语法提案进入各个阶段。
对于 Prettier 来说,这意味着它的解析器需要持续跟进新的语法特性。一个处于 Stage 3 或 Stage 4 的提案,可能已经被很多开发者通过 Babel 或 TypeScript 使用了,如果 Prettier 的解析器还不认识这个语法,就会报解析错误,导致使用该语法的文件无法被格式化。
Prettier 依赖外部解析器(主要是 @babel/parser 和 typescript-estree),解析器的更新进度决定了 Prettier 支持新语法的速度。这个链条是:
ECMAScript 新提案 → Babel/TypeScript 支持新语法 → Prettier 更新解析器依赖 → Prettier 能格式化新语法
每一环都有延迟。Babel 通常在提案进入 Stage 3 后不久就提供支持,但 Babel 的更新到 Prettier 的适配之间可能还有数周到数月的延迟。TypeScript 对提案的支持更早(TypeScript 经常在自己的编译器中实验性地实现提案),但 typescript-estree(TypeScript 解析器的独立包)的更新同步也需要时间。
这意味着:当你使用某个最新的语法提案时,Prettier 可能暂时不支持格式化包含该语法的文件。
装饰器(Decorators)。这是经历时间最长的提案之一。TC39 最终在 2024 年标准化了装饰器,但在此之前,社区存在多个装饰器提案的变体(Stage 1 的旧装饰器、Stage 3 的新装饰器)。Prettier 在很长一段时间内对不同变体的支持不够完整,使用装饰器的 TypeScript 项目经常遇到 Prettier 解析失败。
Pipeline 操作符(|>)。这个提案的语法在 TC39 中经历了多次修改——从 {|x| f(x)} 到 x |> f(_) 再到最新的 x |> f(%)。每次语法变更都要求解析器和 Prettier 适配。
Record 和 Tuple。#{x: 1} 和 #[1, 2, 3] 语法是增加不可变数据结构的提案。这些新字面量语法需要解析器特别支持。
Pattern Matching。更复杂的模式匹配语法仍在早期阶段,但 TypeScript 已经在试验性地实现。Prettier 对这类复杂新语法的支持通常是最慢的。
当遇到 Prettier 不支持的语法时,有几个应对方法:
升级 Prettier 版本。最直接的解决方式。Prettier 的维护者会尽快跟进新语法支持,及时升级到最新版本通常能解决大部分兼容性问题。
npm update prettier
使用 .prettierignore 临时排除。如果升级不可行(比如版本锁定在旧版本),把使用新语法的文件临时加入 .prettierignore。
# .prettierignore # 这些文件使用了 Prettier 暂不支持的 Stage 3 语法 src/decorators/
在编辑器中选择性格式化。VS Code 的 Prettier 扩展在遇到解析失败时会静默跳过(不会报错,也不会格式化)。这意味着你可以继续在其他文件上使用保存时格式化,只是包含新语法的文件不会被处理。
TypeScript 的版本更新频率很高(每 4-6 周一个小版本),而且经常引入实验性的语法特性。这些特性可能在正式的 ECMAScript 提案之外独立存在(比如 const enum、namespace、satisfies 操作符等 TypeScript 特有的语法)。
Prettier 通过 typescript-estree 解析器来支持 TypeScript。当 TypeScript 引入新语法时,typescript-estree 需要同步更新。如果 Prettier 依赖的 typescript-estree 版本落后,就会出现 TypeScript 编译通过但 Prettier 解析失败的情况。
一个实际的建议:在升级 TypeScript 版本后,检查 Prettier 是否还能正常工作。如果出现解析失败,可能需要等待 Prettier 的依赖更新,或者暂时把相关文件加入 .prettierignore。
CSS 的规范演进也在加速。CSS Nesting(嵌套语法)、:has() 选择器、@layer 规则、Container Queries 等新特性需要 PostCSS 解析器(Prettier 使用的 CSS 解析器)跟进支持。PostCSS 的更新通常比较快,因为它是一个活跃的开源项目,而且 CSS 的新特性通常可以通过 PostCSS 插件提前使用。
HTML、JSON、YAML 这类比较稳定的语言不存在跟进问题——它们的语法变化非常缓慢,Prettier 的解析器几乎不需要更新。
社区插件在跟进新语法方面通常比核心更慢。如果你使用 Prettier 的 PHP 或 Ruby 插件,这些语言的新特性支持取决于插件维护者的更新速度。部分插件可能因为维护者精力有限而滞后。
选型建议:如果你的项目严重依赖某个新语言特性,在选择 Prettier 时先验证该特性是否已被支持。如果尚未支持,评估等待更新的可行性或寻找替代方案。
Prettier 在 JavaScript/TypeScript 生态中的语法跟进速度是可接受的——通常在新特性进入 Stage 3 后的 1-3 个月内就能支持。但如果你的团队是"新语法尝鲜者",可能会经常遇到这种暂时的不支持。这不是 Prettier 的设计缺陷,而是任何需要精确解析语法的工具必然面临的挑战。