Prettier logo

Prettier

Prettier 是一个"有态度的"(opinionated)代码格式化工具,通过解析代码并以统一的规则重新打印,确保所有输出代码风格一致,消除团队中关于代码风格的争论。

精选工具代码质量格式化代码风格多语言支持

Prettier 是"有态度的"代码格式化工具,通过解析代码并以统一规则重新打印,确保所有输出代码风格一致,消除团队中关于代码风格的争论,npm 周下载量超 4000 万。

Prettier

Prettier 是一个"有态度的"(opinionated)代码格式化工具,通过解析代码并以统一的规则重新打印,确保所有输出代码风格一致,消除团队中关于代码风格的争论。


技术简介说明

Prettier 由 James Long 于 2017 年创建,其核心灵感来源于 Philip Wadler 1998 年的论文 "A prettier printer"——一种基于文档中间表示(Doc IR)的美观打印算法。Prettier 的核心理念是强制一致性:它移除代码中的所有原始格式,按照自身规则重新排版,让开发者无需关心代码风格,专注于业务逻辑。

Prettier 的"有态度"设计是其最大的差异化特征。与其他格式化工具提供大量可配置选项不同,Prettier 刻意保持极少配置项,几乎所有格式化决策都是固定的。这种设计哲学消除了团队中关于代码风格的讨论——你不需要决定是用单引号还是双引号、缩进 2 格还是 4 格、是否使用分号,Prettier 替你做好了决定。

截至 2026 年 7 月,Prettier 已发展至 v3.9.x 版本,GitHub 上拥有 91,000+ Stars800+ 贡献者,被 1000 万+ 仓库依赖,npm 周下载量超过 4000 万次。它是 JavaScript/TypeScript 生态中使用最广泛的代码格式化工具,也是前端工程化基础设施中不可或缺的一环。2025 年 State of JS 调查中,Prettier 满意度排名始终位居前列。


基本信息

属性
项目名称Prettier(prettier/prettier)
当前最新稳定版v3.9.4(2026 年 7 月)
开发语言JavaScript(核心)
开源协议MIT
首次发布2017 年 1 月
包管理器npm(prettier
官方网站prettier.io
GitHubgithub.com/prettier/prettier
npm 周下载量4000 万+
GitHub Stars91,000+
贡献者800+
依赖仓库数10,000,000+(GitHub)
支持语言JavaScript、TypeScript、JSX、CSS、SCSS、Less、HTML、Vue、Angular、JSON、JSONC、GraphQL、Markdown、YAML、Handlebars 等
配置文件.prettierrc.prettierrc.ts(3.5+)、prettier.config.jsprettier.config.mjspackage.json 中的 "prettier" 字段
编辑器支持VS Code、JetBrains(IntelliJ/WebStorm 等)、Vim/Neovim、Emacs、Sublime Text、Atom 等

快速上手

安装

通过 npm 安装(推荐作为项目开发依赖):

# 使用 pnpm(项目推荐)
pnpm add -D --save-exact prettier
 
# 使用 npm
npm install --save-dev --save-exact prettier
 
# 使用 yarn
yarn add -D --exact prettier

注意:推荐使用 --save-exact 锁定精确版本,避免不同版本间格式化结果的差异。

全局安装(用于快速试用):

npm install -g prettier

基础配置

方式一:.prettierrc 文件(推荐)

在项目根目录创建 .prettierrc(或 .prettierrc.json.prettierrc.yml):

{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 100
}

方式二:TypeScript 配置文件(3.5+ 新增)

从 3.5 版本开始,Prettier 支持使用 TypeScript 编写配置文件:

// .prettierrc.ts
import type { Config } from 'prettier'
 
const config: Config = {
  semi: false,
  singleQuote: true,
  tabWidth: 2,
  trailingComma: 'all',
  printWidth: 100,
}
 
export default config

方式三:JavaScript/ESM 配置文件

创建 prettier.config.mjs(推荐,Prettier 3.x 默认使用 ESM):

/** @type {import("prettier").Config} */
export default {
  semi: false,
  singleQuote: true,
  tabWidth: 2,
  trailingComma: 'all',
  printWidth: 100,
}

方式四:package.json 中的 "prettier" 字段

{
  "prettier": {
    "semi": false,
    "singleQuote": true,
    "tabWidth": 2
  }
}

.prettierignore 文件

.gitignore 语法相同,用于忽略不需要格式化的文件:

# 忽略构建产物
dist/
build/
.next/
node_modules/

# 忽略生成的文件
coverage/
*.min.js
*.min.css

最小示例

# 格式化单个文件并输出到终端
npx prettier --write src/index.ts
 
# 格式化整个项目(排除 ignore 中的文件)
npx prettier --write .
 
# 仅检查格式是否正确(不修改文件,CI 中常用)
npx prettier --check .

package.json 中添加脚本:

{
  "scripts": {
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  }
}

运行:

pnpm format        # 格式化所有文件
pnpm format:check  # 检查格式(不修改文件)

格式化效果示例:

// 格式化前
const obj = {foo: "bar", baz: 42, qux: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]};
function greet(name:string,age:number){console.log(`Hello ${name}, you are ${age} years old.`);}
 
// 格式化后(printWidth: 80)
const obj = {
  foo: 'bar',
  baz: 42,
  qux: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
}
 
function greet(name: string, age: number) {
  console.log(`Hello ${name}, you are ${age} years old.`)
}

核心概念与架构

处理管道(Pipeline)

Prettier 采用经典的编译器管道架构,将代码格式化分解为一系列独立阶段:

源代码 (Source Code)
      │
      ▼
┌─────────────┐
│   Parser    │  ← 使用现成的第三方解析器(Babel、TypeScript、PostCSS 等)
│  (解析器)  │     将源代码转换为 AST,丢弃所有空白和格式信息
└──────┬──────┘
       │
       ▼
┌─────────────────┐
│ Comment Attach  │  ← 将注释通过位置启发式算法重新关联到 AST 节点
│  (注释附着)    │     这是 Prettier 中最复杂的阶段之一
└──────┬──────────┘
       │
       ▼
┌─────────────┐
│   Printer   │  ← 递归遍历 AST,将每个节点转换为 Doc IR
│  (打印机)  │     每种语言有自己的 Printer 实现
└──────┬──────┘
       │
       ▼
┌─────────────────┐
│  Doc (IR)       │  ← 基于 Wadler/Lindig 算法的中间表示
│  (文档 IR)     │     由 group、indent、line 等指令组成
└──────┬──────────┘
       │
       ▼
┌─────────────────┐
│ Layout Engine   │  ← 将 Doc IR 渲染为最终字符串
│  (布局引擎)    │     根据 printWidth 决定是否换行
└──────┬──────────┘
       │
       ▼
格式化后的代码 (Formatted Code)

关键组件

1. Parser(解析器)

Prettier 不自带解析器,而是使用各语言的成熟解析器:

语言使用的解析器
JavaScript / JSXBabel、Acorn、Meriyah、Espree
TypeScript / TSX@typescript-eslint/typescript-estree
CSS / SCSS / LessPostCSS(postcss-scss、postcss-less)
HTML / Vue / Angular@angular/compiler、htmlparser2
JSON / JSONC内置解析器
Markdownmicromark v4(3.9 从 remark-parse v8 升级)
YAMLyaml v2(3.9 从 v1 升级)
GraphQLgraphql(3.9 升级支持 GraphQL.js v17 新语法)
FlowBabel / @prettier/plugin-hermes(3.6+ Rust 解析器)
HandlebarsGlimmer

每个解析器通过 Plugin API 接入,产生带有位置信息的 AST。

2. Comment Attachment(注释附着)

由于 AST 不保留空白和注释位置,Prettier 需要一个复杂的启发式算法将注释重新关联到正确的 AST 节点上。解析器需要提供 locStart / locEnd 位置函数,Prettier 遍历 AST 将每个注释绑定到最近的"包围"或"前/后"节点。这是 Prettier 中 bug 最多的领域之一。

3. Printer(打印机)

Printer 递归遍历带注释的 AST,为每个节点生成 Doc IR——一个声明式的布局描述。每种语言有自己的 Printer,但最终都产生相同的 Doc 中间表示。

4. Doc IR(中间表示)

Doc 基于 Philip Wadler 的 "A prettier printer" 论文,由以下核心指令组成:

指令含义
string要输出的字面文本
indent(doc)对包含的 doc 增加缩进
group(doc)尝试将内容放在一行;如果超出 printWidth,则断开所有内部换行
line当 group 为 flat 时变成空格,否则换行
softline类似 line,但 flat 时不产生任何内容
hardline始终换行
fill(docs[])尽可能多地将项目放入每行
ifBreak(brokenDoc, flatDoc)如果 group 断开则输出 brokenDoc,否则输出 flatDoc
lineSuffix(doc)延迟输出到当前行末尾(用于行尾注释)

group 是核心:Prettier 贪心地决定每个 group 是否能放入配置的 printWidth(默认 80 列)。如果能放下,所有内容渲染为一行;如果不能,group 内的所有内容都换到新行。这产生了 Prettier 特有的"要么全部在一行,要么全部展开"的行为。

5. Layout Engine(布局引擎)

最终阶段遍历 Doc 树,维护光标位置和缩进级别,评估每个 group 的 flat/broken 状态,输出最终的格式化字符串。

配置选项体系

Prettier 有意保持配置精简,核心选项包括:

选项默认值说明
printWidth80每行最大字符宽度(软限制)
tabWidth2缩进空格数
useTabsfalse使用 Tab 缩进
semitrue语句末尾加分号
singleQuotefalse使用单引号
trailingCommaall尾逗号策略(all/es5/none
bracketSpacingtrue对象字面量大括号内加空格
bracketSameLinefalseHTML/JSX 闭合括号不换行
arrowParensalways箭头函数参数是否加括号
endOfLinelf换行符风格
quotePropsas-needed对象属性引号策略
objectWrappreserve对象换行策略(3.5 新增,collapse/preserve
experimentalOperatorPositionend操作符位置(3.5 新增,start/end
proseWrappreserveMarkdown 文本换行策略
htmlWhitespaceSensitivitycssHTML 空白敏感策略

插件架构

Prettier 自身的内置语言支持也是通过 Plugin API 实现的。插件由三部分组成:

const myPlugin = {
  // 语言声明
  languages: [
    { name: 'MyLang', parsers: ['mylang'], extensions: ['.ml'] }
  ],
  // 解析器
  parsers: {
    mylang: {
      parse: (text) => myParser(text),  // 返回 AST
      astFormat: 'mylang-ast',          // 标识使用哪个 Printer
      locStart: (node) => node.start,
      locEnd: (node) => node.end,
    },
  },
  // 打印机
  printers: {
    'mylang-ast': {
      print(path, options, print) { ... }  // AST → Doc IR
    },
  },
}

Parser 和 Printer 通过 astFormat 字符串连接——解析器声明其 AST 格式,打印机注册处理该格式。

3.7 版本起,插件 API 新增了多项增强:

  • plugin.parser.preprocess() 可返回 Promise(异步预处理)
  • AstPath#call() 可安全访问空值属性
  • canAttachComment() 接收祖先节点参数
  • 新增 printPrettierIgnored() 自定义忽略节点打印
  • 允许插件仅提供 estree printer

核心特性

1. 强制一致的代码风格

Prettier 的核心价值是消除代码风格争论。它采用"有态度"的设计,绝大多数格式化决策不可配置——缩进 2 格、不使用分号(可选)、单引号(可选)、尾逗号等都有默认值。团队无需讨论风格问题,Prettier 替你决定。

2. 广泛的语言支持

原生支持 15+ 种语言/格式,无需额外插件:

  • JavaScript / TypeScript / JSX / TSX
  • CSS / SCSS / Less
  • HTML / Vue / Angular
  • JSON / JSONC
  • GraphQL(3.9 起支持 GraphQL.js v17 新语法,含 fragment arguments)
  • Markdown(3.9 起支持 setext headings、改进 CJK 文本换行)
  • YAML(3.9 起升级 yaml v2,修复大量长期问题)
  • Handlebars(3.7 起支持 Front Matter)
  • Flow(3.9 起采用基于 Rust 的新解析器,大幅提升性能)

通过插件还可支持 PHP、Ruby、Rust、Go、Java、Swift、XML、TOML 等更多语言。

3. 丰富的编辑器集成

Prettier 几乎支持所有主流编辑器:

  • VS Codeesbenp.prettier-vscode 扩展(最流行的格式化扩展)
  • JetBrains:IntelliJ IDEA / WebStorm 等原生内置支持
  • Vim / Neovim:通过 Neoformat、ALE、coc-prettier 等
  • Sublime TextAtomEmacs
  • 通过 LSP 协议提供通用编辑器支持

4. 插件系统

开放的 Plugin API 允许社区扩展 Prettier 支持任意语言或自定义格式化规则。Prettier 自身的内置语言实现也基于此 API。常见社区插件包括:

  • prettier-plugin-tailwindcss:Tailwind CSS 类名自动排序(7000+ Stars)
  • prettier-plugin-organize-imports:Import 语句自动排序
  • prettier-plugin-embed:格式化嵌入在模板字符串中的 CSS、SQL、GraphQL 等代码
  • @prettier/plugin-php:PHP 格式化
  • @prettier/plugin-ruby:Ruby 格式化
  • @prettier/plugin-xml:XML 格式化
  • prettier-plugin-java:Java 格式化
  • @prettier/plugin-toml:TOML 格式化

5. 实验性快速 CLI(3.6+)

从 3.6 版本开始,Prettier 引入了实验性高性能 CLI,通过 --experimental-cli 标志或 PRETTIER_EXPERIMENTAL_CLI=1 环境变量启用。在大型项目中,格式化速度提升 10-14 倍(用户反馈从 1 分 10 秒降至 5 秒)。这个快速 CLI 将成为 Prettier 4.0 的默认 CLI。

6. 可编程 API

Prettier 暴露完整的 Node.js API,支持编程式调用:

import * as prettier from 'prettier'
 
// 格式化代码
const formatted = await prettier.format(code, {
  parser: 'typescript',
  semi: false,
  singleQuote: true,
})
 
// 检查代码是否已格式化
const isFormatted = await prettier.check(code, { parser: 'typescript' })
 
// 获取配置
const config = await prettier.resolveConfig(filePath)
 
// 获取支持的解析器列表
const supportInfo = await prettier.getSupportInfo()

7. 区域格式化

Prettier 支持仅格式化文件中的特定区域,通过 rangeStartrangeEnd 选项控制:

const formatted = await prettier.format(code, {
  parser: 'typescript',
  rangeStart: 100,
  rangeEnd: 500,
})

8. Pragma 注释控制

支持通过文件头注释控制是否格式化:

// @prettier       ← 仅当文件包含此注释时才格式化(requirePragma: true)
// @no-prettier    ← 跳过此文件的格式化
// prettier-ignore ← 跳过紧随其后的代码块格式化

9. 内嵌语言格式化

embeddedLanguageFormatting 设为 auto(默认值)时,Prettier 会自动格式化字符串中的嵌入代码,例如:

  • JavaScript 中的 tagged template literals(如 css\...`html`...``)
  • Markdown 中的代码块
  • HTML 中的 <style><script> 内容

10. 高度确定性与幂等性保证

相同输入在相同配置下始终产生相同输出。Prettier 的格式化是确定性的,不依赖时间、环境或其他外部因素。更重要的是,Prettier 保证幂等性——对同一段代码多次运行 Prettier,第二次不会产生任何变化。这确保了格式化结果的稳定性和可预测性。


生态图

┌─────────────────────────────────────────────────────────────────┐
│                      Prettier 生态系统                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌────────────────────┐    │
│  │  prettier    │  │ prettier CLI │  │  prettier API      │    │
│  │  Core Engine │  │  命令行工具   │  │  可编程 Node.js    │    │
│  └──────┬───────┘  └──────┬───────┘  └──────────┬─────────┘    │
│         │                 │                      │              │
│  ┌──────┴─────────────────┴──────────────────────┴───────────┐  │
│  │              Plugin API(插件系统)                         │  │
│  │  ┌───────────┐ ┌────────────┐ ┌──────────────────────┐   │  │
│  │  │内置语言    │ │社区语言插件 │ │ 自定义格式化插件      │   │  │
│  │  │JS/TS/CSS  │ │PHP/Ruby/Go │ │ tailwindcss 排序等   │   │  │
│  │  │HTML/JSON  │ │Java/Swift  │ │ organize-imports     │   │  │
│  │  │MD/YAML/GQL│ │Rust/TOML   │ │ prettier-plugin-embed│   │  │
│  │  └───────────┘ └────────────┘ └──────────────────────┘   │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                 │
│  ┌──────────────────── 编辑器集成 ────────────────────────────┐  │
│  │  VS Code 扩展  │ JetBrains 插件  │ Vim/Neovim │ Emacs    │  │
│  └────────────────────────────────────────────────────────────┘  │
│                                                                 │
│  ┌──────────────────── ESLint 桥接 ──────────────────────────┐  │
│  │  eslint-config-prettier │ eslint-plugin-prettier          │  │
│  │  (关闭 ESLint 格式规则)  │ (将 Prettier 作为 ESLint 规则)│  │
│  └────────────────────────────────────────────────────────────┘  │
│                                                                 │
│  ┌──────────────────── 性能层(3.6+ 新增)───────────────────┐  │
│  │  @prettier/plugin-oxc  │ @prettier/plugin-hermes         │  │
│  │  (Rust OXC 解析器)     │ (Rust Hermes Flow 解析器)      │  │
│  │  实验性快速 CLI          │                                │  │
│  └────────────────────────────────────────────────────────────┘  │
│                                                                 │
│  ┌──────────────────── CI/CD 集成 ───────────────────────────┐  │
│  │  GitHub Actions │ GitLab CI │ 预提交钩子 (Husky/lint-staged) │  │
│  └────────────────────────────────────────────────────────────┘  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

关键生态项目

项目说明
prettier核心 npm 包(周下载 4000 万+)
eslint-config-prettier关闭与 Prettier 冲突的 ESLint 规则(周下载 3000 万+)
eslint-plugin-prettier将 Prettier 作为 ESLint 规则运行
prettier-plugin-tailwindcssTailwind CSS 类名自动排序(7000+ Stars)
prettier-plugin-organize-importsImport 语句自动排序整理
prettier-plugin-embed格式化嵌入在模板字符串中的多语言代码
@prettier/plugin-phpPHP 格式化支持
@prettier/plugin-rubyRuby 格式化支持
@prettier/plugin-xmlXML 格式化支持
@prettier/plugin-oxc基于 Rust OXC 的高性能 JS/TS 解析器(3.6 新增)
@prettier/plugin-hermes基于 Rust Hermes 的 Flow 解析器(3.6 新增,4.0 将替代 Babel)
prettier-vscodeVS Code 官方扩展(esbenp.prettier-vscode
pretty-quick仅格式化 Git 变更文件的工具
prettier-eslint-cliCLI 包装器,先 Prettier 格式化再 ESLint 检查

与 ESLint 的关系

Prettier 和 ESLint 是互补关系,不是替代关系:

  • Prettier:只负责代码格式化(空格、缩进、换行等)
  • ESLint:负责代码质量检查(未使用变量、潜在 bug、最佳实践等)

推荐的现代配置方式:

# 安装
pnpm add -D eslint prettier eslint-config-prettier
 
# 在 ESLint 配置中使用
# eslint.config.js (flat config)
import js from '@eslint/js'
import prettierConfig from 'eslint-config-prettier'
 
export default [
  js.configs.recommended,
  prettierConfig,  // 必须放在最后,关闭所有与 Prettier 冲突的规则
]

适用场景

1. 团队协作开发

多人协作项目中最常见的痛点是代码风格不统一。Prettier 通过强制一致的格式化,彻底消除"用 Tab 还是空格"、"用单引号还是双引号"等争论,让团队将精力集中在业务逻辑和代码质量上。

2. 开源项目维护

开源项目贡献者来自不同背景,代码风格各异。配置 Prettier 后,所有 PR 的代码格式自动统一,维护者无需在 review 中指出格式问题。

3. Monorepo 多包管理

在 pnpm + Turborepo 等 Monorepo 架构中,通过根目录统一的 Prettier 配置,确保所有包的代码风格一致。配合 lint-staged 可实现按需格式化,只处理变更文件。

// 根目录 .prettierrc,通过 overrides 为不同子包定制
{
  "semi": false,
  "singleQuote": true,
  "overrides": [
    {
      "files": "packages/api/**/*",
      "options": { "printWidth": 120 }
    }
  ]
}

4. CI/CD 质量门禁

在 CI 流水线中使用 prettier --check 作为格式检查门禁,确保所有合入主分支的代码都符合格式规范:

# GitHub Actions 示例
- name: Check formatting
  run: npx prettier --check .

5. 多语言混合项目

Prettier 原生支持 JS/TS/CSS/HTML/JSON/Markdown/YAML 等多种语言,一个工具覆盖项目中所有文件格式化需求,减少工具链复杂度。

6. 遗留代码库重构

接手一个格式混乱的遗留项目时,一次 prettier --write . 即可统一所有代码风格,消除历史积累的风格债务。

7. 代码生成工具集成

在模板引擎、脚手架工具、代码生成器中,使用 Prettier API 对生成的代码进行格式化,确保输出代码符合项目规范。


开发与工程化

项目集成流程

1. 安装与配置

# 安装为开发依赖(锁定精确版本)
pnpm add -D --save-exact prettier
 
# 创建配置文件
# .prettierrc
{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 100,
  "endOfLine": "lf"
}
 
# 创建忽略文件
# .prettierignore
dist/
node_modules/
coverage/
.next/
*.min.js

2. 添加 npm scripts

{
  "scripts": {
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "format:file": "prettier --write",
    "format:cache": "prettier --write --cache ."
  }
}

3. 配置 Editor(VS Code)

.vscode/settings.json 中配置:

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.formatOnPaste": false,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  }
}

推荐添加 .vscode/extensions.json 让团队成员自动安装 Prettier 扩展:

{
  "recommendations": ["esbenp.prettier-vscode"]
}

4. 配置 Git Hooks(Husky + lint-staged)

# 安装依赖
pnpm add -D husky lint-staged
 
# 初始化 Husky
npx husky init

配置 .husky/pre-commit

npx lint-staged

配置 package.json 中的 lint-staged

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx,css,scss,html,json,md,mdx,yaml,yml}": [
      "prettier --write"
    ]
  }
}

CI/CD 集成

GitHub Actions

name: Format Check
on: [push, pull_request]
jobs:
  format:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: corepack enable
      - run: pnpm install --frozen-lockfile
      - name: Check formatting
        run: pnpm prettier --check .

GitLab CI

format-check:
  stage: lint
  image: node:22
  script:
    - corepack enable
    - pnpm install --frozen-lockfile
    - pnpm prettier --check .

编程式 API 使用

import * as prettier from 'prettier'
 
async function formatCode(code, filePath) {
  // 读取项目配置
  const config = await prettier.resolveConfig(filePath)
 
  // 推断解析器
  const options = {
    ...config,
    filepath: filePath,
  }
 
  // 格式化
  const formatted = await prettier.format(code, options)
  return formatted
}
 
// 检查单个文件
async function checkFile(code) {
  const isFormatted = await prettier.check(code, {
    parser: 'typescript',
    semi: false,
  })
  return isFormatted
}

性能与安全

性能特点

性能概况

Prettier 使用 JavaScript 编写,性能相比 Biome 等 Rust 工具较慢,但对于大多数项目仍然足够:

场景Prettier 表现
单文件格式化毫秒级,无感知
中等项目(数百文件)1-3 秒
大型项目(数千文件)5-30 秒
Monorepo(数万文件)可能超过 1 分钟
实验性快速 CLI(3.6+)上述场景快 10-14 倍

性能优化建议

  1. 使用 --cache 选项(Prettier 3.x):只格式化变更文件,显著减少 CI 时间
npx prettier --write --cache .
  1. 使用实验性快速 CLI(Prettier 3.6+):
npx prettier --experimental-cli --write .
# 或设置环境变量
PRETTIER_EXPERIMENTAL_CLI=1 npx prettier --write .
# 用户反馈:从 1 分 10 秒降至 5 秒
  1. 合理配置 .prettierignore:排除 node_modules/dist/coverage/*.min.js 等无需格式化的文件

  2. 按需格式化:使用 lint-staged 仅格式化 Git 暂存区的文件,而非全量扫描

  3. 限定格式化范围:使用 --write src/ 替代 --write .,避免扫描无关目录

  4. 使用 OXC/Hermes 解析器插件:对 TypeScript/Flow 项目可考虑基于 Rust 的解析器,大幅提升解析速度

安全注意事项

CVE-2025-54313:eslint-config-prettier 供应链攻击

严重程度:高危(但仅影响 Windows)

时间:2025 年 7 月 18-19 日

影响范围eslint-config-prettier 的 4 个恶意版本(8.10.1、9.1.1、10.1.6、10.1.7)

攻击方式

  1. 攻击者通过钓鱼攻击劫持了 npm 维护者 JounQin 的账号
  2. 发布了包含恶意 post-install 脚本的版本
  3. 在 Windows 系统上安装时执行 node-gyp.dll 恶意软件,实现远程代码执行(RCE)

关联受影响包eslint-plugin-prettiersynckit@pkgr/corenapi-* 系列

应对措施

  • 确保不运行上述 4 个受影响版本
  • 立即更新到安全版本
  • 如在 Windows 上安装了受影响版本,检查是否存在 node-gyp.dll 恶意软件
  • 启用 npm 审计和锁文件完整性检查
  • 在 CI 中启用 npm provenance 验证

通用安全建议

  1. 锁定版本:使用锁文件(pnpm-lock.yaml)确保依赖一致性
  2. 定期审计:运行 pnpm audit 检查已知漏洞
  3. 验证完整性:配置 verify-deps-before-run 确保依赖未被篡改
  4. 最小权限:Prettier 仅在开发环境使用,不进入生产构建,降低了供应链攻击的风险面
  5. 使用 --save-exact:锁定 Prettier 精确版本,避免自动升级带来的格式变化

已知性能瓶颈

  1. JavaScript 运行时开销:作为 JS 编写的大型工具,冷启动和解析成本较高
  2. 大文件处理:超大文件(>10,000 行)可能明显变慢
  3. 插件开销:每个额外插件增加解析和格式化时间
  4. 配置解析:在 Monorepo 中查找和解析嵌套配置可能较慢(3.9 已优化,4.0 将彻底解决)
  5. 解析器切换:混合格式文件(如 .vue SFC)需要多个解析器协作,开销较大

技术对比

Prettier vs ESLint

维度PrettierESLint
定位代码格式化工具代码质量检查工具(Linter)
核心功能统一代码风格(空格、缩进、换行)检测代码问题、潜在 bug、最佳实践
可配置性极少选项("有态度"设计)高度可配置(数百条规则)
自动修复总是重新排版整个文件部分规则支持 --fix
语言支持15+ 种语言主要通过插件扩展,JS/TS 为核心
配置冲突无规则冲突概念规则之间可能冲突,需手动管理
性能中等(JS 实现)中等(JS 实现,大量规则时较慢)
关系互补,非替代互补,非替代

结论:Prettier 和 ESLint 是互补工具。推荐 ESLint 负责代码质量,Prettier 负责格式化。使用 eslint-config-prettier 关闭 ESLint 中与 Prettier 冲突的格式规则。

Prettier vs Biome

维度PrettierBiome
开发语言JavaScriptRust
定位纯格式化工具格式化 + Lint 一体化工具
格式化兼容性基准(100%)约 97% 兼容
性能中等(大型项目 5-30 秒)极快(10-25× 于 ESLint + Prettier)
语言支持15+ 种(含插件更多)8 种(JS/TS/JSX/JSON/CSS/HTML/GraphQL/Vue)
插件生态非常丰富正在建设(v2.0 起)
配置复杂度低(少选项)低(单文件配置)
社区成熟度10 年历史,91k+ Stars较新(2023 年),25k+ Stars
稳定性极高,格式化规则稳定快速迭代中,行为可能变化
适用场景任何需要格式化的项目追求极致性能和工具链统一的新项目

结论

  • 现有项目继续使用 Prettier,生态成熟、兼容性最好
  • 新项目如果追求性能和工具链简化,可以考虑 Biome
  • Biome 与 Prettier 格式化输出约 97% 兼容,迁移成本可控
  • Prettier 通过实验性快速 CLI(v3.6+)和 Rust 解析器插件(OXC/Hermes)正在追赶性能差距

Prettier vs dprint

维度Prettierdprint
开发语言JavaScriptRust
定位格式化 + 少量配置纯格式化(高度可配置)
可配置性极少高度可配置(JSON 配置所有规则)
语言支持15+ 种(含插件)依赖插件(JS/TS/JSON/Markdown 等)
性能中等极快
哲学"有态度",强制一致灵活,允许团队自定义

选择建议

  • 选 Prettier:大多数前端项目,团队协作、开源项目、已有 ESLint 体系
  • 选 Biome:新项目且追求极致性能、希望减少工具链复杂度
  • 选 dprint:需要高度自定义格式规则的项目
  • 两者并用:不推荐。选择其一即可,迁移成本高且无额外收益

最佳实践

1. 保持默认配置

Prettier 的"有态度"设计意味着默认配置已经足够好。除非有强烈的团队共识,否则建议保持默认配置,避免引入不必要的配置争议。

{
  "// 推荐:只修改最必要的选项": "",
  "semi": false,
  "singleQuote": true,
  "printWidth": 100
}

2. 使用 eslint-config-prettier 而非 eslint-plugin-prettier

# ✅ 推荐:仅关闭冲突规则,ESLint 不执行格式化
pnpm add -D eslint-config-prettier
 
# ❌ 不推荐:将 Prettier 作为 ESLint 规则运行(双重格式化,性能差)
pnpm add -D eslint-plugin-prettier

eslint-plugin-prettier 会让 ESLint 执行 Prettier 格式化,导致:

  • 每条 ESLint 检查都运行 Prettier,性能下降 5-10 倍
  • editor.formatOnSave 可能冲突
  • 错误信息不直观(格式化问题显示为 ESLint 错误)

3. 配置 lint-staged 仅格式化暂存文件

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx,css,scss,html,json,md,mdx,yaml,yml}": [
      "prettier --write"
    ]
  }
}

避免在 pre-commit 钩子中格式化整个项目,只处理即将提交的文件。

4. CI 中使用 --check 而非 --write

# ✅ CI 中检查格式
npx prettier --check .
 
# ❌ 不要在 CI 中修改文件
npx prettier --write .

--check 只检查并报告不符合格式的文件,返回非零退出码使 CI 失败。

5. 使用 .prettierignore 排除无关文件

# .prettierignore
dist/
build/
.next/
node_modules/
coverage/
*.min.js
*.min.css
CHANGELOG.md
pnpm-lock.yaml

6. 统一编辑器配置

在项目中添加 .vscode/settings.json.vscode/extensions.json,确保团队成员使用相同的格式化工具和配置:

// .vscode/settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.formatOnPaste": false
}
 
// .vscode/extensions.json
{
  "recommendations": ["esbenp.prettier-vscode"]
}

7. 锁定 Prettier 版本

格式化结果与 Prettier 版本强相关。升级 Prettier 可能导致所有文件格式变化。务必:

  • 使用 --save-exact 和锁文件锁定精确版本
  • 升级 Prettier 时单独提交一次格式化变更(避免混入业务代码变更)
  • 在 CI 中使用与本地相同的 Prettier 版本

8. 结合实验性快速 CLI 提升性能

对于大型项目,使用 Prettier 3.6+ 的实验性快速 CLI:

# 启用实验性快速 CLI(需要 3.6+)
npx prettier --experimental-cli --write .

该 CLI 提供内置并行处理、改进缓存和更快的配置解析,用户反馈性能提升可达 10 倍以上。

常见陷阱

  1. Prettier 与 ESLint 规则冲突:必须使用 eslint-config-prettier 关闭冲突规则,否则两边互相覆盖
  2. printWidth 不是硬限制:Prettier 会在可能的情况下遵守 printWidth,但长字符串、长注释等无法被截断
  3. 格式化与 lint 顺序:在 lint-staged 中先运行 Prettier,再运行 ESLint,避免 ESLint 修复后再被 Prettier 重新格式化
  4. 版本不一致导致 diff:团队成员使用不同版本 Prettier 会导致格式变化来回跳动。务必锁定版本
  5. prettier-ignore 滥用:过度使用 // prettier-ignore 导致代码风格不一致。仅在特殊排版(如 ASCII 表格、对齐常量)时使用
  6. Vue 模板空白敏感:Prettier 默认对 HTML 空白敏感,可能导致 Vue 模板格式化结果不符合预期。根据需要调整 htmlWhitespaceSensitivity 选项

技术局限与边界

已知限制

  1. 不可深度自定义格式化规则:Prettier 的"有态度"设计意味着你无法控制具体的格式化行为。如果团队对某种格式有强烈偏好(如函数参数每行一个),Prettier 可能无法满足。

  2. 性能瓶颈:作为 JavaScript 实现的大型工具,在超大项目(数万文件)中性能明显不如 Biome 等 Rust 工具。实验性快速 CLI(v3.6+)正在改善这一状况。

  3. 不支持代码语义分析:Prettier 只做格式化,不检查代码质量。未使用变量、潜在 bug 等问题需要 ESLint 等 Linter 工具。

  4. 注释格式化不稳定:注释的位置和格式是 Prettier 中最容易出现意外行为的领域,特别是多行注释、行尾注释、嵌套注释等场景。

  5. 不支持所有语言:虽然核心支持 15+ 种语言,但 PHP、Ruby、Rust、Go 等需要通过社区插件,插件质量和维护状态参差不齐。

  6. 无法格式化无效代码:Prettier 需要先成功解析代码为 AST,语法错误的代码无法格式化(与 Biome 的弹性解析不同)。

  7. 不支持增量格式化 API:Prettier 的 API 是全量格式化,不提供"仅格式化变更行"的能力。

不适用场景

  1. 需要高度自定义格式化规则的项目:如果团队对代码格式有大量特殊要求,Prettier 的少量配置项无法满足。
  2. 需要 Lint + Format 一体化的场景:Prettier 只做格式化,如果希望用一个工具同时完成 Lint 和格式化,Biome 更合适。
  3. 对格式化工具性能有极致要求的超大型项目:Biome 等 Rust 工具在性能上具有数量级优势。
  4. 需要格式化非标准/自定义 DSL 的项目:除非自己编写 Prettier 插件,否则无法支持自定义语言。

权衡取舍

取舍Prettier 的选择理由
可配置性 vs 一致性选择一致性减少团队争论,提高协作效率
灵活性 vs 简单性选择简单性零配置即可使用,降低上手门槛
性能 vs 开发便利性选择开发便利性(JS 实现)便于社区贡献和维护
语言覆盖广度 vs 深度选择广度 + 插件扩展通过插件支持更多语言
格式化 vs 代码检查选择专注格式化保持工具边界清晰,各司其职

迁移注意事项

  1. 从其他格式化工具迁移到 Prettier

    • 首次运行 prettier --write . 会产生大量文件变更
    • 建议单独提交一次格式化变更,便于 review
    • 使用 git blame --ignore-rev 跳过格式化提交的 blame
  2. 从 Prettier 迁移到 Biome

    • 格式化输出约 97% 兼容
    • 剩余 3% 的差异需要手动确认
    • 需要重新配置 Lint 规则
    • 注意 Biome 规则命名使用 camelCase,与 ESLint 的 kebab-case 不同
  3. Prettier 版本升级

    • 大版本升级(如 2.x → 3.x)可能改变格式化行为
    • 升级前在分支上测试,确认格式变更可接受后再合并
    • 3.x → 4.x 升级将引入快速 CLI,可能有行为微调

学习资源

官方文档

博客与版本更新

教程与指南

社区资源

学术论文


2026 年现状

最新版本

截至 2026 年 7 月,Prettier 的最新稳定版本为 3.9.4。主要版本时间线:

版本发布时间关键变化
3.5.02025 年 2 月objectWrap 选项、experimentalOperatorPosition、TS 配置文件支持
3.6.02025 年 6 月实验性快速 CLI、@prettier/plugin-oxc(Rust OXC 解析器)、@prettier/plugin-hermes(Rust Hermes Flow 解析器)
3.7.02025 年 11 月类/接口格式化一致性改进、导入属性多行换行、插件 API 增强(异步 preprocess、忽略节点打印等)
3.8.02026 年 1 月Angular v21.1 完整支持(@switch 连续 @case、模板中的展开元素)、Markdown 中 Angular 语法格式化
3.9.02026 年 6 月重大解析器升级:Markdown(remark → micromark v4)、YAML(v1 → v2)、Flow(Rust 解析器)、GraphQL(v17 新语法);JS --no-semi 模式注释稳定化;JSON 保留原始数字/字符串表示
3.9.42026 年 7 月补丁修复

Prettier 4.0 路线图

Prettier 4.0 的核心目标是将实验性快速 CLI 作为默认 CLI 发布。关键信息:

  • 核心卖点:快速 CLI 提供内置并行处理、改进缓存、更快的配置解析和更精简的依赖树,性能提升 10-14 倍
  • Alpha 状态4.0.0-alpha.13 已在 npm 上发布(通过 prettier@next 安装测试)
  • GitHub Milestone #42 追踪中
  • 无确切发布日期:发布由功能就绪驱动而非固定时间表
  • 向后兼容:计划保持 ~100% 向后兼容
  • Flow 迁移:4.0 将使用 @prettier/plugin-hermes 替代 Babel 作为 Flow 的默认解析器

发展趋势

  1. 性能追赶:通过实验性快速 CLI 和 Rust 解析器插件(OXC、Hermes),Prettier 正在积极回应来自 Biome、Oxfmt 等 Rust 原生工具的性能挑战

  2. 解析器持续现代化:3.9 版本完成了多个解析器的重大升级(Markdown micromark v4、YAML v2、Flow Rust 解析器、GraphQL v17),为未来功能奠定基础

  3. 来自 Biome/Oxfmt 的竞争

    • Biome 2025 年快速增长,用 Rust 编写,lint + format 一体化,速度优势 10-25 倍
    • Oxfmt(OXC 团队)2025 年底发布 Alpha,声称比 Prettier 快 30 倍,兼容率 >95%
    • Prettier 通过性能优化和生态优势应对竞争
  4. 供应链安全意识提升:2025 年 7 月的 eslint-config-prettier 供应链攻击事件(CVE-2025-54313)推动了社区对 npm 包安全的关注,锁文件验证和依赖审计成为标配实践

社区活跃度

指标数据
GitHub Stars91,000+
贡献者800+
依赖仓库10,000,000+
npm 周下载量4000 万+
发布频率每 3-6 个月一个 minor 版本
维护者Fisker Cheung、Sosuke Suzuki、Christopher Chedeau 等核心维护团队持续活跃
VS Code 扩展最流行的代码格式化扩展之一

未来展望

  • Prettier 4.0 正式发布:快速 CLI 成为默认,性能大幅提升,保持向后兼容
  • 持续解析器升级:跟进各语言解析器最新版本,支持新的语法特性
  • 插件 API 演进:为插件开发者提供更好的 API,支持更多语言和自定义场景
  • 生态维护:在 Biome 等新兴工具竞争下,持续维护 Prettier 在代码格式化领域的标杆地位
  • 配置解析性能:解决 Monorepo 场景下的配置查找和解析性能问题