代码质量(前端 vscode)

在一个项目中,由于每个人编写代码的风格不一样,对代码的格式上面有一个约束,将会大大提高代码的质量。

eslint

lint在计算机中是一个静态程序分析工具,用来标记代码中可疑的,可能会出现bug的语句。

安装

npm i -D eslint

生成配置文件

npx eslint --init

运行上面,选择相应的配置项,这个命令做了两件事

1.生成.eslintrc.js 配置文件,根据你的选项不同会有略微出入

module.exports = {
  root: true, // 限定配置文件使用范围
  env: {
    // 指定代码运行环境
    browser: true, // browser global variables
    es2021: true, //
  },
  parserOptions: {
    ecmaVersion: "latest", //ECMAScript 版本
    sourceType: "module", //ECMAScript 模块
  },
  // 继承第三方风格
  extends: [
    "airbnb-base", // 全名eslint-config-airbnb-base,可省略eslint-config
  ],
  rules: {},
};

2.下载对应的第三方 eslint 配置,我选的 airbnb 风格的,所以下了 eslint-config-airbnb-base,而 eslint-config-airbnb-base 依赖于 eslint-plugin-import,所以总共下载了两个依赖

代码检查

npx eslint ./需要检查语法的文件路径

配置编辑器

这时候能对代码进行检查了,但只有运行命令的时候才会显示错误,所以为了方便我们开发,vscode 安装插件 ESlint,这个时候就能直接看到文件的报错了,就不用去运行命名了

增加.eslintignore 忽略文件

增加忽略文件,忽略一些文件不进行 eslint 检查

.eslintignore

# 以”#”号开头表示注释;
# 以斜杠“/”开头表示目录;
# 以星号“*”通配多个字符;
# 以问号“?”通配单个字符
# 以方括号“[]”包含单个字符的匹配列表;
# 以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;

# *.txt  ,*.xls  表示过滤某种类型的文件
# target/ :表示过滤这个文件夹下的所有文件
# /test/a.txt ,/test/b.xls  表示指定过滤某个文件下具体文件
# !*.java , !/dir/test/     !开头表示不过滤
# *.[ab]    支持通配符:过滤所有以.a或者.b为扩展名的文件
# /test  仅仅忽略项目根目录下的 test 文件,不包括 child/test等非根目录的test目录

/dist
/build

打包代码进行 eslint 检查

需要插件 eslint-webpack-plugin

安装

npm i -D eslint eslint-webpack-plugin eslint-config-airbnb-base eslint-plugin-import

webpack.config.js 配置

const ESLintPlugin = require("eslint-webpack-plugin");

module.exports = {
  plugins: [new ESLintPlugin()],
};

stylelint

安装

npm i -D stylelint stylelint-config-standard stylelint-prettier stylelint-config-prettier
npm i -D stylelint-less stylelint-config-recommended-less postcss-less

增加.stylelintrc.js

module.exports = {
  plugins: ["stylelint-prettier"],
  extends: [
    "stylelint-config-standard",
    "stylelint-config-recommended-less",
    "stylelint-config-prettier",
  ],
  customSyntax: "postcss-less",
  rules: {
    "prettier/prettier": true,
  },
};

Prettier

ESLint 主要负责处理两种规则:格式化和代码质量问题。格式化不是它的强项,需要用 Prettier 格式化大师来处理代码风格有问题的代码。

Prettier 格式化后的代码,理论上是最好看的。正因为 Prettier 只关注格式化,所以它也可以格式化其它的文件。

安装

npm i -D prettier

增加配置文件
.prettier.js

module.exports = {};

编辑器安装 Prettier -code formatter 插件,可以一键格式化文档

编辑器 settings.josn 增加配置,保存的时候格式化

"editor.formatOnSave": true, //开启自动保存
"editor.defaultFormatter": "esbenp.prettier-vscode", //默认格式化工具选择prettier

eslint 和 prettier 配合使用

prettier 是擅长代码格式的校验,eslint 擅长代码质量的校验。虽说 eslint 也能格式校验,但是并没有 prettier 那么强势。

当你用 Prettier 格式化代码后再用 ESLint 去检测,会出现一些因为格式化导致的 warning。

eslint-plugin-prettier 插件会调用 prettier 对你的代码风格进行检查,其原理是先使用 prettier 对你的代码进行格式化,然后与格式化之前的代码进行对比,如果过出现了不一致,这个地方就会被 prettier 进行标记,最后 eslint 自动 fix 按照 prettier 的规范修复 error 代码

安装

npm i eslint-plugin-prettier eslint-config-prettier -D

.eslintrc.js

extends: ["airbnb-base", "plugin:prettier/recommended"],

有时候配置好后重启 vscode 才能生效

配置 vscode

增加配置文件

在项目根目录下

编辑器配置

{
  "editor.formatOnSave": true, //开启保存的时候格式化
  "eslint.enable": true, //是否开启vscode的eslint
  "eslint.alwaysShowStatus": true, //右下角显示eslint图标
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true // 在保存的时候用eslint修复和prettier不冲突部分错误
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode", //默认格式化工具选择prettier
}

.editorconfig

添加 .editorconfig 文件,编辑器配置文件。.editorconfig 配置文件用于抹平不同编辑器或系统之间的编码差异,放在项目根目录。最常见的配置之一是 end_of_line = lf,如果用 Windows 和 Mac 混合开发,不统一行尾符会造成 eslint 爆红。

由于不同开发者的编辑器设置不同,故在项目中应当包含 .editorconfig,用来统一配置编辑器的换行、缩进存储格式。

配置

# http://editorconfig.org
root = true

[*]
indent_style = space                    # 输入的 tab 都用空格代替
indent_size = 2                         # 一个 tab 用 2 个空格代替
end_of_line = lf                      # 换行符使用 unix 的换行符 \n
charset = utf-8                         # 字符编码 utf-8
trim_trailing_whitespace = true         # 去掉每行末尾的空格
insert_final_newline = true             # 每个文件末尾都加一个空行

[*.md]
trim_trailing_whitespace = false        # .md 文件不去掉每行末尾的空格

husky

GitHook 工具, 结合 eslint,对提交到仓库的代码进行 eslint 检查和修复

运行命令

# 安装哈士奇
npm install husky -D
# 添加 prepare 命令
npm set-script prepare "husky install"
# prepare 创建 bash 脚本,安装 git hooks
npm run prepare
# 添加 pre-commit 的 git hook 脚本
npx husky add .husky/pre-commit "npx eslint src --fix"

运行之后会发现在 ./.husky/pre-commit 里看到 git commit 前会运行的脚本:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# git commit 前先 eslint fix 一波
npx eslint src --fix

但是这样的命令会让每次 commit 前都把整个 src 都扫描并 fix 一次,速度太慢了,而且很容易把别人的屎山也 fix 掉,然后提交上去。

lint-staged

我们更希望只针对提交的文件进行 Lint 操作,可以使用 lint-staged

Lint-staged 仅仅是文件过滤器,检查本次提交所修改(指 git 暂存区里的东西)的问题

安装

npm i -D lint-staged

然后添加 .lintstagedrc.js 配置文件,里面对提交不同的文件进行 eslint --fix 操作。

.lintstagedrc.js

module.exports = {
  "**/*.{ts,tsx,js,jsx}": [
    "eslint --cache --fix --cache-location ./node_modules/.cache/.eslintcache",
  ],
  "**/*.vue": [
    "eslint --cache --fix --cache-location ./node_modules/.cache/.eslintcache",
  ],
  "**/*.{css,less}": [
    "stylelint --cache --fix --cache-location ./node_modules/.cache/.eslintcache",
  ],
};

lint-staged 配置的含义是对提交上来不同类型的文件执行对应的 lint fix 命令。

最后在刚刚创建的 ./.husky/pre-commit 里改成执行 lint-staged 命令:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged

以后每次 commit 前都会跑一次 lint-staged,而 lint-staged 又会对提交的文件进行 ESLint Fix。

commitizen 和 commitlint

  • commitizen:基于 Node.js 的 git commit 命令行工具,辅助生成标准化规范化的 commit message。
  • cz-git:一款工程性更强,轻量级,高度自定义,标准输出格式的 commitizen 适配器
  • commitlint:commitlint 校验提交信息
  • @commitlint/config-conventional:commitlint 规则集

对 git commit 按照统一的风格来提交,这样可以快速定位每次提交的内容,方便之后对版本进行控制。

安装

npm install commitizen cz-git @commitlint/config-conventional @commitlint/cli -D

在 package.json 中配置

"config": {
    "commitizen": {
      "path": "node_modules/cz-git"
    }
  }

增加 .commitlintrc.js 配置文件

// .commitlintrc.js
/** @type {import('cz-git').UserConfig} */
module.exports = {
  rules: {
    // @see: https://commitlint.js.org/#/reference-rules
  },
  extends: ["@commitlint/config-conventional"],
  prompt: {
    alias: { fd: "docs: fix typos" },
    messages: {
      type: "Select the type of change that you're committing:",
      scope: "Denote the SCOPE of this change (optional):",
      customScope: "Denote the SCOPE of this change:",
      subject: "Write a SHORT, IMPERATIVE tense description of the change:\n",
      body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
      breaking:
        'List any BREAKING CHANGES (optional). Use "|" to break new line:\n',
      footerPrefixesSelect:
        "Select the ISSUES type of changeList by this change (optional):",
      customFooterPrefix: "Input ISSUES prefix:",
      footer: "List any ISSUES by this change. E.g.: #31, #34:\n",
      confirmCommit: "Are you sure you want to proceed with the commit above?",
    },
    types: [
      { value: "feat", name: "feat:     A new feature", emoji: ":sparkles:" },
      { value: "fix", name: "fix:      A bug fix", emoji: ":bug:" },
      {
        value: "docs",
        name: "docs:     Documentation only changes",
        emoji: ":memo:",
      },
      {
        value: "style",
        name: "style:    Changes that do not affect the meaning of the code",
        emoji: ":lipstick:",
      },
      {
        value: "refactor",
        name: "refactor: A code change that neither fixes a bug nor adds a feature",
        emoji: ":recycle:",
      },
      {
        value: "perf",
        name: "perf:     A code change that improves performance",
        emoji: ":zap:",
      },
      {
        value: "test",
        name: "test:     Adding missing tests or correcting existing tests",
        emoji: ":white_check_mark:",
      },
      {
        value: "build",
        name: "build:    Changes that affect the build system or external dependencies",
        emoji: ":package:",
      },
      {
        value: "ci",
        name: "ci:       Changes to our CI configuration files and scripts",
        emoji: ":ferris_wheel:",
      },
      {
        value: "chore",
        name: "chore:    Other changes that don't modify src or test files",
        emoji: ":hammer:",
      },
      {
        value: "revert",
        name: "revert:   Reverts a previous commit",
        emoji: ":rewind:",
      },
    ],
    useEmoji: false,
  },
};

使用 husky 生成 commit-msg 文件,验证提交信息:(对提交信息进行拦截)

npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"

这个时候就可拦截了,可以自定义代码提交风格


liangzn
31 声望2 粉丝