【前端规范】01.JS代码规范(Eslint + Prettier+Vscode配置)

270 阅读10分钟

1.代码规范配置图

image.png

本文主要介绍Eslint + Prettier+vscode配置,其他规范将在后续文章进行介绍

2.Eslint

Eslint 是一款JavaScript代码静态检查工具,其核心是通过对代码解析得到的 AST(Abstract Syntax Tree,抽象语法树)进行模式匹配,来分析代码达到检查代码质量和风格问题的能力。

ESLint 的使用其实并不复杂。安装相关依赖之后,可以直接使用开源的配置方案,例如eslint-config-airbnbeslint-config-standard。也可以根据个人或团队的代码风格进行配置。配置完成之后,就可以对代码进行静态检查,发现和修复不符合规范的代码,Eslint提供的auto-fix能力也能够帮助我们自动修复一些代码格式问题。

2.1 安装Eslint

手动安装Eslint

yarn add eslint -D

初始化配置

eslint --init

此时项目根目录会生成 .eslintrc.js文件,该文件主要用来进行ESLint的配置。

2.2 进行Eslint配置

2.2.1 Configuration Comments

Configuration Comments - 使用注释把lint规则嵌入到源码中,这种配置方式允许我们使用JavaScript注释把配置信息直接嵌入到一个代码源文件中

/* eslint no-console: "error" */
console.log('this is an eslint rule check!');

当我们运行eslint xxx.js检查上述文件时,就会发现eslint给出报错信息。

2.2.2 Configuration Files

Configuration Files - 使用配置文件进行lint规则配置

除了直接在代码中注释配置信息,Eslint还支持以文件的形式来进行Eslint的配置

  •     JavaScript(.eslintrc.js
  •     YAML(.eslintrc.yaml
  •     JSON(.eslintrc.json
  •     也可以在package.json文件中添加 eslintConfig字段进行配置

通常情况下会以.eslintrc.js的形式进行配置,默认的配置如下:

module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: ["plugin:vue/essential""eslint:recommended""@vue/prettier"],
  parserOptions: {
    parser: "babel-eslint",
  },
  rules: {
    "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
    "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
  },
};

2.3 具体配置Eslint

主要的配置参数如下:

  • parser
  • parserOptions
  • env
  • global
  • rules
  • plugins
  • extends
  • overrides
2.3.1 parser

Eslint 默认使用Espreer作为解析器,但是该解析器仅支持ECMPScript(es5)标准,对于实验性的语法和非标准(例如 Flow或TypeScript类型)语法是不支持的。因此,我们需要其他的解析器来帮助我们进行解析

  • babel-eslint(.vue文件使用vue-eslint-parser):如果在项目中使用es6,就需要将解析器改成babel-eslint
  • @typescript-eslint/parser:允许ESLint验证TypeScript源代码
2.3.2 parserOptions

默认情况下EsLint支持es5语法,可以覆盖parserOptions中的配置,开启对es6版本以及ts的支持, 而且之前说的parser默认只支持一个配置,可以在该字段中增加更多的配置

module.exports = {
  env: {
    browser: true,
    es6: true,
    node: true,
  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    ecmaVersion: 2020,
    parser: '@typescript-eslint/parser',
    extraFileExtensions: ['.vue'],
    ecmaFeatures: {
      jsx: true,
    },
    sourceType: 'module',
  },
  }
  //两个`parser`的区别在于,外面的`parser`用来解析`vue`文件,使得`eslint`能解析`<template>`标签中的内容,而`parserOptions`中的`parser`,即`@typescript-eslint/parser`用来解析vue文件中`<script>`标签中的代码。

2.3.3 global

项目引入的库中会声明一些变量,但对于Eslint来说需要提前在配置中声明,每个变量有三个选项,writable,readonly和off,分别表示可重写,不可重写和禁用(true表示该变量为 writeable,而 false 表示 readonly)。

{
  "globals": {
    // 声明 jQuery 对象为全局变量
    "$": false, 
    "jQuery": false
  }
}
2.3.4 env

在global中声明变量需要一个一个的声明,env可以对一组变量进行全局预设

 env: {
    browser: true,
    es6: true,
    node: true,
  },

要注意的是,可以在golbals中使用字符串off禁用全局变量来覆盖env中的声明。

小程序中,并不支持env去定义,所以需要通过global进行预定义,否则会提示报错

globals: {
   App: true,
   Page: true,
   wx: true,
   swan: true,
   tt: true,
   my: true,
   getApp: true,
   getPage: true,
   requirePlugin: true,
   mpvue: true,
   mpvuePlatform: true,
   __wxConfig: true,
   getCurrentPages: true
 }
2.3.5 rules

具体配置参数请参考 # Rules

  • off 或 0:表示不验证规则。
  • warn 或 1:表示验证规则,当不满足时,给警告。
  • error或 2 :表示验证规则,不满足时报错退出。

个人常用配置

  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 1 : 0,// 禁止使用console
    'no-debugger': process.env.NODE_ENV === 'production' ? 1 : 0,// 禁止使用debugger
    'space-before-function-paren': 0,// 函数定义时括号前面要不要有空格
    'no-multiple-empty-lines': 0,// 空行最多不能超过2'no-trailing-spaces': 0,// 一行结束后面不要有空格
    'eol-last': 0,// 文件以单一的换行符结束
    'no-unused-vars': 0, // 不能有声明后未被使用的变量或参数
    'padded-blocks': 0,// 块语句内行首行尾是否要空行
    'space-before-blocks': [0, "always"],// 不以新行开始的块{前面要不要有空格
    'indent': [0, 2],//缩进风格
    'quotes': ['warn', 'single'],//"double" (默认) 要求尽可能地使用双引号 "single" 要求尽可能地使用单引号 "backtick" 要求尽可能地使用反勾号

  }
2.3.6 plugins

对于js语法,官方提供的rules配置基本能够满足我们的需求,但对于ts或者jsx的检测,则需要插件来帮助我们进行检查

例如上文提到的@typescript-eslint

  plugins: ['vue', '@typescript-eslint'],
 rules: {
   '@typescript-eslint/no-unused-expressions': 2,
    '@typescript-eslint/camelcase': 0,
     '@typescript-eslint/no-explicit-any': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-non-null-assertion': 'off',
    ...
  }
2.3.7 extends

extends是一份配置好的plugin和rules的组合,支持以字符串或者数组的形式配置

extends: 'standard',

extends: [
    'standard',
    'plugin:vue/recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/vue',
],

需要注意的是以数组的形式配置的话,每个配置继承它前面的配置。拓展是一个数组,Eslint 递归地扩展配置, 然后使用rules属性来拓展或者覆盖extends配置规则。

2.3.8 overrides

有时候需要忽略一些文件特殊的校验规则的时候,可以通过overrides配置进行过滤

 overrides: [
    {
      files: ['*.js'],
      rules: {
        '@typescript-eslint/no-var-requires': 'off',
      },
    },
    {
      files: ['src/common/api/**/*'],
      rules: {
        '@typescript-eslint/no-empty-interface': 'off',
      },
    },
  ],

2.4 使用Eslint

2.4.1 使用Eslint

我们可以通过eslint src/APP.vue 或者配置package.json script命令运行Eslint,也可以通过配合git hooks的形式进行提交前的校验# 实现一些简单的git 提交校验

2.4.2 其他

对于部分文件或者代码不进行Eslint检测

  • 使用注释跳过Eslint的检查
/* eslint-disable */
alert('该注释放在文件顶部,整个文件都不会出现 lint 警告');

/* eslint-disable */
alert('块注释 - 禁用所有规则');
/* eslint-enable */

/* eslint-disable no-console, no-alert */
alert('块注释 - 禁用 no-console, no-alert 特定规则');
/* eslint-enable no-console, no-alert */

alert('禁用该行所有规则'); // eslint-disable-line

// eslint-disable-next-line
alert('禁用该行所有规则');

/* eslint-disable-next-line no-alert */
alert('禁用该行 no-alert 特定规则');

alert(
 '禁用该行 no-alert, quotes, semi 特定规则'
); /* eslint-disable-line no-alert, quotes, semi*/
  • 创建.eslintignore文件忽略某些文件的检查
//.eslintignore文件
node_modules
pont
client/api

  • 也可以在package.json的eslintConfig字段进行配置

3.Prettier的使用

3.1 为什么使用Prettier

Eslint虽然可以检测代码质量问题并给出提示,但是格式化的能力有限,只能格式化js,不支持css,html等语言。而Prettier具有更强大的功能,能够支持包括 js、ts、各种 css、vue 和 md 等前端绝大部分的语言和文件格式 因此,我们可以通过Eslint和Prettier组合使用,用Eslint进行代码校验,用Prettier统一代码风格。

3.2 使用Prettier

pnpm add prettier eslint-config-prettier -D
//由于eslint和prettier里面的一些规则可能会存在冲突,所以需要安装eslint-config-prettier(vue @vue/eslint-config-prettier)

在.eslintrc.js的extends中将prettier设置为最后一个extends即可,相当于用 prettier 的规则,覆盖掉 eslint:recommended 的部分规则

extends: ["eslint:recommended", "prettier"],

也可以通过eslint-plugin-prettier

{
    "rules":{
      "prettier/prettier":"error" 
    },
    "plugins": ["prettier"]}

//或者
{
 "extends": [
     "eslint:recommended",
     "plugin:prettier/recommended"
 ]
}

3.3 配置Prettier

Prettier同样也是支持配置两个文件

module.exports = {
  // 一行最多 120 字符
  printWidth: 120,
  // 行尾需要有分号
  semi: true,
  // 使用单引号
  singleQuote: true,
  // 对象的 key 仅在必要时用引号
  quoteProps: 'as-needed',
  // jsx 不使用单引号,而使用双引号
  jsxSingleQuote: false,
  // 末尾不需要逗号
  trailingComma: 'none',
  // 大括号内的首尾需要空格
  bracketSpacing: true,
  // jsx 标签的反尖括号需要换行
  jsxBracketSameLine: false,
  // 每个文件格式化的范围是文件的全部内容
  rangeStart: 0,
  rangeEnd: Infinity,
  // 不需要写文件开头的 @prettier
  requirePragma: false,
  // 不需要自动在文件开头插入 @prettier
  insertPragma: false,
  // 使用默认的折行标准
  // proseWrap: 'preserve',
  // 根据显示样式决定 html 要不要折行
  htmlWhitespaceSensitivity: 'css',
  // 换行符使用 lf
  endOfLine: 'lf'
}

4.解决Eslint 和 Prettier 之间的冲突

当我们的setting.json配置了自动格式化,同时开启了eslint自动修复

// .vscode/setting.json配置了自动格式化,同时开启了eslint自动修复
{ 
  // 保存时 prettier 自动格式化
  "editor.formatOnSave": true,
  // 保存时自动启用 eslint --fix 自动修复
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  }
}

但是却提示了单双引号的问题,以及分号的问题。这是因为我在eslint中继承了eslint-config-standard,这套规则中推荐使用单引号,行末不添加分号,这与我的prettier配置相互冲突

解决方案

冲突的本质在于 eslint既负责了代码质量检测,又负责了一部分的格式美化工作,格式化部分的部分规则和 prettier不兼容。 能不能让eslint只负责代码质量检测而让prettier负责美化呢? 好在社区有了非常好的成熟方案,即 eslint-config-prettier + eslint-plugin-prettier

  • eslint-config-prettier 的作用是关闭eslint中与prettier相互冲突的规则。
  • eslint-plugin-prettier 的作用是赋予eslintprettier格式化代码的能力。 安装依赖并修改.eslintrc文件
// 安装依赖
yarn add eslint-config-prettier eslint-plugin-prettier -D

// .eslintrc
{
   // 其余的配置
 - "extends": ["eslint:recommended", "standard"]
 + "extends": ["eslint:recommended", "standard",  "plugin:prettier/recommended"]
  // 其余的配置
}

其中plugin:prettier/recommended 这个语法就是加载了 node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js

// node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js
module.exports = {
  // plugin:prettier/recommended 就是加载这个
  configs: {
    recommended: {
      extends: ['prettier'],
      plugins: ['prettier'],
      rules: {
        'prettier/prettier': 'error',
        'arrow-body-style': 'off',
        'prefer-arrow-callback': 'off',
      },
    },
  },
  ...
}
  1. extends: ['prettier']: 通过 eslint-config-prettier 关闭eslintprettier 相冲突的规则。
  2. plugins: ['prettier']: 加载 eslint-plugin-prettier,赋予 eslintprettier 格式化文档的功能
  3. 'prettier/prettier': 'error': 让代码文件中不符合prettier格式化规则的都标记为错误,结合vscode-eslint插件便可以看到这些错误被标记为红色,当运行eslint --fix 命令时,将自动修复这些错误。
  4. arrow-body-styleprefer-arrow-callback: 这两个规则在eslintprettier 中存在不可解决的冲突,所以关闭掉。

至此, prettiereslint 便可以无冲突协作,保存时候也能自动修复并格式化代码了。

5.Vscode插件使用

虽然了解了Eslint以及Prettier的使用,但是还是需要运行命令才能进行检验和格式化,如果希望开发过程中保存代码就可以完成以上操作

在vscode中安装以下插件:

  • ESLint插件
  • Prettier插件
  • EditorConfig for VS Code插件 //可以让编译器读取配置文件,统一团队代码风格

5.1配置setting.json

setting.json分为用户区以及工作区,其中工作区只对当前项目生效

image.png 配置工作区的setting.json如下

{
  "editor.formatOnPaste": false,
  "editor.formatOnSave": true,
  "editor.formatOnType": false,
  "editor.wordWrap": "on",
  "javascript.format.enable": false,
  "typescript.format.enable": false,
  "editor.tabSize": 2,
  "eslint.validate": ["javascript", "javascriptreact", "html", "vue"],
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  },
  "prettier.eslintIntegration": true,
  "prettier.tslintIntegration": true,
  "prettier.requireConfig": true,
  "editor.defaultFormatter": "svipas.prettier-plus",
  "[vue]": {
    "editor.defaultFormatter": "octref.vetur"
  }
}

此时就能自动进行ESLint检查,并修复一些问题。

5.2 配置.editorconfig

上文安装了EditorConfig for VS Code插件,他能够让编译器读取配置文件,统一团队代码风格。 创建.editorconfig文件,这个文件的代码规范会高于编译器默认的代码规则。

配置如下

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = auto

至此就完成了我们Eslint + Prettier+Vscode的配置

参考