VSCode格式化,统一代码规范

7/18/2021 VS Code格式化

# 背景

多人协作共同开发一个项目时,由于各自编码风格的差异,项目最终各个模块间的代码风格可能风格各异,这就会导致后序整个项目的维护成本和代价很高。所以,统一团队编码风格就显得尤为重要。这时,我们就需要通过各种各样的代码格式化工具来对开发成员进行约束,保证代码风格的统一。同时也希望通过工具尽可能的减少低级错误的出现。

# 插件比较

# ESLint

ESLint 可以通过定义 rules 和 extends 来引入更多的规则,但只能检查 JS 语法。不能对 Vue 中的 template 或者 React 中的 jsx进行检测。所以ESLint往往需要引入插件来增强自身的检查能力和范围

# Vetur

Vetur是我们能优雅写Vue的核心,支持<template>调用 html 格式化工具,<script>调用 JavaScript 格式化工具,<style>使用样式格式化工具

优点:

  • 集成了prettier
  • 支持*.vue中不同的块使用不同的格式化方案
  • Emmet语法支持
  • 语法错误校验检查
  • 格式化代码
  • 代码提醒
  • 对三方UI框架支持

缺点:

  • 格式化的标准和ESLint会有冲突
  • 只支持整个文档格式化, 不支持选中某个片段格式化

# Prettier

Prettier是近年来使用频率特别高的一款通用前端代码格式化工具,Prettier几乎能完成所有类型代码文件的格式化工作,或者针对markdown这样的文档进行格式化操作。通过Prettier可以很容易的去规范前端项目中的代码风格标准,而且使用也非常简单。

Prettier 在自己的官网首页列出了这么三点:

  • An opinionated code formatter(固执己见的代码格式化工具【言外之意就是你必须认同我的规则,否则别用,哈哈哈】)
  • Supports many languages (支持多种语言)
  • Integrates with most editors (集成大多数IDE)
  • Has few options (少量的配置)

Prettier的原理非常简单,不管你写的代码是什么样子,Prettier 会先把你的代码转换成AST(Abstract Syntax Tree) 或者说语法树,然后根据自己的规则用统一的格式进行重新输出,输出时基本只需要考虑line length。

例如下面这段代码,Prettier就不会对其进行更改

handleClick(a, b, c, d);
1

如果是下面这样的代码

handleClick(stubObject(), runInContext(), partialRight(), matchesProperty());
1

Prettier会将其重新输出为这样

handleClick(
  stubObject(), 
  runInContext(), 
  partialRight(), 
  matchesProperty()
);
1
2
3
4
5
6

它和ESLint的区别在于Prettier是一个专注于代码格式化的工具,对代码不做质量检查。而ESLint作为大名鼎鼎Linters系列中的一员,是按照规则去检查代码的,遇到不符合规则的代码就会提示用户,而有的规则还能自动解决代码冲突

这些规则主要分为两类

当ESLint遇到违反上面规则的代码时,会提示用户违反了规则,让用户修改代码以符合规则。

而Prettier不会这么麻烦,不管之前的代码符不符合什么规则,都会先把代码解析成 AST,然后按照自己的风格重新输出代码。

Prettier 对这类规则束手无策。而这类规则也是 ESLint 的核心设计,正是因为有了这些规则的存在,我们才能发现开发过程中很多低级的 Bug。

综上,Prettier 不会取代 ESLint,而是能避免我们的代码和这些 ESLint 定义的 Formatting rules 冲突。

那么既要让 Prettier 格式化代码,还想让 ESLint 挑出潜在的 Code-quality 错误,就需要 Prettier 和 Linters 配合使用。

# Beautify

Beautify也是一个老牌格式化插件,虽然Star不如Prettier,但在vetur的template还没有很好的支持prettier时,官方推荐使用js-beautify-html。当然Beautify也有缺点,就是对JSX的支持不是太好。如果比较习惯Beautify的格式化风格,也可以选用Beautify。毕竟,萝卜青菜各有所爱。

# Manta's Stylus Supremacy

格式化stylus的插件,主要是把css格式化为stylus风格,如果项目中没有用到stylus的话可以不用装

# 代码风格

  • javascript遵循ESlint规范
  • html、wxml遵循prettyHtml规范
  • javascript/typescript风格
    1. 结尾分号
    2. 超过120个字符换行
    3. 使用单引号
    4. 无尾随逗号
    5. 箭头函数参数只有一个时,不加小括号
    6. 函数声明禁止圆括号前面有空格
    7. 对象、数组、括号与文字之间加空格

# 个性化配置

打开VS Code配置文件setting.json或者快捷键ctrl + shirt + p,搜索Settings,打开文件

{
  // 每次保存是否自动格式化文件
  "editor.formatOnSave": true, 
  // 每次保存的时候将代码按格式进行修复
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  },
  // 针对.vue、.ts 和 .tsx 文件开启 ESLint 的 autoFix
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    “vue”,
    "typescript",
    "typescriptreact"
  ],
  "[javascript]": {
    "editor.defaultFormatter: "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[vue]": {
    "editor.defaultFormatter": "octref.vetur"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[less]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[scss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // 默认使用prettier格式化支持的文件
  "vetur.format.defaultFormatter.js": "prettier",
  "vetur.format.defaultFormatter.html": "prettyhtml",
  // 如果是vue3.0项目可以加入下面这行代码,让ts在template上获得更好的支持
  "vetur.experimental.templateInterpolationService": true,
  "vetur.format.defaultFormatterOptions": {
    "prettier": {
      // 让prettier使用eslint的代码格式进行校验
      "eslintIntegration": true,
      // 缩近字节数
      "tabWidth": 2,
      // 结尾添加分号
      "semi": true,
      // 超过120个字符换行
      "printWidth": 120,
      // 使用单引号
      "singleQuote": true,
      // 无尾随逗号
      "trailingComma": "none",
      // 箭头函数单个参数不加分号
      "arrowParens": "avoid",
      // 在对象,数组括号与文字之间加空格
      "bracketSpacing": true,
    }
  },
  // 缩进字节数
  "prettier.tabWidth": 2,
  "prettier.semi": true,
  "prettier.printWidth": 120,
  "prettier.trailingComma": "none",
  "prettier.singleQuote": true,
  "prettier.arrowParens": "avoid",
  "prettier.bracketSpacing": true,
  "files.associations": {
    "*.cjson": "jsonc",
    "*.wxss": "css",
    "*.wxs": "javascript"
  },
  // 指定wxml的格式化
  "minapp-vscode.wxmlFormatter": "prettyHtml",
  "minapp-vscode.disableAutoConfig": true
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
Last Updated: 11/21/2022, 6:50:20 AM