开发过程代码管理 -- husky+lint

582 阅读26分钟

介绍

本文主要介绍学习在项目开发时,保持团队中的编码规范以及提交信息的规范,便于团队对代码的管理可追溯可管理的过程。主要分为编辑器的配置以及eslit规范和husky的集成,和后续在服务器进行验证的过程。

编辑器配置

不同的编辑器有不同的默认行为,同一款编辑器在不同的操作系统上也会有不同的表现。不同的开发者也会有自己的喜好。

如:

  • 有的人习惯Tab键 缩进,有的人习惯使用 4个空格
  • 缩进间距有的人习惯使用 2个空格,有的人习惯使用 4个空格。
  • window系统中的换行符是\r\n, Linux 系统中的换行符是\n
  • ....

.editorconfig消除编辑器之间的差异

推荐使用 EditorConfig。EditorConfig 可以在不同平台的不同编辑器之间维护一致的公共配置。

使用EditorConfig 需要在项目中提供.editorconfig文件。
在根目录下和子目录下可以同时存在.editorconfig文件子目录的优先级更高
而位于根目录的.editorconfig文件需要将root配置设置为 true(最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件)。

用于通配符匹配的节名中识别的特殊字符:

特殊字符含义示例
*匹配任何字符串,除了路径分隔符(/)*.html [*.js]
**匹配任何字符串/**
?匹配任何单个字符-
[name]匹配名称中的任何单个字符[pageage.json] 对该文件指定规则
[!name]匹配任何不是名字的单个字符-
{s1,s2,s3}匹配给定的任何字符串(由逗号分隔)(自EditorConfig Core 0.11.0起可用){*.{js,html}}
{num1..num2}匹配num1和num2之间的任何整数,其中num1和num2可以为正或负-

编辑器支持情况: WebStorm默认支持 EditorConfig; VS Code 和 Sublime 要配置 EditorConfig 插件;例如:VS Code 需要配置 EditorConfig for VS Code image.png

配置示例:

    # EditorConfig is awesome: https://editorconfig.org

    # top-most EditorCOnfig file
    # 根目录的配置
    root = true                         # 根目录的配置文件,编辑器会由当前目录向上查找,如果找到 `roor = true` 的文件,则不再查找

    [*]                                 # 匹配所有文件
    indent_style = space                # 空格缩进 缩进类型(tab是硬缩进,space为软缩进)
    indent_size = 4                     # 缩进空格为 4个
    end_of_line = lf                    # 文件换行符是 linux 的 `\n`
    charset = utf-8                     # 文件编码是 utf-8
    trim_trailing_whitespace = true     # 不保留行末的空格
    insert_final_newline = true         # 文件末尾添加一个空行

    curly_bracket_next_line = false     # 大括号不另起一行
    spaces_around_operators = true      # 运算符两遍都有空格
    indent_brace_style = 1tbs           # 条件语句格式是 1tbs
    spaces_around_brackets              # 表示括号和括号之间应有空格:无空格,仅在括号内,仅在括号外或在括号的两侧 (none,inside,outside,both)
    max_line_length                     # 在指定的字符数后强制换行。off关闭此功能
    [*.js]                              # 对所有的 js 文件生效
    quote_type = single                 # 字符串使用单引号

    [*.{html,less,css,json}]            # 对所有 html, less, css, json 文件生效
    quote_type = double                 # 字符串使用双引号

    [pageage.json]                      # 对 package.json生效

优点:

  1. 广泛性:对 vs code, webstorm, atom, ide, visualstudio ... 等都支持;
  2. 配置简单;
  3. 统一:规范常用的,基本的代码要求;

局限:

  1. 不够灵活;不能配置 trim_trailing_semicolon 等;
  2. 和其他格式化工具,例如: eslint, prettier 等配置容易冲突;

editorconfig 只能解决少数基本风格问题,实际在项目用很少使用这种方式;

代码风格格式化

使用Prettier

Prettier是什么?

  • 一个 "有态度","有主见" 的代码格式化工具;(这就意味着代码风格是设置好的)
  • 支持大量编程语言;
  • 已集成到大多数编辑器中;
  • 几乎不需要设置参数;

为什么使用Prettier?

  • 按保存键,代码就被格式化了;
  • 代码评审时无须争论代码样式;
  • 节省时间和精力;

Prettier是一个代码格式化插件,它并不关心你的语法是否正确,只关心你的代码格式,比如是否使用单引号,语句结尾是否使用分号等。但是部分规则和ESLint有冲突?

前置工作 创建干净的demo工程(以vue create xxx)为例:选择不安装任何的 ()linter / formatter;后面我们自己手动安装prettier。

在项目工程中安装 prettier

    npm install --save-dev --save-exact prettier || yarn add --dev --exact prettier

使用prettier格式化项目工程中所有文件。

    npx prettier --write .  || yarn prettier --write .

VS Code 编辑器

image.png Prettier 几乎不需要配置,是开箱即用的也不鼓励自定义样式但是还是提供了少量的配置项可以更改。 如需配置则需要在 根目录下创建 .prettierrc.json;
创建 .prettierrc.json 可以制定规则,同时也告诉其他工具我们使用的是prettier;
创建 .prettierignore 让编辑器和CLI知道哪些文件不需要被格式化;

    # .prettierignore
    # Ignore artifacts:
    build
    coverage

image.png

使用 npx prettier --write .yarn prettier --write . 格式化工程内的文件; image.png image.png

这样每写完一些代码都要去运行命令格式化代码,很麻烦,有没有在保存时自动格式化代码呢?


VS Code 集成 Prettier

使用 vs code 编辑器,有没有办法在写代码时,保存后自动按照 prettier的规则格式化?

ctrl + s保存时自动格式化代码:

  1. vscode中配置并启用了 Prettier - Code formatter 扩展
  2. 文件 -- 首选 -- 设置 -- 工作区 -- 格式化 -- 勾选 Format On Save中勾选开启,此时在项目的根目录会生成.vscode/settings.json 文件;
  3. 在 .vscode/settings.json中配置:"editor.defaultFormatter","editor.formatOnPaste", "esbenp.prettier-vscode" image.png image.png
    {
      "editor.formatOnSave": true, // 在保存时格式化文件
      "editor.formatOnPaste": true// 控制编辑器是否自动格式化粘贴的内容。
      "editor.defaultFormatter": "esbenp.prettier-vscode"
    }

配置结束后,保存时会自动格式化代码 vs-code-prettier.gif


虽然编辑器自动格式化可以提升编程体验,但是不能保证代码风格一致,存在编辑器可能不支持Prettier的情况,如果用户使用的编辑器和设置的不一样等,除了可以和编辑器集成,Prettier还可以和Git集成,在使用 Git 提交时,可以将提交文件自动格式化。

Webstorm 中 Prettier 配置

使用webstorm为编辑器,如何在开发时保存代码自动格式化? git提交代码时自动格式化呢? 在保存时根据prettier自动格式化代码

第1步:下载 Prettier 插件 image.png

第2步:配置Prettier image.png

此时在编写代码保存时就能自动格式化;如果需要自定义配置项,需要在项目根目录.prettierrc.json中配置;其余 Git Hooks 配置和上述 pretty-quick方式

Prettier方式的Git Hooks

npm: pretty-quick,也可以使用 npm 介绍的方式安装。

原理: 其原理是Git自身提供的hook功能。每次在提交之前,Git都会检查是否存在 pre-commit hook,如果存在,则会自动执行其中的命令。在 pre-commit hook 中加入格式化的命令,就可以实现提交时自动格式化。

但是现在存在以下两个问题:

  • 问题一:
    直接运行npx prettier --write . 命令会将这个工程项目格式化。比较好的做法是 只格式化本次提交的文件pretty-quick 工具可以实现选择性格式化,其有很多参数, --staged可以实现只格式化待提交的文件
  • 问题二:
    需要添加 pre-commit hook,并加入格式化的代码,这可能需要对hook 和命令行有一些了解,还要处理跨平台的问题,同时需要将写好的hook让每一名用户都安装。 husky 是一个包,只需要简单安装,就可以给Javascript项目带来使用hook的功能

前置工作: 先执行 git init 在目录中创建新的 Git 仓库; 会生成 .git 隐藏文件夹;

第1步: husky安装

husky4.x 和 husky7.x的安装方式有非常大的差异。 husky支持自动 和 手动 两种安装方式。 husky 是一个 git hook 工具,可以帮助我们在 git 操作之前与之后可设置自动执行的脚本,像:pre-commitcommit-msgpre-push 等等支持的 git hooks。

安装 husky7.x 为例: 自动安装只需要运行下面一条快捷安装命令即可:

    # 自动安装方式:
    npx husky-init

手动安装需要3个步骤:

    # 1. 安装依赖
    npm install husky --save-dev
    
    # 2. 初始化 husky配置
    npx husky install
    
    # 3. 设置 prepare. 这样就会自动执行 2
    npm set-script prepare "husky install"

选择上面任意一种安装方式完成 husky 的安装后,会在 package.json 中会添加如下代码:

    {
        "scripts": {
            "prepare": "husky install"
        }
    }

同时会多出一个 .husky目录,其中的 pre-commit 就是我们要用到的 Git hook; husky 会将 Git 的 hooksPath配置.git/hook 修改为 .husky。如果其他流程有依赖Git hook,则可能需要注意 hook 的路径变化问题,可以看到 hooksPath的配置
在 .git/config中查看:
husky-init 前: image.png husky-init 后: image.png

第2步:preety-quick安装配置

preety-quick 安装命令:

    # preety-quick 安装命令:
    npm install --save-dev pretty-quick
    # 使用 yarn
    yarn add --dev pretty-quick

通过如下命令将 pretty-quick 添加到 hook 中。

    # 通过如下命令将 pretty-quick 添加到 hook 中。
    npx husky set .husky/pre-commit "npx pretty-quick --staged"

此时打开 .husky/pre-commit 文件,该文件中的内容如下,也可以不使用 "husky set"命令,直接修改这个文件

    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    
    # npm test
    npx pretty-quick --staged

使用文本编辑器修改了代码;提交代码,即可体验提交时自动格式化的效果(提交代码自动格式化)。

image.png commit时,自动修复格式化: image.png


集成 Git Hooks 遇到的问题:

  • 用命令commit的描述 "要用双引号" --> 错误X:git commit -m 'xxx'; 正确: git commit -m "xxx"
  • 如果commit提交失败或者没有格式化效果; -- 检查 .husky/pre-commit,是否存在npx pretty-quick --staged以及package.json中的 scripts: {prepare: "husky install"} image.png

使用ESLint

ESLint 可组装插件化的JavaScript和JSX检查工具, ESLint是在ECMAScript/JavaScript代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误。

  • ESLint 使用 Espree 解析JavaScript。
  • ESLint 使用 AST 去分析代码中的模式。
  • ESLint 是完全插件化的。每一个规则都是一个插件并且你可以在运行时添加更多的规则。

前置工作 创建干净的demo工程(以vue create xxx)为例:选择不安装任何的 ()linter / formatter;后面我们自己手动安装eslint。

首先安装 ESLint 。

    # 安装 ESLint
    npm install eslint --save-dev

初始化eslint配置(会生成对应的配置文件)

    # 初始化 eslint配置
    npx eslint --init
    
    # 或者
    npm init @eslint/config

PS: 如果全局安装了eslit ,可以直接运行 eslint --init

image.png image.png image.png image.png image.png image.png image.png image.png image.png

初始化成功后,会在项目的根目录生成一个 .eslintrc.js 文件(这边是json还是js还是yml)要看你在init时候选择的配置文件类型。 image.png

VS Code 中配置ESLint

在 VS Code编辑器中 配置 ESLint

第1步:下载 ESLint 插件(必须) image.png Error Lens(可选的);可以显示错误信息在当前代码行后

具体配置看 GitHub: vscode-error-lens

image.png

第2步:编辑器配置 设置 --> 打开 settings.json 或者 直接打开 .vscode/settings.json image.png 添加如下配置:

    {
        // eslint配置:
        "eslint.enable": true,
        "eslint.run": "onType",
        "eslint.options": {
            "extensions": [
                ".vue",
                ".js",
                ".jsx",
                ".tsx",
                ".ts"
            ]
        }
    }

webstorm 启用eslint配置

在webstorm编辑器中启用eslint配置规则

image.png image.png

parserOptions配置

parserOptions 告诉ESLint 我们希望支持的ECMAScript语法,认情况下,ESLint支持ECMAScript5;如果代码中使用的语法和配置的语法不一致,那么ESLint在解析的时候就会报错。

env配置

env配置环境预置的全局变量,例:在env中设置 "browser":true; ESLint 就会支持在代码中使用浏览器环境的全局变量,而在把 browser 配置删除后,在代码中使用浏览器环境变量时,ESLint 就会报错。

rule检验规则的报错等级

每个检验规则有3个报错等级,0代表关闭, 1代表警告, 2代表错误,

例:下列配置开启了两个规则,一个是警告,另外一个是报错:

    module.exports = {
        rules: {
            quotes: 1,
            eqeqeq: 2
        }
    }

己选择要使用的规则并手动配置 rules 会比较麻烦,可以直接使用社区成熟的规则集。 目前,使用较多的是 ESLint(eslint:recommended) 官方的规范Airbnb的规范; 可以像下面这样通过 extends关键引入:

    module.exports = {
        extends: ['eslint:recommended']
    }

设置好 .eslintrc.js 文件后,运行如下的 "npx eslint ." 命令即可对代码进行检测: image.png image.png

从上面的结果可以发现,dist目录报错较多。dist目录存放编译后的代码,并不需要被检测。
解决办法: 白名单黑名单 的方式:
白名单方式:ESLint支持目录校验,修改命令,只校验指定的文件即可。例: npx eslint 指定目录 image.png

黑名单方式:新建.eslintignore 文件,要被eslint忽略的文件配置在其中即可; image.png

发现每次运行 npx eslit . 很麻烦,把这个命令配置到 package.json中;

    {
        "scripts": {
            "lint": "eslint src"
        }
    }

image.png

ESLint的校验规则``可以分 为两类,分别是 代码风格 代码质量
Prettier 更关心代码风格的(简单的理解是代码怎么写的横平竖直),ESLint 重点在于 管理代码质量的;关注代码的语法和质量;

在 VS Code 中启用 ESLint --> 搜索"ESLint" --> Settings.json中配置如果下代码,eslint生效:

    {
        "eslint.enable": true, // 开启eslint检查
        "editor.codeActionsOnSave": {
            // 使用eslint来fix,包括格式化会自动fix和代码质量检查会给出错误提示
            "source.fixAll.eslint": true
          }
    }

同时使用 Prettier+ESLint 它们规则冲突了,怎么办?

ESLint + Airbnb config 和 ESLint + Standard config都是成熟的 ESLint 规则集,如果 ESLint + Prettier是两种规则,如果配置规则冲突了怎么办?

场景:在 .prettierrc.json 中 修改配置规则:使用单引号:在 .eslintrc.js 中配置规则:默认是使用双引号;它们的规则冲突了;
修改 .prettierrc.json 中修改校验规则:"singleQuote": true 使用单引号规则; image.png 配置 eslint的 quotes 报错等级; eslint的quotes规则默认需要使用双引号后面的数字代表校验规则的报错等级(0代表关闭,1代表警告,2代表错误) image.png 此时使用 Prettier 来格式化代码 运行: npx prettier --write . 会格式化成单引号,但是 eslint 规则又要求使用 双引号,此时代码看起来是:prettier格式化成单引号成功了。但是eslint又要求是双引号,又报错了; image.png

解决:使用 eslint-plugin-prettier + eslint-config-prettier;

下面介绍两款可以解决规则冲突的 ESLint 插件,分别是 eslint-plugin-prettiereslint-config-prettier

eslint-plugin-preitter 可以让 ESLint 对 Prettier 的代码风格进行检查,如果发现不符合 Prettier 代码风格的地方就会报错,其原理是先使用Prettier对代码进行格式化,然后与代码格式化之前的代码进行对比,如果不一致,就会报错。

eslint-config-prettier是一个规则集,其作用是把ESLint中 和 Prettier 的规则冲突的规则都关闭。

第1步:首先安装 eslint-plugin-prettiereslint-config-prettier

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

第2步:修改 ESLint 配置文件 .eslintrc.js

如果有带, 'plugin:vue/vue3-essential' 先去除,全部使用 eslint 和 prettier规则。

    // .eslintrc.js
    module.exports = {
      env: {
        browser: true,
        es2021: true,
      },
      extends: ['eslint:recommended', 'prettier'], // ++++++
      overrides: [],
      parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module',
      },
      plugins: ['vue', 'prettier'], // ++++++
      rules: {
        'prettier/prettier': 'error', // ++++++
      },
    };

eslint-config-prettier提供了一种简洁配置:

    module.exports = {
        extends: ['eslint:recommended', 'plugins:prettier/recommended'],
    }

此时使用 npx prettier --write .格式化代码,eslint就不会报错了;


Git提交时自动运行ESLint

如果能够在Git提交时自动运行ESLint,就可以多一层代码质量保证;

直接使用前面提到的 husky,如果在 .husky/pre-commit 文件中添加 npm run lint 命令,就可以在每次提交时都校验整个项目。但是如果项目较大,则执行校验会非常缓慢,从而导致提交时会卡住很近,而且不在本次提交的代码可能还未开发完成。这时解决ESLint问题是没有意义的。
注: npm run lint, lint命令需要在 package.json中配置 eslint 要检测的目录 image.png
如果只对本次提交的代码进行校验呢?可以使用LintStaged工具LintStaged不仅可以对指定文件运行指定命令,还可以根据命令结果终止提交。

LintStaged工具

ESLint的Git Hooks使用 lint-staged工具;npm: lint-staged

前置工作: 先执行 git init 在目录中创建新的 Git 仓库; 会生成 .git 隐藏文件夹;

第1步:安装 husky 和 lint-staged

    # npm 方式安装 如果已经安装了 husky 安装 lint-staged即可
    npm install --save-dev husky lint-staged
    
    # yarn 如果已经安装了 husky 安装 lint-staged即可
    yarn add --dev husky lint-staged

第2步:在项目的根目录新建LintStaged配置文件, .lintstagedrc.js 并做相关配置

**/*.js 指定为 js 文件; **/*:所有文件

    module.exports = {
        '**/*': ['eslint --cache'],
    }

第3步:修改 .husky/pre-commit文件,在该文件中添加lint-staged校验。

如果没有该文件使用 npx husky-init 初始化; 运行命令:(注意node版本不同命令也会略有区别):

    # 生成 .husky 文件夹
    npx husky install
    
    # 在 pageage.json中的 scripts 添加 prepare命令(即 npm run prepare)
    #  <= node 16 运行:
    npm set-script prepare "husky install"
    # >= node16+ 运行:
    npm pkg set scripts.prepare="husky install"
    # 运行了 npm pkg 其实已经在package.json中的scripts 写入了 "prepare": "husky install" 命令
    # 我们也可以运行 npm run prepare 生成 .husky 文件夹
    
    # 往 .husky下添加pre-commit,并写入 npx lint-staged
    npx husky add .husky/pre-commit "npx lint-staged"

.husky/pre-commit 文件最终内容:

    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    # 安装了pretty-quick
    npx pretty-quick --staged
    npx lint-staged

image.png

结果:
此时修改 src/main.js,写入一行代码 const a = "1"; 会报两个错误:1. 定义的变量a未被使用;2. 是双引号,应该使用单引号; image.png 尝试的去commit代码,看看是否会触发 git hooks,代码是否被改变? 为了防止vscode自动保存格式化;我们使用文本编辑器写入代码并保存; image.png

运行commit,并查看输出结果:提交失败,并提示ESLint校验失败,此时 src/main.js 已经从双引号 被格式化成 单引号了。 image.png

vue create 命令已集成 lint

现代的cli工具已经集成了 linter / formatter Config,不用再去关心繁琐的配置过程了;

vue create xxx cli创建项目为例:会让我们选择 linter / formatter,有如下三种方式:

image.png 我们选择 ESLint + Prettier: image.png 选择 In dedicated config files 定义专用的配置文件,在根目录下生成对应的配置文件; image.png 会在根目录下生成 .eslintrc.js image.png

linter 预设规则有如下几种:

  • ESLint + Airbnb config:
    Airbnb 规范的 eslint 实现: 是其中一个最流行的 JavaScript 代码规范,它差不多包含所有 JavaScript 的角度。校验比较严格。
    以vue项目为例:.eslintrc.js中的配置如下: image.png

  • ESLint + Standard config:
    Standard 规范:标准的 JavaScript 代码规范,自带 linter & 代码自动修正;
    以vue项目为例:.eslintrc.js中的配置如下: image.png

  • ESLint + Prettier:
    Prettier是代码格式化插件:,它不关心语法,只关心代码格式是否统一规整;配合ESLint管理代码质量prettier和eslint的部分规则有冲突
    image.png

规则越多,产生的冲突可能性也会多。vue项目默认还好继承 vue3-essential 的规则,这时候需要多个规则去平衡调和代码风格和质量,例如 .prettier.json, .eslintrc.js ;

规范提交信息的意义

Git每次提交代码,都要写提交信息。一般来说,提交信息需要清晰明了,说明本次提交的目的,但是不同的人对"清晰明了" 会有vu容妃守卫理解和习惯,对于多数人协作的项目来说,这可能会成为一个挑战。

统一提交信息格式可以带来很多好处,示例如下:

  • 规范的约束作用,避免出现毫无意义的提交信息,如update、commit、temp等。
  • 规范的提交信息,在对log分类、检索时更方便。
  • 当生成变更日志时,可以直接从提交信息中提取。

统一提交信息,首先需要一个统一规范。规范来源于实践,社区中存在一些最佳实践,使用比较多的是Conventional Commits 中文叫约定式提交是一种用于给提交信息添加可读含义的规范。

约定式提交规范是一种基于提交信息的轻量级约定,它提供了一个组简单规则来创建清晰的提交记录。 约定式提交规范推荐的提交信息的结构如下:

    <type>[optional scope]: <description>
    [optional body]
    [optional footer(s)]

上述规范中常用的部分包括 type、description 和 body。


一个典型的提交信息示例如下:

    feat: 添加ESLint环境

    1. 添加ESLint环境
    2. 支持VS Code ESLint插件
    3. 支持Git 提交时自动执行ESLint

type 用来对提交进行分类Conventional Commits 规范只提到了 fix 和 feat,
@commitlint/config-conventionalAngular 团队在使用的 基于 Conventional Commits 规范的扩展规则,其中带来了更多语义的type值
常用的type值如下:

  • feat: 开发新的功能
  • fix: 修复bug,不改变功能
  • docs: 修改文档
  • style: 修改代码样式,不修改逻辑
  • refactor: 重构代码逻辑,不修改功能
  • test: 修改测试代码

Conventional Commits 规范和语义化版本是兼容的,对应关系如下:

SemVerConventional Commits
Patch(修订号),向下兼容的问题修改正type的值为 fix
Minor(次版本号),向下兼容的功能性新增type的值为 feat
Major(主版本号),不兼容的API修改type的值最后加 !脚注中包含 BREAKING CHANGE

根据上述对应关系,示例提交信息如下:
修改 Patch 版本号,对应的提交信息,示例如: fix: 修改utils中的对象拷贝bug
修改 Minor 版本号,对应的提交信息,示例如: feat: 修改拷贝函数添加参数控制
修改 Major 版本号,对应的提交信息,示例如:

    # 例子1:
    feat!: 功能改变了,会影响已经引用的。
    
    # 例子2:
    feat: 功能改变了,不兼容以前的代码。
    BREAKING CHANGE: 拷贝传参改变了

有了规范,大家都遵守才有意义,我们引入校验工具 commitlint 来校验提交信息。


Lint检查和规范提交(完整版)

使用eslint规范开发过程代码质量,提交的时候怎么保持统一的提交格式规则呢 ?

分为两部分进行:
第一部分:使用 lint-staged,做提交前(pre-commit)的lint校验;
第二部分:使用 commitizen + commitlint规范提交信息(commit-msg);

上面讲了: husky 是一个 git hook 工具,可以帮助我们在 git 操作之前与之后可设置自动执行的脚本,像:pre-commitcommit-msgpre-push 等等支持的 git hooks。

原理:其实就是使用 husky 来创建2个钩子(pre-commit 和 commit-msg),

  1. pre-commit提交前钩子,然后执行lint-staged进行代码eslit校验;
  2. 创建commit-msg,进行提交信息的规范校验

准备创建示例项目
node版本: 16.15.1;
使用 vue create 命令创建项目:vue create xxxx;
linter formatter 选择:eslint + Airbnb config;

第一部分:使用 lint-staged,做提交前(pre-commit)的lint校验;

第1步:安装 husky 和 lint-staged:

    # 安装 husky 和 lint-staged:
    npm install --save-dev husky lint-staged

第2步:创建 lint-staged配置文件:

lint-staged 支持多种格式,例: .lintstagedrc.json, .lintstagedrc.yaml, lint-staged.config.js or .lintstagedrc.js等;根据自己的项目路径和需要配置。具体看npm package。

    module.exports = {
        "src/**/*.{js,vue}": ['eslint --cache']
    }

image.png

第3步:修改 .husky/pre-commit文件,在该文件中添加lint-staged校验。 如果通过命令无法写入 npx lint-staged, 也可直接找到该文件,在该文件中修改亦可; image.png

    # 生成 .husky 文件夹
    npx husky install
    
    # 在 pageage.json中的 scripts 添加 prepare命令(即 npm run prepare)
    #  <= node 16 运行:会在package.json中的scripts 写入了 "prepare": "husky install" 命令
    npm set-script prepare "husky install"
    
    # >= node16+ 运行:
    npm pkg set scripts.prepare="husky install"
    
    # 运行了 npm pkg 会在package.json中的scripts 写入了 "prepare": "husky install" 命令
    # 我们也可以运行 npm run prepare 生成 .husky 文件夹
    
    # 往 .husky下添加pre-commit,并写入 npx lint-staged
    npx husky add .husky/pre-commit "npx lint-staged"

.husky/pre-commit 文件最终内容:

    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    # 安装了pretty-quick
    npx pretty-quick --staged
    npx lint-staged

我们尝试定义一个没有被使用的变量,根据在.lint-staged中配置的指定文件和eslint策略去检测。 结果如下: image.png

第二部分:使用commitizen + commitlint规范提交信息;

commitizen专注于提交信息的录入;commitlint 专注于提交信息的校验。

commitlint安装配置: 让 commitlint 专注于提交信息的校验。

第1步: 安装 commitlint

    # 安装 commitlint
    npm install --save-dev @commitlint/config-conventional @commitlint/cli

第2步:根目录新建配置文件 commitlint.config.js,并添加相关内容:

    module.exports = {
      extends: ['@commitlint/config-conventional'],
    };

注意:LFCRLF 的选择 image.png

第3步:使用命令 测试 commitlint 校验结果; 命令行运行 echo aaa | npx commitlint image.png

第4步:运行命令,将 commitlint 和 husky 集成。

运行这个明白之前,必须 安装了 husky, 项目内安装husky: npm install husky --save-dev typicode.github: husky文档

    # 先尝试执行
    npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
    
    # 如果上条命令没效果或出现 Usage: xxx ,再尝试执行这个
    node node_modules/husky/lib/bin add .husky/commit-msg 'npx --no -- commitlint --edit $1'

如果以上两条命令都没效果: 在window下运行命令出现了如下情况,请尝试重新手动安装Manual(手动安装)image.png

node node_modules/.bin/husky add Manual(手动安装)

    npm install husky --save-dev
    npx husky install
    npm pkg set scripts.prepare="husky install"
    # 看看package.json的scripts中是否有 prepare
    npm run prepare
    # 尝试执行下
    node node_modules/.bin/husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'

如果还是出现错误或帮助信息,则把 node node_modules/.bin/husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"' 拆分为 node node_modules/.bin/husky add .husky/commit-msg 执行,会在 .husky 生成 commit-msg; image.png package.json的scripts下有 prepare 字段: image.png

可以npm run prepare 会在根目录下 生成 .husky 文件夹 image.png 然后打开 ./husky/commit-msg, 把最下方的undefined替换成 npx --no -- commitlint --edit "$1"即可: image.png

随便写个描述信息,会提示提交信息校验不通过 image.png

输入提交信息后再校验,虽然能够保证提交信息符合规范,但是体验并不友好,而如果能够再输入时给出友好的提示,这样不仅可以提高通过率,还可以提高提交效率。

优化一:
commitlint 提供了 @commitlint/prompt-cli 询问式的交互录入命令。

  1. 安装: npm install --save-dev @commitlint/prompt-cli
  2. 修改package.json中的scripts字段新增 ci命令,使用 npm run ci 命令替换 git commit 命令,再次提交时会 有结构化的提醒和校验提示信息
    {
          "scripts": {
            "ci": "commit"
          }
    }

运行 npm run ci 结果如下:
image.png image.png

commitlint的交互虽然勉强够用,但是不是特别好用, commitizen 是一款专注于交互式的录入提交信息的工具,

优化二:, commitizen使用配置:commitizen专注于提交信息的录入

第1步:安装

    # 安装 commitizen
    npm install --save-dev @commitlint/cz-commitlint commitizen

第2步:修改package.json并配置 scripts 和 config :

    # package.json中添加:
    {
     "scripts": {
        "cz": "git-cz"
      },
      "config": {
        "commitizen": {
          "path": "@commitlint/cz-commitlint"
        }
      }
    }

第3步:使用npm run cz命令进行提交,commitizen提供了更丰富、友好的交互界面,提交结果如下: image.png image.png

这样每次使用命令提交的时候都会被要求要输入规范的提交信息才能提交。那如果我想用编辑器自带的git工具提交呢,或者想使用原始的git命令提交呢?

拓展:WebStorm编辑器插件

实际的开发中我们很少会使用 npm run xx脚本命令来提交代码的,都是在图形化的编辑器中直接点击或者快捷键提交的;如果我们使用编辑器自带的git来提交呢?

用 webstorm打开项目,我们删除了 package-locak.json, 不按规范填写提交下: image.png 这时肯定会被./husky/commit-msg检查到,是 一个不符合规范的描述 提交 image.png image.png 强烈推荐一个 webstorm的 Git 提交模板插件: Git Commit Template
使用 Git Commit Template 插件快捷提交:
安装插件: image.png 创建提交信息: image.png image.png OK 之后,会自动帮我填入 Commit Message中image.png commit成功后: image.png 生成了规范的commit信息: image.png

记录变更日志

每次发布新版本时都需要记录变更日志。历史提交信息是记录变更日志时的重要参考,在发布新版本之前需要手动查阅提交记录,整理变更日志。符合 Conventional Commits 规范的信息,可以使用 Standard Version 工具自动生成变更日志。

使用standard-version 工具可以自动生成变更日志。

第1步: 安装 standard-version

    # local安装
    npm install --save-dev standard-version

第2步: 使用 git log --oneline 查看提交记录如下: image.png

第3步:测试安装后的情况: 运行 npx standard-version --dry-run;

执行 standard-version 命令查看效果,参数 --dry-run 代表测试运行,并不会 修改 CHANGELOG.md 文件中的内容,控制台会输出 standard-version 命令整理的变更日志。

image.png

如果不加参数--dry-run, 那么standard-version的命令会进行如下操作:
(1) 修改版本号
🟢 修改 package.json 和 package-lock.json文件。
🟢 会根据type来决定升级哪个版本号。
🟢 因为有feat,所以将版本从1.0.0,升级到1.1.0.
(2) 修改CHANGELOG.md文件。
(3) 提交内容。
(4) 添加Git tag.

注意: 对我们有用的是操作(2),需要注意的是,CHANGELOG.md文件中只包含符合 Conventional Commits 规范的提交信息,不符合 Conventional Commits规范的提交信息会被自动过滤

CHANGELOG.md是 standard-version 用来记录变更命令的,运行命令会自动生成的。

第4步:为了方便执行脚本,在 package.json中配置 release 命令:

配置后,就可以 运行; 例:npm run release --dry-run

    {
         "scripts": {
            "release": "standard-version"
          }
    }

第5步:为你的第一个版本生成你的更新日志,

    npm run release -- --first-release

image.png

更多standard-version的命令和使用,请查看 standard-version

后话

规范需要和检查配合才能发挥更大的作用。目前在本地进行校验,依赖 Git hook 功能,然后使用 Git hook 校验存在被绕过的风险,本地校验的另一个问题是,协作时无法知道对方提交的代码是否符合规范,只有将代码下载到本地执行校验才可以获得校验结果。

Git 提交时会执行hook校验,如果添加参数 --no-verify, 则可以跳过 hook校验。
git commit -m "xxx" --no-vertify 就会跳过 git hook的校验;
image.png image.png

如果能够在服务上运行校验,既解决了 Git hook 校验可能被绕过的问题。 社区中有很多在服务器上运行测试和校验的服务。社区提供的服务叫做 持续集成服务

持续集成(Continuous Integration, CI) 是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成,每次集成都通过自动化的构建(包括编译、发布、自动化测试)来验证,从而尽早的发现集成错误。

后续持续集成...

参考:

EditorConfig官网
Prettier官网
ESLint中文官网
typicode.github: husky
npm package: pretty-quick
npm package: lint-staged
npm package: @commintlint/cli
npm package: @commintlint/config-conventional
npm package: standard-version