5月28日 07:28

Prettier 与其他代码格式化工具有什么区别?如何选择?

Prettier 和 ESLint 有什么本质区别?

Prettier 是代码格式化工具,ESLint 是代码质量检查工具,二者不是替代关系而是互补关系。

核心区别在于工作原理:Prettier 将代码解析为 AST(抽象语法树),然后按照自己的规则重新输出,保证同样的输入永远得到同样的输出;ESLint 则基于规则引擎逐行扫描代码,检测潜在的错误和反模式。

实际项目中标准做法是两者结合:用 eslint-config-prettier 关闭 ESLint 中与格式化重叠的规则,让 Prettier 完全负责格式化(缩进、换行、引号风格),ESLint 专注代码质量(未使用变量、潜在 bug、最佳实践)。

json
// .eslintrc.json { "extends": ["eslint:recommended", "prettier"], "plugins": ["prettier"] }

Prettier 相比 Beautify、Standard.js 的优势在哪?

vs Beautify: Beautify 基于正则匹配做格式化,不具备 AST 解析能力,对复杂语法结构(如嵌套的三元表达式、链式调用)的格式化效果差,且输出不确定——同一份代码多次格式化可能产生不同结果。Prettier 基于 AST 重新打印代码,输出完全确定性,这是团队协作的基础。

vs Standard.js: Standard.js 是"零配置"的代名词,但它不允许任何自定义——分号必须有或必须没有,没有中间地带。Prettier 同样开箱即用,但保留了少量关键配置(单引号/双引号、分号、行宽等),适合需要一定灵活性的团队。

维度PrettierBeautifyStandard.js
解析方式AST正则AST
输出确定性完全确定不确定完全确定
可配置性少量关键选项丰富几乎为零
多语言支持JS/TS/CSS/HTML/JSON/MDJS/CSS/HTMLJS/TS

Biome 等新一代工具会取代 Prettier 吗?

2026 年 Biome 成为最值得关注的替代方案。它用 Rust 编写,将格式化和 lint 合并为一个工具,在大型 monorepo 中性能优势显著:10,000+ 文件的项目,格式化+检查不到 200ms,而 ESLint+Prettier 组合需要近 12 秒。

但 Prettier 短期内不会被取代,原因有三:

  1. 生态成熟度: Prettier 拥有大量编辑器插件、预提交钩子、CI 集成方案,Biome 生态仍在追赶
  2. 插件体系: Prettier 支持插件格式化额外语言(如 Java、Ruby、PHP),Biome 目前语言覆盖有限
  3. 迁移成本: 已有项目的 .prettierrc 配置和格式化基线,切换工具意味着大量 diff

选择建议: 新项目可以尝试 Biome,享受性能提升和简化配置;已有项目不必急于迁移,等 Biome 生态更成熟再说。

Prettier 的 AST 重打印机制是什么意思?

这是理解 Prettier 行为的关键。Prettier 的工作流程:

  1. 解析(Parse): 将源代码解析为 AST
  2. 遍历(Traverse): 遍历 AST 节点
  3. 打印(Print): 根据行宽限制和自身规则重新输出代码

这意味着 Prettier 不是"调整"你的代码,而是"重新生成"你的代码。你写的空行、多余括号、手动对齐——大部分都会被丢弃重写。

这也是为什么 Prettier 配置选项少:它不是逐条规则控制,而是整体重打印,只暴露行宽、缩进等顶层参数。这种设计牺牲了灵活性,换来了确定性。

实际项目中怎么配置 Prettier + ESLint?

完整的工程化配置分三步:

第一步:安装依赖

bash
npm install -D prettier eslint eslint-config-prettier eslint-plugin-prettier

第二步:配置文件

json
// .prettierrc { "semi": true, "singleQuote": true, "printWidth": 80, "trailingComma": "es5" }
json
// .eslintrc.json { "extends": ["eslint:recommended", "plugin:prettier/recommended"], "env": { "es2024": true, "node": true } }

plugin:prettier/recommended 做了三件事:加载 eslint-plugin-prettier(把 Prettier 规则作为 ESLint 规则运行)、加载 eslint-config-prettier(关闭 ESLint 格式化相关规则)、设置 prettier/prettier 为 error 级别。

第三步:编辑器集成

json
// .vscode/settings.json { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" } }

保存时先 Prettier 格式化,再 ESLint 自动修复,分工明确不冲突。

第四步:Git 钩子自动化

bash
npm install -D husky lint-staged npx husky init echo "npx lint-staged" > .husky/pre-commit
json
// package.json { "lint-staged": { "*.{js,ts}": ["eslint --fix", "prettier --write"], "*.{css,html,json,md}": ["prettier --write"] } }

提交时自动格式化和检查,不合格的代码进不了仓库。

Prettier 有哪些已知局限?

配置不够灵活: 行宽以内无法手动换行,printWidth: 80 时超过 80 字符的链式调用会被强制换行,即使你手动排列得更易读。这是"确定性"的代价——不允许个人偏好覆盖工具判断。

大项目性能瓶颈: Prettier 是单线程的,超大型项目全量格式化耗时较长。应对方式是用 lint-staged 只格式化变更文件,或引入缓存。

版本升级可能产生 diff: Prettier 的格式化结果在不同大版本间可能有差异,团队必须锁定版本号,升级时全量格式化会产生大量无意义 diff。

面试追问:什么时候不该用 Prettier?

三种场景下 Prettier 不是最佳选择:

  1. 遗留大型项目: 全量格式化会产生数千行 diff,干扰 code review,建议渐进式引入(只格式化新文件或变更文件)
  2. 需要精细控制格式的场景: 如代码生成器输出、教学材料中特意安排的缩进,Prettier 的重打印会破坏这些刻意格式
  3. 纯 Python 项目: Python 有 Black,设计理念与 Prettier 一致但针对 Python 语法优化,混用 Prettier 反而增加复杂度
标签:Prettier