Prettier 代码格式化插件 -- 配置翻译

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文地址

1. 简介:

一款 Opinionated「预设立场型」的代码格式化工具,支持以下语言:

题外:Opinionated 这个词我反复斟酌,实在不知如何翻译才好。即使是英文中大家讨论的也很激烈,非一句半句说的清楚,可以看看参考链接。在 FCC 群请教过,有位前辈回复我 「预设立场型」软件。我觉得翻译的很好。

如果你这样写:

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

Prettier 会帮你格式化成:

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


2. 安装

yarn

yarn add prettier --dev --exact
# or globally
yarn global add prettier

npm

npm install --save-dev --save-exact prettier
# or globally
npm install --global prettier

IDE 安装直接在 plugin market 搜索 Prettier,参考https://www.jianshu.com/p/0ada1096be5a


3. 不需要格式化的文件或者代码,该怎样标识?

3.1 Ignoring Files 标识无需格式化的文件比较简单:

项目根目录下创建 .prettierignore 文件,和 .gitignore 相似。然后直接添加文件名即可:
task_form.html

这也是翻译官文的原因。目前项目有个文件引用的 layui, 格式化前:

<select name="level" id="level" lay-verify="required" {{{if .Task}}}disabled="disabled" {{{end}}} class="selece_greg">
  <option value="1" {{{if .Task}}} {{{if eq .Task.Level 1}}}selected{{{end}}} {{{end}}}>主任务</option>
  <option value="2" {{{if .Task}}} {{{if eq .Task.Level 2}}}selected{{{end}}} {{{end}}}>子任务</option>
</select>

格式化后:

<select
              name="level"
              id="level"
              lay-verify="required"
              {{{if
              .Task}}}disabled="disabled"
              {{{end}}}
              class="selece_greg"
            >
              <option
                value="1"
                {{{if
                .Task}}}
                {{{if
                eq
                .Task.Level
                1}}}selected{{{end}}}
                {{{end}}}
                >主任务</option
              >
              <option
                value="2"
                {{{if
                .Task}}}
                {{{if
                eq
                .Task.Level
                2}}}selected{{{end}}}
                {{{end}}}
                >子任务</option
              >
            </select>

这样本身已经没有美观可言了,要命的是项目启动报错,指说这个文件有标签没有闭合。一查官文还真有这种操作呢,可以忽略格式化某些文件或者行。

3.2 标识忽略格式化的代码,需要添加注释 prettier-ignore,例:

3.2.1 JS
matrix(
  1, 0, 0,
  0, 1, 0,
  0, 0, 1
)

// prettier-ignore
matrix(
  1, 0, 0,
  0, 1, 0,
  0, 0, 1
)

格式化后:

matrix(1, 0, 0, 0, 1, 0, 0, 0, 1);

// prettier-ignore
matrix(
  1, 0, 0,
  0, 1, 0,
  0, 0, 1
)
3.2.2 JSX
<div>
  {/* prettier-ignore */}
  <span     ugly  format=''   />
</div>
3.2.3 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>
3.2.4 CSS
/* prettier-ignore */
.my    ugly rule
{

}
3.2.5 Markdown
<!-- prettier-ignore -->
Do   not    format   this
3.2.6 Range Ignore 有范围的注释(v1.12.0+ 支持)

这种方式只适用于 top-level 和自动生成代码的内容,比如 all-contributors, 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 -->
3.2.7 GraphQL
{
  # prettier-ignore
  addReaction(input:{superLongInputFieldName:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {
    reaction {content}
  }
}


4. 配置项

4.1 Print Width 即 Line Width,排版宽度即每行最大宽度。默认值是 80。

默认 CLI 重写定义 API 重写定义
80 --print-width <int> printWidth: <int>

注:如果想在 Markdown 文件中禁用折行功能,可以在 Prose Wrap 中配置。

4.2 Tab Width

制表符宽度,每个层级缩进几个空格。默认值 2

默认 CLI 重写定义 API 重写定义
2 --tab-width <int> tabWidth: <int>

4.3 Tabs

是否使用 tab 代替 space(空格) 为单位缩进,默认 false

默认 CLI 重写定义 API 重写定义
false --use-tabs useTabs: <bool>

4.4 Semicolons

分号,句尾是否自动补全“分号”,默认 true

  • true 为每个 statement 末尾都添加分号
  • false 只为会引起 ASI Failure 语句的开始行添加分号
默认 CLI 重写定义 API 重写定义
true --no-semi semi: <bool>

4.5 Quotes

默认 false,启用双引号,不启用单引号。Prettier 会默认把单引号变成双引号。

注:

  • JSX 会忽略此配置项 -- 详情 jsx-single-quote
  • 当其中一种引号的使用频率远远大于另一种时,较少使用的那种引号会被用作格式化字符串的引号。 例如:"This \"example\" is single quoted" 会被格式化为'This "example" is single quoted'(因为大部分项目是 "双引号" 居多,所以保存后,整个字符串语句就被 '单引号' 包裹了)

详情请查看 strings rationale

默认 CLI 重写定义 API 重写定义
false --single-quote singleQuote: <bool>

4.6 Quote Props

自定义引号配置:

  • "as-needed" -- 按需添加
  • "consistent" -- 一致原则,即对象中若有一个属性添加了引号,其他所有属性都添加
  • "preserve" -- 遵循原则,遵循输入的引号
默认 CLI 重写定义 API 重写定义
"as-needed" --quote-props <as-needed|consistent|preserve> quoteProps: "<as-needed|consistent|preserve>"

4.7 JSX Quotes

在 JSX 文件中使用单引号代替双引号

默认 CLI 重写定义 API 重写定义
false --jsx-single-quote jsxSingleQuote: <bool>

4.8 Trailing Commas

为多行数组的非末尾行添加逗号(单行数组不需要逗号),配置项:

  • "none" - 不添加逗号
  • "es5" - 在 ES5 中生效的逗号 (对象,数组等等)
  • "all" - 任何可以添加逗号的地方 (包括函数实参). 此配置需要 node 8 或一个 transform 方法。
默认 CLI 重写定义 API 重写定义
none --trailing-comma <none|es5|all> trailingComma: "<none|es5|all>"

4.9 Bracket Spacing

括号空格,在对象字面量和括号之间添加空格,配置项:

  • true - Example: { foo: bar }.
  • false - Example: {foo: bar}.
默认 CLI 重写定义 API 重写定义
true --no-bracket-spacing bracketSpacing: <bool>

4.10 JSX Brackets

Put the > of a multi-line JSX element at the end of the last line instead of being alone on the next line (does not apply to self closing elements).
将多行 JSX 元素的 > 放置于最后一行的末尾,而非换行。例:

  • true
<button
  className="prettier-class"
  id="prettier-id"
  onClick={this.handleClick}>
  Click Here
</button>
  • false
<button
  className="prettier-class"
  id="prettier-id"
  onClick={this.handleClick}
>
  Click Here
</button>
默认 CLI 重写定义 API 重写定义
false --jsx-bracket-same-line jsxBracketSameLine: <bool>

4.11 Arrow Function Parentheses 箭头函数圆括号

v1.9.0 及以上

  • "avoid" - 在可以消除的情况下,消除括号. Example: x => x
  • "always" - 一直保留括号. Example: (x) => x
默认 CLI 重写定义 API 重写定义
"avoid" --arrow-parens <avoid|always> arrowParens: "<avoid|always>"

4.12 Range

区间格式化

两个配置项可以用于「起始」(闭区间)/ 「截止」(开区间) 于某个标识:

  • 包含被选中语句,向上至第一行都是选中的区间
  • 选中区间从该行向下至最后一行

cursorOffset 冲突,不可同时使用。

默认 CLI 重写定义 API 重写定义
0 --range-start <int> rangeStart: <int>
Infinity --range-end <int> rangeEnd: <int>

4.13 Parser

指定使用的解析器

Prettier 可以根据文件路径推断出解析器的类型,因此无需更改此配置项。

babelflow 解析器都支持同一组 JS 特性集(包含 Flow 类型注解). 在某些特殊情况下,有可能会产生差异,当遇到这些情况时,推荐使用 flow 代替 babel.

有效配置项:

  • "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
  • "flow" (via flow-parser)
  • "typescript" (via @typescript-eslint/typescript-estree) First available in v1.4.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

自定义解析器 Custom parsers 亦可支持. First available in v1.5.0

默认 CLI 重写定义 API 重写定义
none --parser <string>
--parser ./my-parser
parser: "<string>"
parser: require("./my-parser")

4.14 File Path

指定文件名称以确认应用何种解析器。
例如,以下会应用 CSS 解析器:

cat foo | prettier --stdin-filepath foo.css
默认 CLI 重写定义 AP I 重写定义
none --stdin-filepath <string> filepath: "<string>"

4.15 Require pragma 编译附注

v1.7.0 及以上支持

Prettier 支持在一个文件的头部设置约束,仅格式化那些包含「特殊注释」的文件,这种约束称为「 pragma 编译附注」。当需要逐步迁移体积较大的且未格式化过的基础代码时,此配置项是很有用处的。

例如,当设置--require-pragma时,文件中第一个注释写成下面这样,该文件将会被格式化:

/**
 * @prettier
 */

/**
 * @format
 */
默认 CLI 重写定义 AP I 重写定义
false --insert-pragma insertPragma: <bool>

4.16 Prose Wrap

v1.8.2 及以上支持

默认情况下,prettier 对于 markdown 文件的段落是执行超出长度换行的。但一些情况下,如果需要设置不换行,可以使用 "never" 这个配置。

有效配置项:

  • "always" - 超出长度自动折行
  • "never" - 用不折行
  • "preserve" - 遵循原有格式. v1.9.0 及以上支持
默认 CLI 重写定义 AP I 重写定义
"preserve" --prose-wrap
<always|never|preserve>
proseWrap:
"<always|never|preserve>"

4.17 HTML Whitespace Sensitivity 空格敏感度

v1.15.0 及以上支持

为 HTML 文件定义全局空格敏感度,详情请查看 whitespace-sensitive formatting

有效配置项:

  • "css" - 遵循 CSS display 属性的默认值
  • "strict" - 严格模式,
  • "ignore" - 忽略模式 Whitespaces are considered insensitive.
默认 CLI 重写定义 AP I 重写定义
"css" --html-whitespace-sensitivity
<css|strict|ignore>
htmlWhitespaceSensitivity:
"<css|strict|ignore>"

4.18 End of Line

1.15.0 及以上

历史原因导致有两种文件行尾处理方式: \n (or LF for Line Feed) 和 \r\n (或 CRLF for Carriage Return + Line Feed)(译者注:这里 LF 和 CRLF 是什么都够一篇文章讨论了,详情查看 理解 CRLF, LF )

LF 常用于 Linux 和 macOS 操作系统,CRLF 常用于 Windows 操作系统。 详情查看 Wikipedia.

默认情况下,Prettier 遵循现有规则,也可以将一个文件的首行末尾作为标准格式化余下的所有行。

如果同一个项目的开发人员使用的是不同的操作系统,git 仓库代码的行尾会出现混乱情况。甚至有可能出现 Windows 用户将已经提交的 LF 误转为 CRLF. 这种情况会引起比较棘手的 git diff,如果没有加以留心则会导致此文件 (git blame) 的行对行历史丢失。

如果想确保由 Prettier 格式化的文件在 git 仓库只保留 Linux 类型的行尾,可以进行以下设置:

  1. 设置配置项 endOfLine 的值为 lf
  2. 配置一个 pre-commit hook 以便 Prettier 顺利运行
  3. 配置 Prettier 使其可以在你的 CI pipeline 中使用 --check flag
  4. Windows 用户在操作 git 仓库之前执行 git config core.autocrlf false,这样 checkout 的时候 git 就不会自动将 LF 转换为 CRLF 了。 另有一种可供选择的解决方案:添加 * text=auto eol=lf 到仓库的 .gitattributes 文件。

如今的文本编辑器都可以纠正 \n (LF) 行尾的显示问题。只有少数比较老旧的 Windows 的 Notepad 有可能无法实现。

Valid options:

  • "auto" - 保持原有规则(如有混合使用,则按照第一行规则格式化其余所有行)
  • "lf" – Line Feed only (\n) 常用语 Linux 和 macOS 操作系统以及 git 仓库
  • "crlf" - Carriage Return + Line Feed characters (\r\n) 常用于 Windows 操作系统
  • "cr" - Carriage Return character only (\r) 使用几率超小超小
默认 CLI 重写定义 AP I 重写定义
"auto" --end-of-line <auto|lf|crlf|cr> endOfLine: "<auto|lf|crlf|cr>"


5. Configuration File 配置文件

Prettier 使用 cosmiconfig 配置方式。 以下任意一种皆可:

  • .prettierrc 文件,YAML 或 JSON 格式,可选扩展名: .yaml/.yml/.json
  • .prettierrc.toml 文件,TOML 格式 (须添加 .toml 扩展名)
  • prettier.config.js.prettierrc.js 文件,导出一个对象
  • package.json 文件添加 "prettier" key

格式化代码时,查找配置文件的顺序是由当前目录项上一层层查找。如果有 config 文件,则按照文件规则格式化。(由此推断,层级越近的配置文件,优先级越高)

配置项参考本文 4.0 内容。

5.1 基础配置

JSON:

{
  "trailingComma": "es5",
  "tabWidth": 4,
  "semi": false,
  "singleQuote": true
}

JS:

// prettier.config.js or .prettierrc.js
module.exports = {
  trailingComma: "es5",
  tabWidth: 4,
  semi: false,
  singleQuote: true
};

YAML:

# .prettierrc or .prettierrc.yaml
trailingComma: "es5"
tabWidth: 4
semi: false
singleQuote: true

TOML:

# .prettierrc.toml
trailingComma = "es5"
tabWidth = 4
semi = false
singleQuote = true

5.2 覆写默认配置

Prettier 采用 eslint 的 覆写格式,以便于为某些特定文件制定特定配置。

JSON:

{
  "semi": false,
  "overrides": [
    {
      "files": "*.test.js",
      "options": {
        "semi": true
      }
    }
  ]
}

YAML:

semi: false
overrides:
  - files: "*.test.js"
    options:
      semi: true

覆写时,files(生效文件) 是必填项,值可以是字符串或者字符串数组。excludeFiles(排除文件) 是选填项,值同样可以是字符串或者字符串数组。

5.3 设置解析器配置项

通常情况下,Prettier 可以根据文件扩展名找到相应的解析器。如果有 Prettier 不识别的文件类型,可以结合覆写功能告诉 Prettier 如何解析。

比如告诉 Prettier 如何格式化 .prettierrc 文件:

{
  "overrides": [
    {
      "files": ".prettierrc",
      "options": { "parser": "json" }
    }
  ]
}

或者从 babel 解析器切换到 flow:

{
  "overrides": [
    {
      "files": "*.js",
      "options": {
        "parser": "flow"
      }
    }
  ]
}

注:parser 解析器配置项不可放置于外层作用于全局的配置文件,仅可应用于覆写。

The End

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容