前端代码规范从0到1

1,513 阅读9分钟

基本概念

eslint和prettier

《搞懂 ESLint 和 Prettier》

  • eslint作用:检查代码质量,比如是否有已定义但未使用的变量,或者使用函数式编程的函数是否产生副作用等
  • prettier作用:pretter没有对代码的质量进行检查的能力,其只会对代码风格按照指定的规范进行统一,避免一个项目中出现多种不同的代码风格。比如tab键为多少个空格
  • 代码质量出问题意味着程序有潜在 Bug,而风格问题充其量也只是看着不爽

eslint规则设置:

// 配置参数
rules: {
    "规则名1": [规则值, 规则配置],
    "规则名2": [规则值, 规则配置]
}

规则值(决定了是否开启/关闭)

  • off 或 0:关闭规则
  • warn 或 1:开启规则,warn 级别的错误 (不会导致程序退出)
  • error 或 2:开启规则,error级别的错误(当被触发的时候,程序会退出)

使用配置文件的第一种方式是通过 .eslintrc.* 和 package.json 文件。ESLint 将==自动==在要检测的文件目录里寻找它们,紧接着是父级目录,一直到文件系统的根目录(除非指定 root: true)

自动修复

  • vscode安装 eslint 插件后不用我们手动运行检查node_modules/.bin/eslint yourfile.js,如果我们的项目中引入并配置了eslint,我们在写代码的时候vscode的eslint插件会根据我们配置的文件自动帮我们检查代码格式是否正确,省去了要手动命令行检查的麻烦
  • 自动修复:--fix的作用是自动修复根据我们配置的规则检测出来的格式问题
<!--在 package.json 中配置:可自动修复全部对应后缀名的文件-->

"scripts": {
  "lint": "./node_modules/.bin/eslint --ext .js,.vue ./ --fix",
},

其实eslint只能fix掉部分规范具体看文档的规则前面是否带了一个小扳手,如果带的话证明可以修复

  • 也可以配置vscode的setting.json文件,达到保存自动修复当前文件(也是读取我们项目根目录的Eslint规则)
// settings.json 中的部分配置

{
    "editor.formatOnSave": false, // 每次保存自动格式化
    "editor.defaultFormatter": "esbenp.prettier-vscode",  
    "window.zoomLevel": 0, // 原始缩放比例
    "editor.codeActionsOnSave": { // 在保存时用eslint规则进行修复
    "source.fixAll.eslint": false
    },
    "eslint.enable": true,  //是否开启vscode的eslint
    "eslint.options": {    //指定vscode的eslint所处理的文件的后缀
      "extensions": [
          ".js",
          ".vue",
          ".ts",
          ".tsx"
      ]
    }
}

基本配置及相关文件解读(eslint+husky+prettier+lint-staged)

配置 .editorconfig

ditorConfig用于在基本代码库中维持一致的编码风格和设置,例如缩进样式、选项卡宽度、行尾字符以及编码等。这里可以根据具体项目用什么框架开发具体设置

在vscode中搜索安装EditorConfig插件,根目录下新建 .edittorconfig文件写入一些配置代码

// .editorconfig

root = true

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

[*.md]
trim_trailing_whitespace = false

配置 Eslint

  1. 配合vscode使用可以安装 eslint 插件
  2. 安装以下EsLint包:(注意要安装在开发环境上,还有就是如果你使用的是脚手架的话,选了Eslint选项,会自带这些包。)
    "eslint": "^6.7.2",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-vue": "^6.2.2",
  1. 在项目的根目录下新建.eslintrc.js 文件
// .eslintrc.js 文件内容

// extends:基础配置(我们这里使用的是腾讯的代码规范,配合`prettier`)
extends: ['@tencent/eslint-config-tencent', 'plugin:vue/essential', 'prettier'],

// rules:可以根据需要定义新的规则,或覆盖extends里面的基础规则配置
"rules": {
     "semi": ["error", "never"], // 禁止使用分号
}

让Eslint识别Typescript:

  1. 安装依赖:
tnpm i typescript
tnpm i -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

// @typescript-eslint/parser 是一个eslint的解析器,该解析器利用TypeScript ESTree允许ESLint整理TypeScript源代码。

  1. @typescript-eslint/eslint-plugin 是eslint识别TypeScript规则的插件 我们把他放入 extends 这个数组里。
// eslintrc.js
module.exports = {
    "parser":  '@typescript-eslint/parser', 
    "extends": ['plugin:@typescript-eslint/recommended'],
    "plugins": ['@typescript-eslint'],
    "env": {
        "browser": true,
        "es6": true
    },
    "rules": {
      "semi": ["error", "never"], // 禁止使用分号
    }
};


配置prettier

基本概念:

  • 主要用来统一代码格式
  • eslint也会对代码进行一定程度的格式校验,但主要是用来对代码规范的扫描,而prettier则是专门用来对代码进行格式化,两个工具各司其职
  • 工作原理:将格式化前的代码和格式化后的代码进行比对,如果发现不一样,prettier就会对其进行标记并按照指定的格式化规范进行修复

配置步骤:

  1. 根目录下新建配置文件.prettierrc.js
// .prettierrc.js 文件
module.exports = {
  "printWidth": 80, //一行的字符数,如果超过会进行换行,默认为80
  "tabWidth": 2, //一个tab代表几个空格数,默认为80
  "useTabs": false, //是否使用tab进行缩进,默认为false,表示用空格进行缩减
  "singleQuote": false, //字符串是否使用单引号,默认为false,使用双引号
  "semi": true, //行位是否使用分号,默认为true
  "trailingComma": "none", //是否使用尾逗号,有三个可选值"<none|es5|all>"
  "bracketSpacing": true, //对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
  "parser": "babylon" //代码的解析引擎,默认为babylon,与babel相同。
}
  1. 安装 Prettier 依赖:
// eslint-config-prettier eslint-plugin-prettier 插件就是为了解决冲突的
tnpm i -D prettier eslint-config-prettier eslint-plugin-prettier

Prettier 和 ESLint 一起使用的时候会有冲突,解决方法:

  1. 首先我们需要使用 eslint-config-prettier 来关掉 (disable) 所有和 Prettier 冲突的 ESLint 的配置(这部分配置就是上面说的,格式问题的配置,所以关掉不会有问题),方法就是在 .eslintrc 里面将 prettier 设为最后一个 extends
// .eslintrc.js 文件
{      
    "extends": ["prettier"] // prettier 一定要是最后一个,才能确保覆盖    
}
  1. (可选,推荐) 然后再启用 eslint-plugin-prettier ,将 prettier 的 rules 以插件的形式加入到 ESLint 里面。这里插一句,为什么"可选" ?当你使用 Prettier + ESLint 的时候,其实格式问题两个都有参与,disable ESLint 之后,其实格式的问题已经全部由 prettier 接手了。那我们为什么还要这个 plugin?其实是因为我们期望报错的来源依旧是 ESLint ,使用这个,相当于把 Prettier 推荐的格式问题的配置以 ESLint rules 的方式写入,这样相当于可以统一代码问题的来源
// .eslintrc    
{      
    "plugins": ["prettier"],      
    "rules": {        
        "prettier/prettier": "error"      
    }    
}

配置 husky + lint-staged 构建代码工作流

  1. 安装 husky lint-staged 依赖
tnpm i -D husky lint-staged
  1. 配置 husky/.huskyrc.js
// 单独在根目录新建一个 .huskyrc.js 文件
module.exports = {
  hooks: {
    'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
    'pre-commit': 'lint-staged',
  },
};

// 或者在 package.json 中添加以下配置
"husky": {
    "hooks": {
      'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS', // commitlint 的配置
      'pre-commit': 'lint-staged'
    }
  }
  
  1. 配置 lint-stage/.lintstagedrc.js
// 单独在根目录新建一个 .lintstagedrc.js 文件
module.exports = {
  '*.{js,vue,ts}': 'eslint',
};

// 或者在 package.json 中添加以下配置
"lint-staged": {
    "*{.ts,.js}":[
      "eslint --ext .tsx,.ts --fix ./src",
      "prettier --write",
      "git add"
    ]
  }

husky作用:

  • 为了确保本地的代码已经通过检查才能push到远程,这样才能从一定程度上确保应用的线上质量
  • 在本地进行git commit的时候开始进行扫描检查

工作原理:

  • 在运行 git commit 时候,自动会先去运行 prettier --write 格式化代码,再运行 eslint 校验代码是否符合规范。这两步都通过后才会提交代码。如果任何一步失败,则会停止提交

git的hook:

  • git的hook可以理解成当执行如git add、git commit等git操作时的回调,可以查看.git文件下的hooks目录,这里存放的是git相关操作的一些脚本例子。通过git hook就可以在本地进行commit的时候触发代码扫描来确保本地代码的质量

  • 使用到lint-staged工具来识别被加入到stage区文件,就是每次只对当前修改后的文件进行扫描,即只对git add加入到stage区的文件进行扫描即可,完成对增量代码进行检查

commitlint.config.js(提交规范)

安装:

tnpm install --save-dev @commitlint/config-conventional @commitlint/cli

配置: 在husky的配置加入CommitlIint配置,v1.0.1版本以后为HUSKY_GIT_PARAMS,v0.14.3为GIT_PARAMS

// package.json文件

"husky": {
    "hooks": {
      "pre-commit": "npm run test",
      "commit-msg": "commitlint -e $HUSKY_GIT_PARAMS"  // 关键代码
    }
  },

提交格式:

<type>: <subject>

常用type类别:

  • upd:更新某功能(不是 feat, 不是 fix)
  • feat:新功能(feature)
  • fix:修补bug
  • docs:文档(documentation)
  • style: 格式(不影响代码运行的变动)
  • refactor:重构(即不是新增功能,也不是修改bug的代码变动)
  • test:增加测试
  • chore:构建过程或辅助工具的变动

例子:

git commit -m 'feat: 增加 xxx 功能'
git commit -m 'bug: 修复 xxx 功能'

commitlint.config.js文件配置:

  • rule配置说明::rule由name和配置数组组成,如:'name:[0, 'always', 72]',数组中第一位为level,可选0,1,2,0为disable,1为warning,2为error,第二位为应用与否,可选always|never,第三位该rule的值。具体配置例子如下
// 配置文件commitlint.config.js,当然也可以是 .commitlintrc.js

module.exports = {
  extends: [
    "@commitlint/config-conventional"
  ],
  rules: {
    'type-enum': [2, 'always', [
      'upd', 'feat', 'fix', 'refactor', 'docs', 'chore', 'style', 'revert'
     ]],
    'type-case': [0],
    'type-empty': [0],
    'scope-empty': [0],
    'scope-case': [0],
    'subject-full-stop': [0, 'never'],
    'subject-case': [0, 'never'],
    'header-max-length': [0, 'always', 72]
  }
};

.ls-lint.yml(文件命名规范)

  • PascalCase
  • kebab-case

执行流程

  1. 待提交的代码git add 添加到暂存区;
  2. 执行 git commit;
  3. husky注册在git pre-commit的钩子函数被调用,执行lint-staged;
  4. lint-staged 取得所有被提交的文件依次执行写好的任务(ESLint 和 Prettier);
  5. 如果有错误(没通过ESlint检查)则停止任务,同时打印错误信息,等待修复后再次执行commit;
  6. 成功commit,可push到远程

在上述流程中,有这样几个核心点:

  1. husky注册git的钩子函数保证在git 执行commit时调用代码扫描的动作;
  2. eslint完成按照配置的规则进行扫描;
  3. Lint-staged保证只对当前add到git stage区的文件进行扫描操作,这样做的原因在于,如果对全工程的文件进行扫描的话,并且之前的前端工程并未注重代码规则的检测的话,很大可能性会出现成百上千的error,基本上心里是崩溃的。因此,只对当前add的文件进行检测,达到及时止损的目的,历史代码可以切到新的分支进行修复后再进行合并

总结:

  • 通过Eslint去约束Javascript/Typescript
  • Prettier 美化代码,统一代码风格
  • 使用 husky + lint-staged 在commit前做检查,避免存在不规范或者存在bug的代码入仓库

使用以上工具,就可以保证我们从本地开发到commit提交代码都是经过校验的!因此我们在平时开发写代码的时候会实时校验,然后在用gitcommit提交代码的时候也会再校验一次,这样就有了双重保障代码的质量!!!

参考文章

《从零配置 Eslint + Prettier + husky + lint-staged 构建前端代码工作流》《eslint+husky+prettier+lint-staged提升前端应用质量》