资讯专栏INFORMATION COLUMN

[译] A Prettier JavaScript Formatter

elina / 1512人阅读

摘要:原文今天我发布一个格式化工具它的灵感来源于它对于和的语言特性有着高级的支持通过将解析为并且基于美化和打印会丢掉几乎全部的原始的代码风格从而保证代码风格的一致性跟不一样的在于它没有大量的和需要管理不过同时有一点也很重要一切都是确定好的我很高

原文 http://jlongster.com/A-Pretti...

今天我发布 Prettier, 一个 JavaScript 格式化工具. 它的灵感来源于 refmt, 它对于 ES2017, JSX 和 Flow 的语言特性有着高级的支持. 通过将 JavaScript 解析为 AST 并且基于 AST 美化和打印, Prettier 会丢掉几乎全部的原始的代码风格, 从而保证 JavaScript 代码风格的一致性. 跟 ESLint 不一样的在于它没有大量的 options 和 rules 需要管理. 不过同时有一点也很重要, 一切都是确定好的.
我很高兴的随着离开 Mozilla 之后我有时间做自己的开源工作了, 这是我 2017 年的开始.

下面是一个在线运行的 Demo. 注意语法是支持 JSX 和 Flow 的. 你可以在下面的编辑器里输入任何代码, 代码会被自动格式化.
行长的最大值是 60. 两个编辑器当中上面一个是原始输入, 下面是格式化之后的版本.

//                                           60 chars -->   |
function makeComponent() : int {
  return {
    longCall() {
      complicatedFunction(importantArgument(), secondaryArgument())
      weirdStyle({ prop: 1 },
        1, 2, 3);
    },
    render() {
      const user = {
        name: "James"
      };
    return 
hello ${name}! JSX is supported
; } }; }
//                                           60 chars -->   |
function makeComponent(): int {
  return {
    longCall() {
      complicatedFunction(
        importantArgument(),
        secondaryArgument()
      );
      weirdStyle({ prop: 1 }, 1, 2, 3);
    },
    render() {
      const user = { name: "James" };
      return (
        
hello ${name}! JSX is supported
); } }; }

(上面的 Demo 运行在 Prettier 0.0.8)

很多人知道我在写 React 代码的时候通常不会写 JSX. 一个月之前我想试试了, 我猜意识到挡在我前面的是 Emacs 对 JSX 支持不足的问题. Emacs 对代码缩进本来有不错的支持. 我从来不需要手动多缩进什么东西. 但是对于 JSX 却不起作用, 我看了下其他的编辑器, 也看到了类似地问题(其他的编辑器在强制纠正缩进规则这方面基本上做的更差).

大概在同时我用了一段时间 Reason, Reason 提供了 refmt 工具用来自动格式化代码. 我就被迷住了. refmt 屏蔽了写代码当中很多让人分心的因素. 你可以按自己的习惯随便写, 然后格式化掉. 我意识到这不仅可以解决 JSX 的问题, 它也可以对任何编辑器提供强制整个团队代码样式的一致性的工具.

如果说计算机擅长做某个事情的话, 计算机会擅长解析代码和分析代码. 所以我准备把这个事情做出来, 这样就有了 Prettier. 我并不打算从底层开始写, 所以 Prettier 是从 fork recast 的 printer 开始的, 内部用 Wadler 在 "A prettier printer" 的算法进行了重写.

为什么选这套算法? 首先要看下为什么已有的样式格式化工具并没有实际的效验.

已有的样式格式化工具缺失了一个极为重要的部分: 最大的行长. 当然, 你是可以用让 ESLint 在行长过大时警告的(ESLint 不会知道怎样修复它). 最大行长是格式化工具决定性的一个部分, 特别是用在布局和折叠代码.

比如看下面的代码:

foo(arg1, arg2, arg3);

看上去格式化的方式是对的. 然而我们都会遇到这样的情况:

foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne());

我之前的格式突然就不正常了, 因为太长了. 你多半会这样来处理:

foo(
  reallyLongArg(),
  omgSoManyParameters(),
  IShouldRefactorThis(),
  isThereSeriouslyAnotherOne()
);

这个例子清楚地展出了最大行长对于我们想要的代码的样式有着直接的影响. 目前的样式工具无视了这一点, 也就意味着在这个麻烦的场景当中它们毫无帮助. 团队里的每个人会按照他们自己不一样的规则调整代码的样式, 因而我们也就失去了我们想要的一致性.

Wadler 算法的论文描述了基于约束的代码的局部系统. 它会"测算"代码的长度, 如果超过了最大行长, 就会折行.

即便我们不顾行长, 在各种 linter 工具里也有很多办法偷懒. 我所知道的最严格的 linter 也会让这样代码的代码通过:

foo({ num: 3 },
  1, 2)

foo(
  { num: 3 },
  1, 2)

foo(
  { num: 3 },
  1,
  2
)

Prettier 通过解析代码和基于 AST 重新生成满足自己的规则的代码, 计算考虑了最大行长, 必要时进行代码的折行, 最终屏蔽了各种过于自由的样式.

关于模式

为了让 Prettier 变得实用我做了大量的工作. 目前输出的代码已经不错了, 我估计后面还有很多让大家能觉得更好的调整.

我们尽量让代码能遵循特定的模式. 比如这个写法在 JavaScript 很流行:

myPromise
  .then(() => {
    // ...
  })
  .then(() => {
    // ...
  })
  .catch(() => {
    // ..
  });

简单的 printer 会把它折叠成下面这样:

myPromise.then(() => {
  // ...
}).then(() => {
  // ...
}).catch(() => {
  // ..
});

不过在这场, 我们检测到"链式调用"的模式然后特意把每个 .then 生成在独立的一行.

如果你用到了某个 Prettier 没有格式化好的模式, 请提交一个 Issue, 我们来讨论一下如何检测这个规则以及如何有针对性地处理你的场景.

默契的团队

在团队中工作时, 很需要减少摩擦, 特别是在大型团队里. 尽管无法完全避免摩擦, 我们更多能做的是通过工具变得更容易在一起协作.

你可能觉得配置一下 ESLint 不会消耗太多时间, 或者说团队里不会话很多时间争论语法. 根据我的经验, 实际上不是. 即便你配置了大量的 ESLint 规则, 它实际上还是无法捕捉到全部的样式的差异. 团队仍然会努力去强制一套统一的样式, 而这显得很让人分心.

语法的细节其实没那么重要. 就让 Prettier 这样的工具来做格式和排版就好了, 程序员应该关注在那些真正的问题上.

自由度

结果好像的用了 Prettier 之后你写代码更加自由了, 怎么写都可以, 因为随后一格式化马上就纠正回来了!

不想关心分号的问题? 当然, 直接写就好了:

function foo() {
  var x = 5
  var y = 6
  var z = 7
  return x + y + z
}

把这段代码贴到上面去, 你会看到 Prettier 已经帮你把分号插入好了.

处理特别复杂的问题的时候想要写点脏代码的? 当然可以, 全写在一行都可以. 用自己习惯写的脏的语法就好了. 然后只要一个快捷键就能把代码格式化掉.

试一试 Prettier!

鸣谢:

Christopher Chedeau 鼓励我把这些弄到能用的程度, 还有添加了 Jest 测试工具

Pieter Vanderwerff 在做相似的项目, 帮忙讨论了解决方案

Jordan Walke 写的 refmt, 也是 Prettier 的直接灵感来源

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82247.html

相关文章

  • Web 项目编码规范化工具

    摘要:项目编码规范化工具工具代码校验工具,让代码更一致和避免。在配置文件到项可对单条规则一一进行改写。以下以项目需校验文件为例参考链接一步一步,统一项目中的编码规范 Web 项目编码规范化工具 工具 ESLint The pluggable linting utility for JavaScript and JSX 代码校验工具(linting utility),让代码更一致和避免 bug...

    meislzhua 评论0 收藏0
  • VS code-前端配置_022

    摘要:前端配置简体中文插件,一般会自动识别你的环境,自动提示是否需要简体中文的语言包。使用插件将目前配置保存到上,以后只需要从上获取,就可以一次性安装插件配置信息。 VS code-前端配置 showImg(https://segmentfault.com/img/bVbuK6l?w=1224&h=999); Chinese (Simplified) Language Pack for Vi...

    cyrils 评论0 收藏0
  • Prettier+VScode 治好你的代码洁癖

    摘要:忍无可忍只能拔枪相见了。而只关心格式化文件最大长度混合标签和空格引用样式等。可见,代码格式统一的问题,交给再合适不过了。和配合使用,风味更佳。我的配置文件如下到此,安装完毕,使用就可格式化代码。两者配合才能使项目代码优雅健壮 试想一个多人开发的项目,每次同步代码,看到各个风格迥异,换行空格混乱,4格,2格缩进交替上演的代码文件,分分钟逼死强迫症啊。忍无可忍只能拔枪相见了~~。统一的代码...

    qc1iu 评论0 收藏0
  • vscode 配置eslint 开发vue的相关配置

    摘要:参考详情请参考此插件允许和修复文件中包含的内联脚本。这是因为中发生了许多内部更改,包括支持预处理器中自动固定的新。请确保在你的配置中使用了该插件自身的配置代码规范解决报错问题 如何在vscode中用JavaScript Standard Style风格去验证 vue文件实际上JavaScript Standard Style有一个FAQ, 说明了如何使用。 但是有一点非常重要的作者没有...

    haobowd 评论0 收藏0

发表评论

0条评论

elina

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<