代码规范和自动格式化
代码规范和自动格式化
在团队开发中,统一代码规范是必不可少的。ESlint 是我们前端工程化中代码检测的一款常用工具。它不仅可以检测 JS 还支持 Vue 和 JSX 。
前置知识——最佳实践:
- ESlint 检测不合规的代码,npm 包也有修复功能,但是没有 Prettier 强大。
 - Prettier 修复不合规的代码
 - Editorconfig 统一不同操作系统下的编码格式
 三者都有对应的 VScode 插件。但需要明白的是,VScode 插件是通过本地的配置,在编写代码时就帮开发者 检测、修复代码!而通过 npm 安装的包,是通过指令的方式检测、修复。俩者的功能和用途是不一样的!
安装和使用
环境要求: Node.js (>=6.14), npm version 3+。
可以使用 npm 安装 ESlint(开发时依赖) : npm install eslint -d
其次,你需要为 ESlint 设置配置文件: npx eslint --init
采用 init 初始化指令时,可以依据你的需求,为 ESlint 设置配置文件,最后会在当前文件夹下生成 .eslintre.cjs 的配置文件。并且我们可以在配置文件中看到许多 rules 配置规则。
【注意】若是新项目,请检查 package.json 文件中是否有书写
"type": "module",使用了 ES6 的模块导入。这时的配置文件不再接受.js格式的配置读写,想要使用 CommonJS 模块,需要用.cjs格式结尾配置文件才可被正常读取。
此时,我们可以通过指令: npx eslint . --fix 修复全部代码。
ESlint 配合 VScode 插件使用
虽然通过指令,可以做到统一修复代码,但是如果想在编写代码的时候立即发现不合规的地方,我们还是需要通过 VScode 插件 “ESLint” 来完成。
但我们安装完 “ESLint” 插件后,便会在编辑文件中,看到报错提示信息。当然,我们可以更进一步,利用 ESLint 进行自动修复(更流行的是用 Prettier 进行修复,下文会介绍),通过 设置打开 setting.json , 在其中编辑改写:
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
}
即,保存文件时执行——”ESLint 自动修复文件“。
但是,由于自带的代码格式化功能并不彻底,所以目前社区更流行将 ESlint 作为单一的语法检测工具,代码自动修复交由更专业的 Prettier 工具实现。
设置 Prettier
如上文所述,Prettier 的代码格式化功能更加强大,但是其语法和 ESLint 却并不相同,所以还需要额外再设置一番。
在
VScode中安装Prettier插件,并在项目中局部安装:npm install -d prettier由于目的是配合 ESLint 使用,因此,我们在根目录创建
.prettierrc配置文件,以下列出部分通用设置:{ "useTabs": false, "tabWidth": 2, "printWidth": 100, "singleQuote": true, "trailingComma": "none", "bracketSpacing": true, "semi": false }这个时候,我们就可以对项目进行初步格式化操作了:
npx prettier --write .
但是这并不是我们想要的。我们需要让 ESLint 检测代码,Prettier 修复这部分问题代码。而俩者的语法并不相同,因此,我们接下来解决这部分的冲突。
使用
eslint-config-prettier这个插件,用来关闭所有和 Prettier 冲突的 ESLint 规则。安装插件:
npm install -D eslint-config-prettier eslint-plugin-prettier。eslint-plugin-prettier: 基于 prettier 代码风格的 eslint 规则,即 eslint 使用 pretter 规则来格式化代码。
eslint-config-prettier: 禁用所有与格式相关的 eslint 规则,解决 prettier 与 eslint 规则冲突,确保将其放在 extends 队列最后,这样它将覆盖其他配置。
后续只需在扩展末尾添加
"plugin:prettier/recommended"即可。在
.eslintrc.cjs配置文件中的extends处加入解决prettier的冲突 的扩展:// .eslintrc.js module.exports = { ...... extends: [..., 'plugin:prettier/recommended'], // 现在是以 prettier/recommend 为主, 解决了与 eslint 的冲突 ...... }
配合 Typescript
// .eslintrc.cjs
module.exports = {
  extends: [
    'eslint-config-airbnb-base',
    'plugin:@typescript-eslint/recommended',
  ],
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint'],
  rules: {
    // 不在 import 其它 moudle时,填写文件后缀名
    'import/extensions': 'off',
    // typescript 中的 interface 以及 type 不存在变量提升的问题
    'no-use-before-define': 'off',
    // 保证eslint见到 interface 或者 type 在声明前使用时不会报错
    '@typescript-eslint/no-use-before-define': [
      'error',
      { ignoreTypeReferences: true },
    ],
    // 如果单文件中只有一个导出项,则eslint会告诉你使用export default的方式导出, 关闭次功能
    'import/prefer-default-export': 'off',
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.ts'],
        moduleDirectory: ['node_modules', './src'],
      },
    },
  },
  parserOptions: {
    project: './tsconfig.json',
  },
}
值得注意的是,若是 Vue3 + Ts ,extends 中的“
plugin:vue/vue3-essential” 插件,存在解析器 “vue-eslint-parser”,用npx eslint --init生成的配置中,默认使用的是“@typescript-eslint/parser”解析器,而 extends 的顺序是 ts 在 vue 后面,因此将 vue 的解析器覆盖掉了,所以需要对解析器的配置做出微小调整:// "parser": "@typescript-eslint/parser", "parser": "vue-eslint-parser", "parserOptions": { "ecmaVersion": "latest", "parser": "@typescript-eslint/parser", "sourceType": "module" },
当然,我们还需要为 VScode 进行本地设置,来更好的配置我们的插件(告诉 VScode,对这些文件进行敲代码时,你要给我干活ヽ(o)丿):
// VScode 的 setting.json
  /* ESlint 设置 */
  "eslint.alwaysShowStatus": true,
  "eslint.format.enable": true, // 开启eslint自动修复js/ts/jsx/tsx功能
  "eslint.trace.server": "verbose", //在输出中看到更多日志
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "javascriptreact",
    "typescriptreact"
  ], // eslint 作用范围
  "typescript.tsdk": "node_modules/typescript/lib",
  "editor.formatOnSave": true, // 保存时格式化
  // 设置js的formatter为eslint
  "[javascript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[typescript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[json]": {
    "editor.defaultFormatter": "vscode.json-language-features"
  },
  // jsonc是有注释的json
  "[jsonc]": {
    "editor.defaultFormatter": "vscode.json-language-features"
  },
  "eslint.codeActionsOnSave.mode": "problems",
  "editor.defaultFormatter": "esbenp.prettier-vscode", // 默认格式化 用 Prettier
  // 将json文件识别为jsonc格式
  "files.associations": {
    "*.json": "jsonc",
  },
统一代码风格实战
问题:项目中遇到 ESLint 报错:“Expected linebreaks to be 'CRLF' but found 'LF'.”
查阅官方文档后,了解到由于不同的操作系统的换行符不同,因此存在兼容性问题。
报错原因:
- 这个问题是用户的操作系统可能为 Mac/Linux 等系统;
 - 手动配置过 VScode 换行编码风格为 "\n";
 - 安装过 Editorconfig 插件,并且设置了换行规则 "
end_of_line = lf" 
并且,配置了 ESlint 规则:'linebreak-style': ['error', 'windows']。
因此先看 ESlint 用于控制代码换行符的兼容性和格式的配置规则:'linebreak-style': ['error', 'windows']。该规则可设置为以下三个值之一:
"unix":表示 Unix/Linux/Mac 等系统中通用的换行符风格(即 "\n");"windows":表示 Windows 系统默认的换行符风格(即 "\r\n");"auto":根据当前平台自动选择上述两种风格之一。
在这里,配置为 ['error', 'windows'] 表示强制使用 windows 风格的换行符,并且如果检测到代码文件中存在不兼容 windows 换行符的内容,就会报错并提示更正。其中 "error" 用来指定该规则是一个错误类型的告警,并将由其影响停止进程执行。
解决办法:
统一 “.editorconfig” 和 “.eslintrc.js” 俩个配置文件。
.editorconfig:
[*]
charset = utf-8
indent_style = tab
end_of_line = lf # 统一换行符
.eslintrc.js:
module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: ['plugin:vue/essential', 'eslint:recommended', '@vue/prettier'],
  parserOptions: {
    parser: 'babel-eslint',
  },
  rules: {
    // ...
    // 统一换行符检测规则
    'linebreak-style': ['error', 'unix'],
  },
}
当然,只是这样还不够,我们还应当配置“.prettierrc” 帮助我们修复不合规的代码。配置规则为:
{
  // ...
  "endOfLine": "lf"
}
通过如上三个设置,就能统一换行编码风格为 “ \n ”。
