[译] A Prettier JavaScript Formatter

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

(上面的 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!

道谢:

    原文作者:题恭弘=叶 恭弘
    原文地址: https://segmentfault.com/a/1190000008861384
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞