<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Prettier 完全指南,以及和 Git、VSCode、ESLint 整合,讓你的代碼變美麗

          共 12678字,需瀏覽 26分鐘

           ·

          2021-09-10 16:01

          點擊上方 全棧前端精選,關(guān)注公眾號

          回復1,加入高級前端交流群

          還是老習慣。有錯誤請指正,我及時修改。有問題請評論區(qū)提出來,有時間我會解答。

          作者:陳龍

          https://zhuanlan.zhihu.com/p/81764012

          已獲取作者授權(quán),請勿未經(jīng)允許轉(zhuǎn)載。

          0.前言

          用了兩年 Prettier,之前也寫過一篇簡單的文章,但是很不全面詳細。最近又把 Prettier 的文檔詳細看了一遍,結(jié)合過去兩年的一些思考,有了更多的理解,希望這篇文檔讓大家對 Prettier 有一個全方位的理解。

          我一向倡導的學習方式就是閱讀官方文檔,好的技術(shù)一定有好的文檔。而閱讀官方文檔分成三個階段:

          1. 剛開始接觸的時候,通篇閱讀。對要學的東西有一個宏觀認識和理解。

          理解,就是要明白一項技術(shù)的設計初衷、背后的哲學。學習任何一項技術(shù)、語言、框架之初,都要問自己幾個問題:

          • 為什么要出現(xiàn)這個新東西?之前同類或類似的東西有什么不好嗎?
          • 這個東西帶來哪些新思想和設計哲學,解決了之前哪些不容易解決的問題?
          • 發(fā)明人對我們有什么建議,可以讓我們更好地利用這個東西?

          帶著上面的問題去閱讀文檔。有不理解的部分不用怕,因為不可能第一遍讀文檔就理解全部。不理解的部分要記下來,便于今后返回來查閱。

          很多人都不注意上面這些問題,而是上來就應用,人家用我就用,或者公司要求用,或者追時髦用。按照自己以前的經(jīng)驗和想法用別人按不同思想開發(fā)出來的技術(shù),越用越難受,然后就得出結(jié)論:這個東西不成熟,坑很多。

          2. 開始實踐。只有實踐才出真知。也只有實踐才能對之前以為自己理解的部分又更深入的認識,也只有實踐才能把之前不理解的部分想明白。有些概念必須在實際問題環(huán)境中才能看明白想清楚。這時候,遇到問題要返回去查閱文檔相對應的部分。因為你在第一階段已經(jīng)對文檔結(jié)構(gòu)有了了解。

          3.在用了一段時間后,認為自己已經(jīng)算是“熟悉”了。在不忙的時候,回過頭重新把文檔再通讀一遍。這時候你會發(fā)現(xiàn)自己站在了一個新的高度,也會發(fā)現(xiàn)文檔中的一些觀點是自己以前沒有注意的,這種感覺就對了。

          這篇文檔就算是我在第 3 階段之后的一篇總結(jié),分享給大家。

          1.為什么用 Prettier?代碼風格最不好管理的地方在哪里?

          代碼風格是所有程序員都要遇到的問題,不管是團隊協(xié)作還是個人練習。就連不懂開發(fā)的老板都會裝逼一下,強調(diào)一定要注意代碼風格。往往很多公司想到提高代碼質(zhì)量和開發(fā)效率,首先就想到從代碼風格入手。

          但現(xiàn)實中卻很少看到代碼風格管理很好的團隊。因為在大多數(shù)時候,代碼風格起于討論,也止于討論,虎頭蛇尾有始無終。無法確定一個讓所有人都滿意的方案,就很難執(zhí)行下去

          就算勉強少數(shù)人服從了大多數(shù),但在實際開發(fā)過程中還會遇到各種各樣的問題。例如不同開發(fā)人員用不同的 IDE,用相同 IDE 的又因為設置不同默認的縮進也不同。自己又懶得去設置,或者不會設置,最后就亂了。好不容易實現(xiàn)了功能,每次代碼審查前還要手動去修改這些細節(jié)的東西,實在頭疼。那如何解決呢?

          針對這種情況的辦法,我國政府早就鄭重提出了:擱置爭議,共同開發(fā)。吵來吵去,大家各自還為石油頭疼。放著寶貴的資源在海底,看著中東那幫家伙發(fā)財,太傻了。

          Prettier 也鄭重提出:大家不要吵!用這種風格還是那種風格是半斤八兩的關(guān)系,但是最后用沒用上卻是 0 和 1 的關(guān)系。咱們先提高代碼的可讀性和可維護性再說,具體什么風格我給你們定。

          大家都遵循 Prettier 給出的方案就好了,保證一切順利進行下去。這就是 Prettier 的opinionated

          咱們在下一節(jié)詳細講。

          2.什么是 Prettier?

          Prettier 在自己官網(wǎng)首頁列出這么三點:

          • An opinionated code formatter
          • Supports many languages
          • Integrates with most editors
          • Has few options

          官方首先告訴你,Prettier 是一個 Opinionated 的代碼格式化工具。所以要掌握 Prettier 的精髓就是要理解這個單詞。

          什么是 Opinionated?我在知乎很多回答中都提到這個詞,對于理解框架或技術(shù)非常重要。很多框架在文檔開始就會告訴你它是Opinionated還是Unopinionated

          例如看 Angular 官方的Style Guide[1]

          Looking for an opinionated guide to Angular syntax, conventions, and application structure? Step right in! This style guide presents preferred conventions and, as importantly, explains why.

          甚至于,框架都可以按照是否 Opinionated 分為兩大類:

          Java 服務器端開發(fā)的同學,打開 Spring Boot 的文檔:

          熟悉 Node 開發(fā)的同學,打開 http://expressjs.com[2]

          熟悉前端三大框架的同學問自己一個問題:Angular 和 React/Vue 在開發(fā)體驗上有什么區(qū)別?

          Angular 其實是 Opinionated,規(guī)定了你的代碼結(jié)構(gòu),讓你最好按照它給你指定的方式組織代碼。React 則沒管這么多,相對比較自由。也就是這篇文章[3]中說的:

          Angular is a full-featured “opinionated” framework. That means you have to do things the Angular way, which makes is more difficult and more rewrite to add into existing apps.
          React and Vue are “non-opinionated” frameworks. Technically, they are not frameworks. But rather “l(fā)ibraries”. They are easier to add into existing web apps without a heavy rewrite. You can drop bits and pieces of them into existing app and migrate them over little at a time.

          Prettier 說自己是一個 Opinionated code formatter,就是說:你必須認同我的觀點,按照我說的做。否則你就別用我,硬著頭皮用就會處處不爽!

          在我上一篇文章下可以看到這樣的評論:

          官方說的第 2 條:支持很多語言。看這幅圖就行了:

          圖中右側(cè)的是 Community Plugins,其中包含我比較關(guān)心的 Java。但是 Java 支持的并不好。Java Plugin 是我一直推廣的 jHipster 團隊開發(fā)的,Github 倉庫地址在這里[4],處于 Alpha 階段,而且 JHipster 自己也沒有正式使用。

          官方說的第 3 條:可以和很多 IDE 集成。看這幅圖就行了:

          我會在后面章節(jié)給出 Webstorm 和 VSCode 的配置和使用方法。

          第 4 條:Has few options,其實就是 Opinionated 的最直接體現(xiàn)。除了必要的設置項,不會再給你們更多。給你設置項越多,你們越亂,你們就會繼續(xù)爭吵!

          蘋果手機就一個 Home 鍵,老子就這樣,接受不了的滾去安卓。安卓三個鍵,左側(cè)是返回鍵,右側(cè)是屬性鍵?你換手機的時候可不一定是這樣,你還要手動設置成自己習慣的。偶爾用一下別人的安卓,可能就和你的不一樣。鍵多了就形成了混亂,還是一個鍵好。這也是 Prettier 的設計哲學,Prettier 就是代碼格式化工具中的 Apple。

          Prettier 的原理非常簡單:

          不管你寫的代碼是個什么鬼樣子,Prettier 會去掉你代碼里的所有樣式風格,然后用統(tǒng)一固定的格式重新輸出。輸出時基本上只考慮一個參數(shù),就是 line length。

          例如你寫的這行代碼:

          foo(arg1, arg2, arg3, arg4);

          一行裝得下這么多代碼,所以就不需要改。

          如果你寫了下面代碼:

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

          太長了,Prettier 就會重新改成這樣輸出:

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

          咱們再仔細探究一下這個過程。不管你之前寫的代碼是什么樣,首先必須符合語法規(guī)范。Prettier 先把你的代碼轉(zhuǎn)換成一種中間狀態(tài),叫 AST(Abstract Syntax Tree)。

          用 Prettier 提供的Playground[5]更直觀一些:

          上圖左側(cè)是手寫代碼,中間是 AST(去掉了任何代碼風格),右側(cè)是重新輸出的結(jié)果。

          Prettier 就是在這個 AST 上重新按照自己的風格輸出代碼。

          3.先練練手

          這里先介紹一下最簡單的使用方法,讓大家有一個直觀感受。如果你正在學習 JavaScript/Typescript,你的工程里只有幾個 JS/TS 文件,可以這樣用。但實際工程階段肯定是不會這么用的。Prettier 如何和其他工具整合,以及如何設置,我們后面會講到。

          NPM

          mkdir learn-prettier && cd learn-prettier
          npm init
          npm install prettier --save-dev --save-exact

          // 在learn-prettier/src目錄下創(chuàng)建index.js文件,然后自己寫一些JS代碼。JS代碼用上文那個超長的foo(......)就可以,自己也可以改的更亂一些,但必須符合JS語法。

          npx prettier --write src/index.js
          // 在看格式化之后的index.js,已經(jīng)重新輸出成固定格式了。

          Yarn

          mkdir learn-prettier && cd learn-prettier
          yarn init
          yarn add prettier --dev --exact

          // 在learn-prettier/src目錄下創(chuàng)建index.js文件,然后自己寫一些JS代碼。JS代碼用上文那個超長的foo(......)就可以,自己也可以改的更亂一些,但必須符合JS語法。

          yarn prettier --write src/index.js
          // 在看格式化之后的index.js,已經(jīng)重新輸出成固定格式了。

          npm init 命令會問你一些問題,以便于生成 package.json,一路回車采用默認值就行。

          你也可以把 package.json 內(nèi)容改改,改的亂一些,但要符合 JSON 格式。然后執(zhí)行下面命令看看 package.json 也被重新輸出了:

          npx prettier --write package.json

          其實...,你也知道,很少有人會通過命令行用,現(xiàn)在大家都用 WebStorm 呢,好像更牛 X 的人在用 VS Code。下面咱們就看看 WebStorm 和 VS Code 怎么整合 Prettier。

          4.IDE 整合

          IDE 或 Editor,這里只介紹 WebStorm 2018.1 以上版本和 VS Code。老版本的 IDEA 或 Webstorm 也可以用,但是最好還是升級吧。
          WebStorm 的設置適用于 JetBrains 家族的其他 IDE,例如 IntelliJ IDEA、PHPStorm、PyCharm...

          WebStorm

          首先安裝 Prettier Plugin

          手動格式化

          快捷方式:

          • 最直接方式
            Mac:Alt + Shift + Cmd + P
            Windows: Alt + Shift + Ctrl + P
          • 或 Mac:CMD + Shit + A
            Windows:Ctrl + Shift + A,然后輸入 Prett...
          • 或 Double Shift(連按兩次 Shift),然后選擇 Action,然后輸入 Prett...

          上面的方式就是執(zhí)行了npx prettier \--writeyarn prettier \--write,可以格式化文件、文件夾下的所有文件、或選中的一段代碼。

          保存文件時自動格式化

          如果想在保存文件的時候自動讓 Prettier 格式化代碼,需要 File Watcher。

          點+,然后選擇 Prettier。

          VS Code

          安裝Prettier Extention[6]

          手動格式化

          快捷方式:

          Mac:CMD + Shift + P -> Format Document WIndows:Ctlr + Shift + P -> Format Document

          如果安裝其他格式化代碼的 Extension,VS Code 會在右下角提示:

          點擊 Configure...

          比如我就安裝了三個可以格式化代碼的 Extension:

          選擇 Prettier 就可以了。這時候 settings.json 會增加下面內(nèi)容:

          javascript 和 typescript 的默認 Formmater 用哪個 Extension。當然這需要你在.js 和.ts 文件上分別設置一次才可以產(chǎn)生上面的設置。

          保存文件時自動格式化

          打開 VS Code 的設置界面
          Mac:CMD + ,
          Windows:Ctrl + ,

          選上這個配置項:

          其實...,你又想了,IDE 整合了 Prettier 也不是很方便,能不能提交代碼的時候自動執(zhí)行格式化?這樣的話,我平時寫代碼根本不需要關(guān)心啥格式了,保證入庫的代碼讓 Code Review 的人別罵我就好。下面咱們就看看怎么樣讓 Git 在 Commit 前先執(zhí)行 Prettier。

          5.Git 整合

          既然要和 Git 整合,首先確保你當前的工程在用 Git。

          和 Git 整合,有四種方法:

          • lint-staged,
          • pretty-quick
          • pre-commit
          • precise-commits

          其中除了 pre-commit 之外,都是 npm 的 module,需要先 npm install ...。我們只介紹 lint-staged 用法。當你需要 Prettier 和其他 Linters 一起用的時候,也用 lint-staged。

          先 npm install 吧:

          // 先別運行這兩行,下面會有更簡單的辦法
          npm install husky
          npm install lint-staged

          其實,更簡單的操作是運行下面這一行:

          // 這一行就可以安裝husky和lint-stage,并且配置好husky。
          npx mrm lint-staged

          husky[7],你沒猜錯就是哈士奇的英文。

          二哈在這里的作用就是咬住 Git 的hooks[8]不放。我們這里只關(guān)心 pre-commit 這一個 hook。

          mrm 之后,你的 package.json 多了這些內(nèi)容:

          "devDependencies": {
              "husky""^3.0.5",
              "lint-staged""^9.2.5"
            },
            "husky": {
              "hooks": {
                "pre-commit""lint-staged"
              }
            },
            "lint-staged": {
              "*.{js,css,json,md}": [
                "prettier --write",
                "git add"
              ]
            }

          現(xiàn)在你可以修改 js、css、json、md 文件,把他們搞亂!然后 git add .,然后再 git commit \-m 'Test Prettier'試試了。

          我現(xiàn)在正在用 Markdown 寫這篇文章,Prettier 也能幫我格式化。

          Prettier 和 IDE 以及 Git 都整合的很好,幫助我們自動格式化了代碼。這時候你又有新的疑問了:Prettier 和已有的各種 Linters 是什么關(guān)系?以前一直用 JSLint 或 TSLint,甚至還會用到 StyleLint。現(xiàn)在 Prettier 支持 JS、TS、CSS,能夠自動重新格式化這些代碼,還有必要用各種 Linters 嗎?如果 Prettier 和 ESLint/TSLint 一起用又會怎么樣呢?

          6.Prettier 和各種 Linters 是什么關(guān)系?如何配合使用?

          各種 Linters 是按照規(guī)則(Rules)去檢查代碼的,遇到不符合規(guī)則的代碼就會提示你,有的規(guī)則還能自動幫你解決沖突。

          這些規(guī)則分為兩類:

          • Formatting rules

          例如 ESlint 的max-len[9]規(guī)則,設置單行長度不能超過 80 字符。
          incorrect code:

          /*eslint max-len: ["error", { "code": 80 }]*/

            var foo = { "bar""This is a bar.""baz": { "qux""This is a qux" }, "difficult""to read" };

          correct code:

          JavaScript   /eslint max-len: ["error", { "code": 80 }]/
          var foo = {
          "bar": "This is a bar.",
          "baz": { "qux": "This is a qux" },
          "easier": "to read"
          };

          再例如 ESLint 的keyword-spacing[10]規(guī)則,關(guān)鍵字前后必須有空格。
          incorrect code:

          JavaScript   /eslint keyword-spacing: ["error", { "before": true }]/
          if (foo) {
          //...
          }else if (bar) {
          //...
          }else {
          //...
          }

          correct code:

          JavaScript   /eslint keyword-spacing: ["error", { "before": true }]/   /eslint-env es6/
          if (foo) {
          //...
          } else if (bar) {
          //...
          } else {
          //...
          }

          當 ESLint 遇到上面的 incorrect code 的時候,會提示你違反規(guī)則,讓你修改代碼以符合規(guī)則。

          而 Prettier 則不會這么麻煩,它根本不管你之前符不符合什么規(guī)則,都先把你的代碼解析成 AST,然后按照它自己的風格給你重新輸出代碼。

          換句話說,Prettier 對應的是各種 Linters 的 Formatting rules 這一類規(guī)則。而且你用了 Prettier 之后,就不會再違反這類規(guī)則了!不需要你自己手動修改代碼。

          • Code-quality rules

          例如 ESLint 的no-unused-vars[11]規(guī)則,不允許沒用的變量定義出現(xiàn)。

          incorrect code:

          /*eslint no-unused-vars: "error"*/
          /*global some_unused_var*/

          // It checks variables you have defined as global
          some_unused_var = 42;

          var x;

          // Write-only variables are not considered as used.
          var y = 10;
          y = 5;

          // A read for a modification of itself is not considered as used.
          var z = 0;
          z = z + 1;

          // By default, unused arguments cause warnings.
          (function(foo) {
          return 5;
          })();

          // Unused recursive functions also cause warnings.
          function fact(n) {
          if (n < 2) return 1;
          return n * fact(n - 1);
          }

          // When a function definition destructures an array, unused entries from the array also cause warnings.
          function getY([x, y]) {
          return y;
          }

          correct code:

          /*eslint no-unused-vars: "error"*/

          var x = 10;
          alert(x);

          // foo is considered used here
          myFunc(function foo() {
          // ...
          }.bind(this));

          (function(foo) {
          return foo;
          })();

          var myFunc;
          myFunc = setTimeout(function() {
          // myFunc is considered used
          myFunc();
          }, 50);

          // Only the second argument from the descructured array is used.
          function getY([, y]) {
          return y;
          }

          Prettier 對這類規(guī)則束手無策。而且這類規(guī)則也正是各種 Linters 的重點,因為它們真的能幫你發(fā)現(xiàn)很多低級的 Bug。

          所以,Prettier 并不會取代各種 Linters,而是能避免你的代碼和這些 Linters 定義的 Formatting rules 沖突。Linters 檢查出來違反 Code-quality rules 的情況后還需要你自己根據(jù)業(yè)務邏輯和語法手動修改。Prettier 幫你格式化代碼,但是不會幫你挑出潛在的錯誤。

          那么既要讓 Prettier 幫你格式化代碼,還想讓 Linters 幫你挑出潛在的 Code-quality 類錯誤,怎么辦?就需要 Prettier 和 Linters 配合使用。

          Prettier 和 Linters 的整合需要做兩件事:

          1. 禁用 Linters 自己的 Formatting rules,讓 Prettier 接管這些職責。這些配置有現(xiàn)成的 Config,Linters 的配置繼承這個 Config 就可以了。
          2. 讓 Linters 執(zhí)行時首先能夠調(diào)用 Prettier 格式化帶啊,然后再檢查 Code-quality 類規(guī)則。這是 由 Linters 的 Plugin 實現(xiàn)的。

          具體去看 Prettier 的文檔[12]

          7.配置

          最后一節(jié),咱們開始說 Prettier 的配置項。

          Prettier 反復強調(diào)自己是一個 Opinionated code formatter,而且只有 few(很少) options。這意味著:

          Prettier 不是一個你想如何設置就如何設置的代碼風格格式化工具,不能任由你改變其輸出風格。其最主要的目的就是讓團隊停止爭吵,配置項越多,就離這個主要目的越遠,團隊就會一直討論應該如何配置。這就是 Prettier 的哲學,而且廣受歡迎。

          在 Prettier 的 Issue 里看這個[13]

          reactjs 團隊成員,Redux 和 Create React App 的合作者發(fā)表了自己的觀點:反對繼續(xù)增加配置項

          就已有的配置項,Prettier 官方都明確說了其中很多都不是他們想要的,是迫不得已加上的。

          之前說到 AST 的時候用了一下 Playground,這些配置在Playground[14]里很容易看到和測試。全部配置項文檔在這里[15]

          最近在發(fā)現(xiàn)有人寫了一個專門的配置工具[16]

          prettier-eslint

          這個工具有兩種用法:

          // 創(chuàng)建工程初始化的時候用
          npm init prettier-eslint
          // 或直接使用
          npx create-prettier-eslint

          另外補充一點,TSLint已經(jīng)不再維護了,明年起將停止更新。前端代碼不管TS還是ES,都用ESLint吧。具體看作者在Medium上的Blog[17]相關(guān)Issue[18]

          如果覺得這篇文章還不錯
          點擊下面卡片關(guān)注我
          來個【分享、點贊、在看】三連支持一下吧

             “分享、點贊在看” 支持一波 

          參考資料

          [1]

          Style Guide: https://link.zhihu.com/?target=https%3A//angular.io/guide/styleguide

          [2]

          http://expressjs.com: https://link.zhihu.com/?target=http%3A//expressjs.com

          [3]

          這篇文章: https://link.zhihu.com/?target=https%3A//learnwebtutorials.com/comparison-react-angular-vue-frameworks

          [4]

          這里: https://link.zhihu.com/?target=https%3A//github.com/jhipster/prettier-java

          [5]

          Playground: https://link.zhihu.com/?target=https%3A//prettier.io/playground

          [6]

          Prettier Extention: https://link.zhihu.com/?target=https%3A//marketplace.visualstudio.com/items%3FitemName%3Desbenp.prettier-vscode

          [7]

          husky: https://link.zhihu.com/?target=https%3A//github.com/typicode/husky

          [8]

          hooks: https://link.zhihu.com/?target=https%3A//githooks.com/

          [9]

          max-len: https://link.zhihu.com/?target=http%3A//eslint.org/docs/rules/max-len

          [10]

          keyword-spacing: https://link.zhihu.com/?target=http%3A//eslint.org/docs/rules/keyword-spacing

          [11]

          no-unused-vars: https://link.zhihu.com/?target=http%3A//eslint.org/docs/rules/no-unused-vars

          [12]

          文檔: https://link.zhihu.com/?target=https%3A//prettier.io/docs/en/integrating-with-linters.html

          [13]

          這個: https://link.zhihu.com/?target=https%3A//github.com/prettier/prettier/issues/40

          [14]

          Playground: https://link.zhihu.com/?target=https%3A//prettier.io/playground

          [15]

          這里: https://link.zhihu.com/?target=https%3A//prettier.io/docs/en/options.html

          [16]

          工具: https://link.zhihu.com/?target=https%3A//github.com/leggsimon/create-prettier-eslint

          [17]

          Medium上的Blog: https://link.zhihu.com/?target=https%3A//medium.com/palantir/tslint-in-2019-1a144c2317a9

          [18]

          相關(guān)Issue: https://link.zhihu.com/?target=https%3A//github.com/palantir/tslint/issues/4534


          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲一级视频在线 | 91女人18毛片水多的意思 | 毛片基地操逼视频 | 搡老熟女大熟了88AV一区二区 | 天天操天天狠 |