1.2固执哲学终结争论


1.2 固执哲学终结争论

核心洞察:选择本身是问题

Prettier 的缔造者 Christopher Chedeau 在 2017 年发布这个工具时,在 README 里写了一段被反复引用的话:

The problem Prettier solves is the following: by far the most common question people have when they're setting up a project is "How do I format my code?" It seems like a trivial thing, but it ends up being the single biggest source of bikeshedding in any project.

"bikeshedding"(停车棚争论)是一个术语,指人们在一个不重要的问题上投入了不成比例的讨论精力。代码格式正是这个问题的典型案例——每个人都能发表意见,每个人的意见都有一点道理,但最终的选择对项目成功几乎没有影响。

Prettier 的洞察是:代码格式的价值在于一致性,而不在于风格本身的优劣。只要全团队的代码看起来一样,具体用单引号还是双引号、两个空格还是四个空格,这些选择根本不重要。既然如此,为什么还要花时间去争论一个不重要的选择?

以退为进:限制选择来获得自由

Prettier 的策略是做出一个完整的、自洽的风格决策集,然后不让你改(或只让你改极少数几项)。这种策略初听起来是"剥夺自由",但实际效果恰恰相反。

它剥夺的是一种"微不足道的自由"——你失去了对引号类型的控制权、对缩进宽度的控制权、对尾随逗号的控制权。这些控制权在编码实践中几乎不产生任何创造性价值。没有人会因为用了双引号而不是单引号而写出更好的算法。

它赋予的是一种"更高层次的自由"——你不再需要思考格式问题,不再需要维护 ESLint 的上百条风格规则,不再需要在代码审查中讨论格式。这些被释放出来的精力和注意力,可以全部投入到业务逻辑、架构设计、性能优化这些真正需要创造力的工作上。

这就像一个城市的交通系统:如果每个路口的红绿灯时长都由附近居民投票决定,结果是争论不断、交通混乱。但如果由交通管理部门统一设定一套科学的标准,所有路口采用相同的信号规范,整个城市的通行效率反而会大幅提升。居民失去的是"决定我家门口红绿灯配时"的权利,得到的是"不用堵在路上"的自由。

"固执"不是傲慢,是工程判断

Prettier 的"固执"常被误解为工具作者的傲慢——"凭什么你的审美就是标准?"。但这种理解搞反了因果关系。Prettier 的作者并不声称内置的风格是"最好的",而是说它"足够好,且不需要争论"。

这是两个完全不同的主张。前者暗示存在一个客观最优的风格,这是错误的——风格确实没有绝对优劣。后者则是一个务实的工程判断:与其花时间找"最优",不如选一个"不错"的然后开始干正事。

Prettier 内置的默认配置确实经过了一些设计考量:80 字符的 printWidth 是一个有几十年历史的行宽传统,tabWidth: 2 符合大多数 JavaScript 项目的实践,单引号加分号是社区中更常见的组合。但这些选择本身不是重点——就算把默认值改成双引号加 Tab,只要团队统一用,效果是一样的。

关键的工程属性不是"默认值是否最优",而是两个确定性特征:

幂等性(Idempotency):同一段代码经过 Prettier 处理一次后,再处理任意次,输出不变。这意味着你永远不会在格式化过程中引入新的变更——代码要么已经格式化过(不变),要么还没格式化过(被统一成标准格式),不存在"格式化一次变一次"的情况。

确定性(Determinism):同样的输入永远产生同样的输出。无论谁在什么时候运行 Prettier,只要代码语义不变,输出完全一致。这消除了"我格式化后的结果跟你不一样"的可能性。

图 1-2:Prettier 的幂等性与确定性

幂等性和确定性这两个特征加在一起,意味着代码的格式变成了一种"稳定态"——一旦达到,就不会再变。团队的代码库会自然收敛到这个稳定态,而不需要任何人的额外努力。

从配置地狱到信任委托

理解 Prettier 的哲学,最好的方式是对比传统 ESLint 配置的体验。

一个典型的 ESLint 配置文件,光是和格式相关的规则就有几十条。indentquotessemicomma-danglebrace-styleobject-curly-spacingarray-bracket-spacingspace-before-function-parenkeyword-spacingmax-len……每一项都有若干可选值和参数。一个五人团队在配置这些规则时,几乎不可能不产生分歧——每个人对"代码应该长什么样"都有不同的直觉。

更麻烦的是,这些规则之间还会互相冲突或产生边界情况。"如果函数参数太多要换行,那换行后缩进多少?是跟括号对齐还是多一层?箭头函数的情况又怎么处理?"这些细节问题在 ESLint 规则体系里需要一条条配置,而且经常需要加载额外的插件才能覆盖。

Prettier 把这些决策全部代劳了。你不需要告诉它"引号用单引号"——它内置了这个决定。你不需要告诉它"对象最后一个属性加逗号"——它也内置了。整个配置文件从几十条规则压缩到可能只有一两项:

{ "printWidth": 100, "singleQuote": true }

很多团队甚至完全不需要配置文件——直接用默认值。

这种体验的转变,本质上是把一种"治理模式"从民主协商变成了信任委托。团队不再需要就每条规则达成共识,而是集体信任一个工具的判断。这是一种社会契约的重新签订,它之所以能被广泛接受,正是因为 Prettier 给出的结果确实足够好——没有人会因为必须用单引号而痛苦到拒绝使用这个工具。

争论终止的真实效果

Facebook(Prettier 的诞生地)在内部推广 Prettier 后,代码审查中的格式讨论基本消失了。这不是夸张——当所有人知道"代码格式由 Prettier 决定"这个事实后,就没有人再在 review 里提格式问题了。不是被禁止提,而是自然没有了提的动机,因为讨论格式已经没有意义——不管你觉得双引号多好,Prettier 都会把它改成单引号,你改不了一行。

这种变化看起来小,但对团队文化的影响很大。代码审查从"格式纠正 + 逻辑审查"变成了纯粹的"逻辑审查"。审查者的注意力从"这里少了一个空格"转移到"这个算法的时间复杂度对不对"、"这个错误处理是否覆盖了边界情况"。审查质量提高了,开发者的挫败感降低了,整体效率上了一个台阶。

开源项目引入 Prettier 后也有类似效果。贡献者不需要先学习项目特有的风格规则——只要跑了 Prettier,格式就对了。这降低了贡献门槛,让更多人有能力提交合乎规范的 PR。

01-02-fig01

图 1-3:引入 Prettier 前后的代码审查效率变化

反对意见及其回应

"固执"哲学在实践中遇到过一些合理的质疑,值得逐一回应。

"默认值不适合我的项目"。这确实可能发生,但 Prettier 提供的配置项(如 printWidthsingleQuotetabWidth)足以覆盖最常见的调整需求。真正遇到不可调和冲突的情况极少,而且通常是因为项目有特殊的历史原因(比如需要兼容 80 字符宽的终端),而不是因为 Prettier 的默认值"不好"。

"工具应该灵活,不应该限制用户"。这个原则在大多数工具领域是正确的,但代码格式化是个例外。灵活性意味着选择,选择意味着讨论,讨论意味着成本。对于代码格式这个特定的领域,"灵活"带来的成本大于收益。这不是一个普遍原则,而是针对特定问题的具体判断。

"我习惯了另一种风格,用 Prettier 很不舒服"。这种不适感通常在一到两周内消失。人类对代码风格的适应速度远超想象——你现在觉得"别扭"的风格,两周后就会变成"正常"的。短期的适应成本换来的是长期的效率提升,这笔账是划算的。

Prettier 的实践已经在数以万计的开源项目和商业项目中验证了这个哲学的可行性。那些曾经在风格争论上浪费大量时间的团队,在引入 Prettier 后几乎无一例外地感受到了效率提升。这不是理论推演,而是被反复验证的工程实践。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U