xDocxDoc
AI
前端
后端
iOS
Android
Flutter
AI
前端
后端
iOS
Android
Flutter
  • 关于

    • Prettier
    • 构建并强制执行
    • Prettier vs. Linters
    • 选项设计原理
    • 设计理念
  • 使用

    • 安装指南
    • 忽略代码
    • precommit
    • 插件
    • CLI
    • API
    • Browser
    • CI
  • 配置 Prettier

    • options
    • Configuration File
    • 共享配置
  • Editors

    • 编辑器集成
    • WebStorm 设置
    • Vim 配置指南
    • 监视文件变更
  • Misc

    • 技术实现细节
    • 生态
    • 企业解决方案

设计理念

Prettier 是一个强约定的代码格式化工具。本文阐述其核心设计原则。

Prettier 的核心关注点

正确性

Prettier 的首要原则是输出行为完全一致的合法代码。若发现格式化后行为改变,请务必https://github.com/prettier/prettier/issues - 这属于需要修复的严重缺陷!

字符串处理

引号选择策略:

  • 优先选择转义字符更少的引号类型
  • "It's gettin' better!"(双引号需0次转义)
  • 而非 'It\'s gettin\' better!'(单引号需2次转义)
  • 默认使用双引号(可通过 /docs/options#quotes 选项修改)

JSX特殊规则:

  • 属性值默认双引号(遵循HTML惯例)
  • 通过 /docs/options#jsx-quotes 启用单引号
  • 保持原始转义形式(如 "🙂" 不转为 "\uD83D\uDE42")

空行处理

空行自动生成存在技术挑战,Prettier采用智能策略:

  1. 保留原始空行结构
  2. 合并连续空行为单空行
  3. 移除块级结构首尾空行
  4. 文件始终以单个换行符结尾

多行对象

智能折行策略:

// 原始含换行 → 保持多行
const user = {
  name: "John Doe",
  age: 30,
};

// 原始无换行 → 保持单行
const user = { name: "John Doe", age: 30 };

手动控制技巧:

// 单行转多行:在 { 后添加换行
const user = {
 name: "John Doe", age: 30 };
// 格式化后 →
const user = {
  name: "John Doe",
  age: 30,
};

// 多行转单行:删除 { 后换行
const user = {  name: "John Doe",
  age: 30
};
// 格式化后 →
const user = { name: "John Doe", age: 30 };

:::note[格式化可逆性说明] 当前策略是临时方案,团队正在研究更优启发式规则,目标是实现完全可逆的格式化(增删属性不改变原有格式结构)。 :::

装饰器处理

类装饰器:强制独立行

@observer // 始终单独成行
class OrderLine {
  @observable price: number = 0; // 方法装饰器保持原位
}

方法装饰器:尊重原始布局

class HeroButton {
  // 单行装饰器保持单行
  @Output() change = new EventEmitter();
  
  // 多行装饰器保持多行
  @readonly
  @nonenumerable
  NODE_TYPE: 2;
}

模板字符串

智能折行规则:

// 含换位的插值保持多行
`User: ${user.firstName} ${  // 原始有换行
  user.lastName
}`

// 无换位插值保持单行(即使超宽)
`thisIsAVeryLongString${andThisIsAVeryLongInterpolation}`

提示

在 ${} 内添加换行可强制折行

分号策略

自动安全防护:

// 原始无分号
[-1, 1].forEach(delta => addLine(delta))

// 格式化后添加防护分号
;[-1, 1].forEach(delta => addLine(delta))

防护分号避免后续添加代码时出现https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Lexical_grammar#自动分号插入错误

注意

Prettier 不修复现有分号相关错误:

// 错误代码保持错误行为
console.log('Running')(
  async () => await work()
)()

打印宽度

options.md#print-width 是指导值而非严格限制:

特殊场景突破限制:

  1. 导入语句
import { SingleComponent } from "../components/single-component/main";
  1. 测试描述
it("验证超长描述文本不被意外折行", () => { /*...*/ })

JSX格式化

特殊处理原则:

// 普通函数
function greet(user) {
  return user ? `Welcome, ${user.name}!` : "Greetings!";
}

// JSX组件:括号包裹+条件表达式分行
function Greet({ user }) {
  return (
    <div>
      {user ? (
        <p>Welcome, {user.name}!</p>
      ) : (
        <p>Greetings!</p>
      )}
    </div>
  );
}

避免残留分号导致的渲染问题:<p>Greetings!</p>;

注释处理

内容保留:

  • 普通注释保持原样
  • JSDoc风格注释自动对齐缩进

位置策略:

// 推荐:独立行注释
// eslint-disable-next-line no-eval
const result = safeEval ? eval(input) : fallback;

// 避免:行尾注释
const result = safeEval ? eval(input) : fallback; // eslint-disable-line

魔法注释注意事项:

// 错误:折行后失效
// eslint-disable-next-line no-eval
const result = safeEval && allowNative ? eval(input) : fallback;

// 正确:移至表达式前
const result =
  // eslint-disable-next-line no-eval
  safeEval && allowNative ? eval(input) : fallback;

最佳实践

优先使用范围注释:/* eslint-disable */ 和 /* istanbul ignore next */

非标准语法声明

Prettier 对 ECMAScript 提案和非标准 Markdown 语法的支持属于实验性功能:

  • 支持力度:尽力而为(best-effort)
  • 兼容性:可能在不通知的情况下变更
  • 版本变更:不视为破坏性更新

机器生成文件声明

package.json 等机器生成文件采用特殊格式化策略:

// 使用 JSON.stringify 风格格式化
{"dependencies":{"prettier":"^3.0.0"}}

移除垂直空白等差异属于预期行为,避免与包管理器冲突。

Prettier 的明确边界

Prettier 仅专注代码打印,不进行代码转换:

不做转换的典型案例:

  • 引号类型转换(单引号↔双引号↔模板字符串)
  • 字符串连接符拆分(+ 操作符)
  • 可选语法简化(移除 {}/return)
  • 条件表达式转 if-else 语句
  • 导入/对象键/类成员排序
  • CSS属性重排

这些转换可能影响代码行为,违背#正确性核心原则。

设计总结

Prettier 通过约束性设计实现统一的代码风格:

  1. 可靠性优先:保证格式化前后代码行为完全一致
  2. 最小意外原则:
    • 字符串引号智能选择(最少转义)
    • 空行与对象结构保留原始意图
    • 装饰器位置尊重开发者习惯
  3. 安全防护:
    • 自动添加防护分号避免ASI错误
    • JSX括号包裹防止语法错误
  4. 灵活约束:
    • 打印宽度作为指导值而非绝对限制
    • 特殊语法(测试用例/导入语句)突破限制
  5. 边界清晰:
    • 不改变代码语义行为
    • 不进行语法转换
    • 不重排代码结构

这种"有主见的格式化"消除了风格争论,使开发者专注于逻辑而非排版。通过3000+项目的实践检验,Prettier已成为现代工作流的基石工具。

最后更新: 2025/8/26 10:07
Prev
选项设计原理