prettier使用指南
01.什么是prettier
prettier是一個代碼格式化工具,支持下列編程語言的代碼格式化
- JavaScript (including experimental features)
- JSX
- Angular
- Vue
- Flow
- TypeScript
- CSS, Less, and SCSS
- HTML
- JSON
- GraphQL
- Markdown, including GFM and MDX
- YAML
和其他lint工具比如eslint的區別
prettier的配置項比較少(容易配置),且只專注于代碼樣式,而eslint還提供語法檢查,現在的eslint也集成了formatter功能。
prettier相比eslint支持更多文件的格式化。
02.使用方法
安裝
在項目中,安裝到開發依賴上
npm install --save-dev --save-exact prettier
忽略不想格式化的文件
創建 .prettierignore忽略你不希望格式化的文件,node_modules是默認會被忽略的目錄。
他的用法就類似于.gitignore
,下面是官方給的例子
# Ignore artifacts:
build
coverage
命令行執行格式化
在項目中手動調用prettier命令行進行格式化
npx prettier --write .
提前查看會格式化哪些文件,不實際執行格式化
npx prettier --check .
實際使用過程中,還是直接用編輯器的插件的,設置成保存的時候執行格式化。
解決和eslint的沖突
安裝 eslint-config-prettier,這個插件會把eslint中可能導致沖突的規則關掉,這樣兩者就能兼容使用了。
git hooks
可以設置在git提交之前執行一次格式化( pre-commit hook ),這樣我們倉庫里的代碼就都是格式化好的了。
只需要在package.json里面加入一些配置。
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"**/*": "prettier --write --ignore-unknown"
}
}
如果你使用eslint,請確保lint-staged里,eslint的執行順序放在前面
需要安裝husky 和 lint-staged這兩個依賴才能實現,其中husky是幫助我們添加git hooks的工具,而lint-staged則是篩選那些staged的git文件執行lint。
執行npx mrm lint-staged
就會把兩個工具都安裝好。
用注釋忽略格式化代碼
// prettier-ignore
注釋會忽略抽象語法樹下一行代碼的格式化
舉個例子
matrix(
1, 0, 0,
0, 1, 0,
0, 0, 1
)
// prettier-ignore
matrix(
1, 0, 0,
0, 1, 0,
0, 0, 1
)
執行prettier格式化后:
matrix(1, 0, 0, 0, 1, 0, 0, 0, 1);
// prettier-ignore
matrix(
1, 0, 0,
0, 1, 0,
0, 0, 1
)
JSX中的注釋
<div>
{/* prettier-ignore */}
<span ugly format='' />
</div>
HTML中的注釋
<!-- prettier-ignore -->
<div class="x" >hello world</div >
<!-- prettier-ignore-attribute -->
<div
(mousedown)=" onStart ( ) "
(mouseup)=" onEnd ( ) "
></div>
<!-- prettier-ignore-attribute (mouseup) -->
<div
(mousedown)="onStart()"
(mouseup)=" onEnd ( ) "
></div>
CSS中的注釋
/* prettier-ignore */
.my ugly rule
{
}
MarkDown中的注釋
<!-- prettier-ignore -->
Do not format this
忽略一定范圍的代碼
available in v1.12.0+
通常實在文件頂部使用來取消一些自動生成內容的格式化
比如markdown里的toc和表格等
<!-- prettier-ignore-start -->
<!-- SOMETHING AUTO-GENERATED BY TOOLS - START -->
| MY | AWESOME | AUTO-GENERATED | TABLE |
|-|-|-|-|
| a | b | c | d |
<!-- SOMETHING AUTO-GENERATED BY TOOLS - END -->
<!-- prettier-ignore-end -->
YAML
# prettier-ignore
key : value
hello: world
GraphQL
{
# prettier-ignore
addReaction(input:{superLongInputFieldName:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {
reaction {content}
}
}
Handlebars
{{! prettier-ignore }}
<div>
"hello! my parent was ignored"
{{#my-crazy-component "shall" be="preserved"}}
<This
is = "also preserved as is"
/>
{{/my-crazy-component}}
</div>
03.使用配置文件進行配置
最推薦的使用方式是使用配置文件。
prettier支持的配置文件的優先級如下,它使用 cosmiconfig提供配置文件支持的:
- A
"prettier"
key in yourpackage.json
file. - A
.prettierrc
file written in JSON or YAML. - A
.prettierrc.json
,.prettierrc.yml
,.prettierrc.yaml
, or.prettierrc.json5
file. - A
.prettierrc.js
,.prettierrc.cjs
,prettier.config.js
, orprettier.config.cjs
file that exports an object usingmodule.exports
. - A
.prettierrc.toml
file.
這里我使用 .prettierrc.js
來配置,因為偏好json那種風格的配置文件,但是json有個最大的問題是不支持注釋。所以我這里用了js,把每一項都寫上了注釋,方便以后改的時候查看。
vscode讀取這種單獨配置文件的優先級會高于插件內配置。
可配置選項
module.exports = {
// 1.一行代碼的最大字符數,默認是80(printWidth: <int>)
printWidth: 80,
// 2.tab寬度為2空格(tabWidth: <int>)
tabWidth: 2,
// 3.是否使用tab來縮進,我們使用空格(useTabs: <bool>)
useTabs: false,
// 4.結尾是否添加分號,false的情況下只會在一些導致ASI錯誤的其工況下在開頭加分號,我選擇無分號結尾的風格(semi: <bool>)
semi: false,
// 5.使用單引號(singleQuote: <bool>)
singleQuote: true,
// 6.object對象中key值是否加引號(quoteProps: "<as-needed|consistent|preserve>")as-needed只有在需求要的情況下加引號,consistent是有一個需要引號就統一加,preserve是保留用戶輸入的引號
quoteProps: 'as-needed',
// 7.在jsx文件中的引號需要單獨設置(jsxSingleQuote: <bool>)
jsxSingleQuote: false,
// 8.尾部逗號設置,es5是尾部逗號兼容es5,none就是沒有尾部逗號,all是指所有可能的情況,需要node8和es2017以上的環境。(trailingComma: "<es5|none|all>")
trailingComma: 'es5',
// 9.object對象里面的key和value值和括號間的空格(bracketSpacing: <bool>)
bracketSpacing: true,
// 10.jsx標簽多行屬性寫法時,尖括號是否另起一行(jsxBracketSameLine: <bool>)
jsxBracketSameLine: false,
// 11.箭頭函數單個參數的情況是否省略括號,默認always是總是帶括號(arrowParens: "<always|avoid>")
arrowParens: 'always',
// 12.range是format執行的范圍,可以選執行一個文件的一部分,默認的設置是整個文件(rangeStart: <int> rangeEnd: <int>)
rangeStart: 0,
rangeEnd: Infinity,
// 18. vue script和style標簽中是否縮進,開啟可能會破壞編輯器的代碼折疊
vueIndentScriptAndStyle: false,
// 19. endOfLine: "<lf|crlf|cr|auto>" 行尾換行符,默認是lf,
endOfLine: 'lf',
// 20.embeddedLanguageFormatting: "off",默認是auto,控制被引號包裹的代碼是否進行格式化
embeddedLanguageFormatting: 'off',
}
// 14. requirePragma: <bool>,格式化有特定開頭編譯指示的文件 比如下面兩種
/**
* @prettier
*/
// or
/**
* @format
*/
// 15.insertPragma: <bool> 自當插入pragma到已經完成的format的文件開頭
// 16. proseWrap: "<always|never|preserve>" 文章換行,默認情況下會對你的markdown文件換行進行format會控制在printwidth以內
// 13. 指定parser,因為pretter會自動選擇,所以一般不用指定(parser: "<string>" parser: require("./my-parser"))
// "babel" (via @babel/parser) Named "babylon" until v1.16.0
// "babel-flow" (same as "babel" but enables Flow parsing explicitly to avoid ambiguity) First available in v1.16.0
// "babel-ts" (similar to "typescript" but uses Babel and its TypeScript plugin) First available in v2.0.0
// "flow" (via flow-parser)
// "typescript" (via @typescript-eslint/typescript-estree) First available in v1.4.0
// "espree" (via espree) First available in v2.2.0
// "meriyah" (via meriyah) First available in v2.2.0
// "css" (via postcss-scss and postcss-less, autodetects which to use) First available in v1.7.1
// "scss" (same parsers as "css", prefers postcss-scss) First available in v1.7.1
// "less" (same parsers as "css", prefers postcss-less) First available in v1.7.1
// "json" (via @babel/parser parseExpression) First available in v1.5.0
// "json5" (same parser as "json", but outputs as json5) First available in v1.13.0
// "json-stringify" (same parser as "json", but outputs like JSON.stringify) First available in v1.13.0
// "graphql" (via graphql/language) First available in v1.5.0
// "markdown" (via remark-parse) First available in v1.8.0
// "mdx" (via remark-parse and @mdx-js/mdx) First available in v1.15.0
// "html" (via angular-html-parser) First available in 1.15.0
// "vue" (same parser as "html", but also formats vue-specific syntax) First available in 1.10.0
// "angular" (same parser as "html", but also formats angular-specific syntax via angular-estree-parser) First available in 1.15.0
// "lwc" (same parser as "html", but also formats LWC-specific syntax for unquoted template attributes) First available in 1.17.0
// "yaml" (via yaml and yaml-unist-parser) First available in 1.14.0
// 17. htmlWhitespaceSensitivity: "<css|strict|ignore>" html中的空格敏感性
// 針對不同文件或目錄設置不同配置的方法,json格式例子
// {
// "semi": false,
// "overrides": [
// {
// "files": "*.test.js",
// "options": {
// "semi": true
// }
// },
// {
// "files": ["*.html", "legacy/**/*.js"],
// "options": {
// "tabWidth": 4
// }
// }
// ]
// }
下面是精簡版本,默認配置在我這里需要修改的只有兩個選項
-
semi,行末是否加分號,有以下幾個原因讓我選擇false
- 我主要使用的vue他的代碼風格就是不加分號的,不加分號代碼也能正常運行(因為編譯器是自動給你加分號執行的),只需要注意幾個會出問題的點。
- 加分號會增加文件大小,寫代碼和刪代碼都需要多按麻煩
- 我常用的其他語言,比如go,python和powershell也可以不用分號
使用單引號而不是雙引號,同理,vue的代碼風格使用的是單引號,很多js代碼風格都是使用單引號
module.exports = {
semi: false,
singleQuote: true,
}
關于js使用單引號的好處,為什么不用雙引號
首先,雙引號其實是c語言(類c++的java,c#都是這樣)帶來的強迫癥,c語言用單引號表示單個字符,雙引號表示字符串,c語言區分這兩個我猜是因為要斤斤計較內存的使用的緣故,編譯的時候給單個字符內存分配和給字符串內存分配的占用是不同的。但是在js,python這些語言里面,單引號雙引號都可以用字符串,就沒必要一定遵循這個強迫癥了。
shell和powershell這兩種語言里面用單引號表示純字符串,雙引號則是可以添加變量的字符串。因為這兩種腳本也是比較常用的,為了統一,干脆所有字符串統一用單引號,雙引號留著都不用,比如powershell腳本里面我也不用雙引號,而是用format來格式化字符串。
用單引號可以少按一個shift,方便一些
html中用的是雙引號,所以js區分一下,用單引號。
其他默認的配置符合我使用習慣的也有可以討論的:
關于tab用幾個空格的討論我選擇用兩個空格。
一般兩個空格就是最小的縮進了,2個空格和4個空格應該是主流的兩種。在前端項目里面一般是兩個空格。有以下的原因吧:
- js語言回調函數之類嵌套的場景比較多,如果用4空格縮進會占用過多的空間,2空格就比較緊湊。
- 2空格輸入和刪除都更方便(雖然我都是用tab輸出2空格),方便修改
缺點也是比較緊湊,看著容易累。
針對特定文件覆蓋配置
把官方的例子搬了過來。這樣就能針對不同文件進行配置了。
{
"semi": false,
"overrides": [
{
"files": "*.test.js",
"options": {
"semi": true
}
},
{
"files": ["*.html", "legacy/**/*.js"],
"options": {
"tabWidth": 4
}
}
]
}