您現在的位置是:首頁 > 垂釣

Prettier看這一篇就行了

  • 由 酷扯兒 發表于 垂釣
  • 2021-09-06
簡介target=https%3Aprettier

爾的結構是什麼意思

「來源: |前端技術江湖 ID:bigerfe」

作者:陳龍

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

已獲取作者授權,請勿未經允許轉載。

0。前言

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

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

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

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

為什麼要出現這個新東西?之前同類或類似的東西有什麼不好嗎?

這個東西帶來哪些新思想和設計哲學,解決了之前哪些不容易解決的問題?

發明人對我們有什麼建議,可以讓我們更好地利用這個東西?

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

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

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

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

這篇文件就算是我在第 3 階段之後的一篇總結,分享給大家。

1。為什麼用 Prettier?程式碼風格最不好管理的地方在哪裡?

程式碼風格是所有程式設計師都要遇到的問題,不管是團隊協作還是個人練習。就連不懂開發的老闆都會裝逼一下,強調一定要注意程式碼風格。往往很多公司想到提高程式碼質量和開發效率,首先就想到從程式碼風格入手。

但現實中卻很少看到程式碼風格管理很好的團隊。因為在大多數時候,程式碼風格起於討論,也止於討論,虎頭蛇尾有始無終。

無法確定一個讓所有人都滿意的方案,就很難執行下去

就算勉強少數人服從了大多數,但在實際開發過程中還會遇到各種各樣的問題。例如不同開發人員用不同的 IDE,用相同 IDE 的又因為設定不同預設的縮排也不同。自己又懶得去設定,或者不會設定,最後就亂了。好不容易實現了功能,每次程式碼審查前還要手動去修改這些細節的東西,實在頭疼。那如何解決呢?

針對這種情況的辦法,我國政府早就鄭重提出了:

擱置爭議,共同開發

。吵來吵去,大家各自還為石油頭疼。放著寶貴的資源在海底,看著中東那幫傢伙發財,太傻了。

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

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

opinionated

咱們在下一節詳細講。

2。什麼是 Prettier?

Prettier 在自己官網首頁列出這麼三點:

An opinionated code formatter

Supports many languages

Integrates with most editors

Has few options

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

什麼是 Opinionated?我在知乎很多回答中都提到這個詞,對於理解框架或技術非常重要。很多框架在文件開始就會告訴你它是

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 伺服器端開發的同學,開啟 Spring Boot 的文件:

Prettier看這一篇就行了

熟悉 Node 開發的同學,開啟 http://expressjs。com[2]:

Prettier看這一篇就行了

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

Angular 其實是 Opinionated,規定了你的程式碼結構,讓你最好按照它給你指定的方式組織程式碼。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 “libraries”。 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,就是說:你必須認同我的觀點,按照我說的做。否則你就別用我,硬著頭皮用就會處處不爽!

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

Prettier看這一篇就行了

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

Prettier看這一篇就行了

圖中右側的是 Community Plugins,其中包含我比較關心的 Java。但是 Java 支援的並不好。Java Plugin 是我一直推廣的 jHipster 團隊開發的,Github 倉庫地址在這裡[4],處於 Alpha 階段,而且 JHipster 自己也沒有正式使用。

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

Prettier看這一篇就行了

我會在後面章節給出 Webstorm 和 VSCode 的配置和使用方法。

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

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

Prettier 的原理非常簡單:

不管你寫的程式碼是個什麼鬼樣子,Prettier 會去掉你程式碼裡的所有樣式風格,然後用統一固定的格式重新輸出。輸出時基本上只考慮一個引數,就是 line length。

例如你寫的這行程式碼:

foo(arg1, arg2, arg3, arg4);

一行裝得下這麼多程式碼,所以就不需要改。

如果你寫了下面程式碼:

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

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

foo(

reallyLongArg(),

omgSoManyParameters(),

IShouldRefactorThis(),

isThereSeriouslyAnotherOne()

);

咱們再仔細探究一下這個過程。不管你之前寫的程式碼是什麼樣,首先必須符合語法規範。Prettier 先把你的程式碼轉換成一種中間狀態,叫 AST(Abstract Syntax Tree)。

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

Prettier看這一篇就行了

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

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目錄下建立index。js檔案,然後自己寫一些JS程式碼。JS程式碼用上文那個超長的foo(……)就可以,自己也可以改的更亂一些,但必須符合JS語法。

npx prettier ——write src/index。js

// 在看格式化之後的index。js,已經重新輸出成固定格式了。

Yarn

mkdir learn-prettier && cd learn-prettier

yarn init

yarn add prettier ——dev ——exact

// 在learn-prettier/src目錄下建立index。js檔案,然後自己寫一些JS程式碼。JS程式碼用上文那個超長的foo(……)就可以,自己也可以改的更亂一些,但必須符合JS語法。

yarn prettier ——write src/index。js

// 在看格式化之後的index。js,已經重新輸出成固定格式了。

npm init 命令會問你一些問題,以便於生成 package。json,一路回車採用預設值就行。

你也可以把 package。json 內容改改,改的亂一些,但要符合 JSON 格式。然後執行下面命令看看 package。json 也被重新輸出了:

npx prettier ——write package。json

其實。。。,你也知道,很少有人會透過命令列用,現在大家都用 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

Prettier看這一篇就行了

手動格式化

快捷方式:

最直接方式

Mac:Alt + Shift + Cmd + P

Windows: Alt + Shift + Ctrl + P

或 Mac:CMD + Shit + A

Windows:Ctrl + Shift + A,然後輸入 Prett。。。

或 Double Shift(連按兩次 Shift),然後選擇 Action,然後輸入 Prett。。。

Prettier看這一篇就行了

上面的方式就是執行了npx prettier \——write或yarn prettier \——write,可以格式化檔案、資料夾下的所有檔案、或選中的一段程式碼。

儲存檔案時自動格式化

如果想在儲存檔案的時候自動讓 Prettier 格式化程式碼,需要 File Watcher。

Prettier看這一篇就行了

點+,然後選擇 Prettier。

Prettier看這一篇就行了

VS Code

安裝Prettier Extention[6]

手動格式化

快捷方式:

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

Prettier看這一篇就行了

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

Prettier看這一篇就行了

點選 Configure。。。

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

Prettier看這一篇就行了

選擇 Prettier 就可以了。這時候 settings。json 會增加下面內容:

Prettier看這一篇就行了

javascript 和 typescript 的預設 Formmater 用哪個 Extension。當然這需要你在。js 和。ts 檔案上分別設定一次才可以產生上面的設定。

儲存檔案時自動格式化

開啟 VS Code 的設定介面

Mac:CMD + ,

Windows:Ctrl + ,

選上這個配置項:

Prettier看這一篇就行了

其實。。。,你又想了,IDE 整合了 Prettier 也不是很方便,能不能提交程式碼的時候自動執行格式化?這樣的話,我平時寫程式碼根本不需要關心啥格式了,保證入庫的程式碼讓 Code Review 的人別罵我就好。下面咱們就看看怎麼樣讓 Git 在 Commit 前先執行 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],你沒猜錯就是哈士奇的英文。

Prettier看這一篇就行了

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

mrm 之後,你的 package。json 多了這些內容:

“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”

}

現在你可以修改 js、css、json、md 檔案,把他們搞亂!然後 git add 。,然後再 git commit \-m ‘Test Prettier’試試了。

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

Prettier看這一篇就行了

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

6。Prettier 和各種 Linters 是什麼關係?如何配合使用?

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

這些規則分為兩類:

Formatting rules

例如 ESlint 的max-len[9]規則,設定單行長度不能超過 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]規則,關鍵字前後必須有空格。

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 的時候,會提示你違反規則,讓你修改程式碼以符合規則。

而 Prettier 則不會這麼麻煩,它根本不管你之前符不符合什麼規則,都先把你的程式碼解析成 AST,然後按照它自己的風格給你重新輸出程式碼。

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

Code-quality rules

例如 ESLint 的no-unused-vars[11]規則,不允許沒用的變數定義出現。

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 對這類規則束手無策。而且這類規則也正是各種 Linters 的重點,因為它們真的能幫你發現很多低階的 Bug。

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

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

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

禁用 Linters 自己的 Formatting rules,讓 Prettier 接管這些職責。這些配置有現成的 Config,Linters 的配置繼承這個 Config 就可以了。

讓 Linters 執行時首先能夠呼叫 Prettier 格式化帶啊,然後再檢查 Code-quality 類規則。這是 由 Linters 的 Plugin 實現的。

具體去看 Prettier 的文件[12]。

7。配置

最後一節,咱們開始說 Prettier 的配置項。

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

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

在 Prettier 的 Issue 裡看這個[13]:

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

Prettier看這一篇就行了

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

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

最近在發現有人寫了一個專門的配置工具[16]:

prettier-eslint

這個工具有兩種用法:

// 建立工程初始化的時候用

npm init prettier-eslint

// 或直接使用

npx create-prettier-eslint

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

參考資料

[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]

相關Issue: https://link。zhihu。com/?target=https%3A//github。com/palantir/tslint/issues/4534

The End

歡迎自薦投稿到《前端技術江湖》,如果你覺得這篇內容對你挺有啟發,記得點個

「在看」

Top