代码风格统一: 使用husky, prettier, eslint在代码提交时自动格式化,并检查代码。

7,949 阅读5分钟

引言

这个需求主要是组内成员用的编辑器不统一,代码风格也各异,所以在修改代码时,如果格式化了代码,在code review阶段很难分辨修改了的代码。当然,代码风格统一还有其他好处,这里就不不多废话了。

先看效果

源文件

可以看到有很多红线,这个是因为不符合prettier的规则,这种情况下会使用eslint进行报错,就是你看到的红线了。具体如何配置之后再讲。下面来看看提交时的情况。

对比上图,可以看到代码已经被格式化了。这时我们再改一改,去掉eslint报的错误。注意HelloWorld()后故意留个报错,而且我们没有加分号。

再次提交。

此时的代码变为

可以看到,之前HelloWorld()后的报错没有了,而且分号自动加上去了。这是用了eslint自动修复的功能。

总结下: 在我们提交代码时,先自动帮我们格式化代码,然后使用eslint检查代码,并自动修复错误,在修复不了的时候,报错给我们。并且报错后此次的commit不会提交。

下面看如何配置。

使用的工具

  • husky。一个git钩子工具,这里主要用pre-commit钩子。通俗点讲就是husky可以在你commit之前帮你做一些事情。
  • prettier。 一个很流行的代码格式化工具,你很容易在编辑器找到实现它的各种插件,像vscode,atom,webstom都可以找到。这里用它在代码提交前做代码格式化。
  • eslint。 代码检查工具。eslint也可以负责一部分代码格式检查的工作,但是prettier已经做的很好了,所以我便没用eslint的代码格式检查,只让其负责代码错误检查。
  • lint-staged。在你提交的文件中,执行自定义的指令。don’t let 💩 slip into your codebase. — lint-staged

安装

安装eslint

npm i -D eslint babel-eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react

安装prettier

npm install --save-dev prettier eslint-plugin-prettier eslint-config-prettier

安装husky,lint-staged

npm i -D husky lint-staged pretty-quick

prettier配置

  • prettier 代码格式化核心
  • eslint-plugin-prettier 插件,可以让eslint使用prettier规则进行检查,并使用--fix选项。像之前的格式不对时,eslint提示的红线。
  • eslint-config-prettier 插件,之前说了eslint也会检查代码的格式,这个插件就是关闭所有不必要或可能跟prettier产生冲突的规则。

eslintrc.json添加如下配置:

{
 "extends": ["airbnb", "plugin:prettier/recommended"],
}

这个配置做如下三件事:

  1. 使eslint-plugin-prettier生效
  2. 不符合prettier/prettier的规则,会报错。就是之前截图中的红线。
  3. 使eslint-config-prettier生效。就是会覆盖eslint中与prettier冲突的配置。

prettier配置文件

prittier配置文件支持很多种,具体可以看这里。我使用的是.prettierrrc格式,因为试过其他格式,但是只有.prettierrrc,vscode才可以识别。 生成配置可以直接用官网上的try it out,左下角有导出配置。下面这份配置基本上是风格要求的全部了,具体可按照个人爱好进行配置。

{
  "printWidth": 120, // 一行最大多少字符
  "tabWidth": 2, // tab占用的字符数
  "useTabs": false, // 是否使用tab代替空格
  "semi": true, // 是否每句后都加分号
  "singleQuote": true, // 是否使用单引号
  "jsxSingleQuote": false, // jsx是否使用单引号
  "trailingComma": "all", // 数组尾逗号。
  "bracketSpacing": false, // {foo: xx}还是{ foo: xx }
  "jsxBracketSameLine": false, //看官网
  "arrowParens": "always" //剪头函数参数是否使用()
}

eslint配置

直接上配置:

{
  "extends": ["airbnb", "plugin:prettier/recommended"], // eslint扩展规则
  "parserOptions": {
    "ecmaVersion": 7,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "parser": "babel-eslint",// 解决ES6 improt会报错
  "env": { // eg如果不配置browser,window就会被eslint报undefined的错
    "es6": true,
    "browser": true,
    "node": true
  },
  "plugins": ["react", "jsx-a11y", "import"],
  "rules": {
    "class-methods-use-this": 0,
    "import/no-named-as-default": 0,
    "react/jsx-filename-extension": [
      "error",
      {
        "extensions": [".js", ".jsx"]
      }
    ]
  }
}

husky钩子pre-commit配置

  "husky": {
    "hooks": {
      "pre-commit": "lint-staged" // pre-commit,提交前的钩子
    }
  },
  "lint-staged": {
    // 此处可以配置文件夹和文件类型的范围
    "src/**/*.{jsx,tsx,ts,js,json,css,md}": [
      "prettier --write", // 先使用prettier进行格式化
      "eslint --fix", // 再使用eslint进行自动修复
      "git add" // 所有通过的话执行git
    ]
  },

husky会在你提交前,调用pre-commit钩子,执行lint-staged,如果代码不符合prettier配置的规则,会进行格式化;然后再用eslint的规则进行检查,如果有不符合规则且无法自动修复的,就会停止此次提交。如果都通过了就会讲代码添加到stage,然后commit。

其他的坑

  1. 尾逗号 只有换行时才会有效果: trailingComma配置为 all
function HelloWorld({greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) {
	let noTrailingComma = [a , b,c]
}

格式化后为

function HelloWorld({
  greeting = "hello",
  greeted = '"World"',
  silent = false,
  onMouseOver, // 这里有逗号
}) {
  let noTrailingComma = [a, b, c]; // 注意这里c后面没有逗号
}

  1. vscode配置 我的vscode默认使用的是全局安装的eslint,没有使用项目本地的,所以要更新下全局的eslint插件版本。如果小伙伴知道如何配置的,跟我说下哈。

结尾

如果小伙伴有看不明白或者我写的不清楚的,有问题的,欢迎指正~

有篇文章可以参考着看 lion1ou.win/2020/06/23/