Git lint 相关 发表于 2024-09-10 更新于 2024-09-10
字数总计: 2.6k 阅读时长: 10分钟 阅读量:
前言 在 集成 lint 代码规范工具 中,已经集成了对项目代码的检查,但这并不是强制的,可能没有在编辑器中配置 ESLint,或者忽视了命令行中的错误提示,导致错误的代码被提交到仓库中。
我们需要在 Git 提交代码前,通过 Git Hooks 强制对代码进行增量检查 (每次都进行全量 lint 检查是非常耗时的)。并配置 commitlint 对提交信息也进行检查。
示例仓库:qxchuckle/monorepo-test
参考:【从 0 到 1 搭建 Vue 组件库框架】3. 集成 lint 代码规范工具 一文带你彻底学会 Git Hooks 配置 [Git Hooks] 在代码提交前自动格式化代码 (前端工程化配置) 使用commitlint校验git commit message commit规范+commitlint+CHANGELOG自动生成一条龙服务 【前端】代码Git提交规范之约定式提交和Commitizen简化提交流程
commitlint commitlint 用于规范化 Git 提交信息。
安装 1 pnpm i -wD @commitlint/config-conventional @commitlint/cli
在根目录创建 commitlint.config.mjs
,继承默认的 @commitlint/config-conventional 规范集。(这些个 lint 工具的配置文件长得都大差不差)。
安装 @archoleat/commitlint-define-config 以获得配置提示。
commitlint.config.mjs 1 2 3 4 5 import { defineConfig } from '@archoleat/commitlint-define-config' ;export default defineConfig ({ extends : ['@commitlint/config-conventional' ], });
@commitlint/config-conventional
规定了 Conventional Commits 式的提交信息,详见 Git 规范与实践 。
gitmoji 如果你使用了 gitmoji ,可以继承 commitlint-config-gitmoji 配置。
Git Hooks commitlint 无法单独使用。因为提交信息发生在 git commit 阶段,而 git commit 时,控制台已经被占用,我们无法输入其他命令。
但 Git 提供了 Git Hooks 功能,它能在特定的重要动作发生时触发自定义脚本。 可以在 commit 动作发生时执行 commitlint 脚本,通过 commit-msg 钩子判断所提交的信息是否符合规范。
Hook 就是在执行某个事件之前或之后进行一些其他额外的操作。
Git Hooks 的实现非常简单,就是就 .git/hooks 文件下,保存了一些对应阶段的 shell 脚本文件 ,其中默认存在的 .sample
文件是示例文件,将该后缀去掉,如 pre-commit 文件,就是钩子文件了,Git 会在特定阶段自动执行对应的脚本文件 。
Husky 我们当然可以手动创建这些钩子文件,但是 .git 文件夹并不会被提交到仓库中,其他人在 clone 项目时,无法使用这些钩子。
这就需要使用 Husky 来管理、配置钩子了。
1 2 pnpm i -wD husky npx husky init
这会在项目根目录创建 .husky
文件夹,里面存放了一些和 Git Hooks 同名的钩子文件。并将 core.hooksPath 配置为该文件夹。初始化完成时只有 pre-commit 文件。
其原理很清晰明了,操作钩子时,只需在 .husky
文件夹中操作对应的文件即可。当然可以使用系统自带的 echo 等命令完成,看个人喜好。
1 echo "npm test" > .husky/pre-commit
此外,初始化时还会修改 package.json 文件,添加 scripts.prepare
脚本,以在 npm 安装依赖前执行 husky 命令,用于正确配置 core.hooksPath 为 .husky
文件夹。
package.json 1 2 3 4 5 { "scripts" : { "prepare" : "husky" } }
配置 commit-msg 钩子 添加 .husky/commit-msg 文件,调用 commitlint 进行检查。
.husky/commit-msg 1 2 3 4 5 6 7 #!/usr/bin/env sh npx --no -- commitlint --edit $1
现在,不规范的提交将被拒绝。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 > git commit -m "测试不规范提交" ⧗ input: 测试不规范提交 ✖ subject may not be empty [subject-empty] ✖ type may not be empty [type-empty] ✖ found 2 problems, 0 warnings ⓘ Get help : https://github.com/conventional-changelog/commitlint/ husky - commit-msg script failed (code 1) > git commit -m "test: 测试规范提交" [main 1bd745a] test : 测试规范提交 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .husky/commit-msg delete mode 100644 .husky/pre-commit
lint-staged 实现增量检查 目前的 ESLint 、Stylelint 都是全量检查,这是耗时且不必要的,因为往往只有修改后即将提交的文件才需要检查。
很容易想到的是配合 Git 实现增量检查,即只检查 staged(暂存区) 的文件。lint-staged 就是这样一个工具。
安装
lint-staged 支持通过 glob 模式匹配,对暂存区的文件列表进行分类过滤,以实现对不同的文件应用不同检查的效果。
创建 lint-staged.config.mjs
配置文件。
lint-staged.config.mjs 1 2 3 4 5 6 7 8 9 10 export default { '**/*.{js,jsx,tsx,ts}' : ['eslint --fix' ], '**/*.{scss,css}' : ['stylelint --fix' ], '**/*.vue' : ['eslint --fix' , 'stylelint --fix' ], '**/*' : ['prettier --write' ], };
配置 pre-commit 钩子 lint-staged 要处理的是暂存区文件,所以需要使用 Git 的 pre-commit 钩子,实现在 commit 发生之前对发生变化的文件进行 Lint 扫描,若 Lint 抛出错误,说明此次准备提交的文件存在代码规范的问题,提交失败。
这需要我们再次用到 husky。
.husky/pre-commit 1 2 #!/usr/bin/env sh npx --no -- lint-staged
现在提交代码时,会检查并尝试修复暂存区的文件。
commitizen 配合 VSCode 可以使用 Conventional Commits 、git-commit-plugin 等插件快速生成符合 Angular 团队规范 的提交信息。
而命令行工具更加通用,commitizen 提供 cz 命令替代 commit 命令,它会引导开发者通过一系列问题来填写提交信息,确保提交信息符合规范。
安装 1 2 npm i -g commitizen pnpm i -wD commitizen
还需要安装额外的适配器,否则 repo 就不是对 Commitizen 友好的,git cz 的工作方式会与 git commit 完全相同。
cz-conventional-changelog 是 commitizen 的首选适配器。
1 pnpm i -wD cz-conventional-changelog
编辑 package.json 文件,添加 config.commitizen 字段,指定适配器。
package.json 1 2 3 4 5 6 7 8 "scripts" : { "commit" : "cz" } "config" : { "commitizen" : { "path" : "cz-conventional-changelog" } }
现在,使用 pnpm run commit
命令提交代码,会引导你填写符合规范的提交信息。
1 2 3 4 5 6 7 8 9 10 > pnpm run commit cz-cli@4.3.0, cz-conventional-changelog@3.3.0 ? Select the type of change that you're committing: (Use arrow keys) > feat: A new feature fix: A bug fix docs: Documentation only changes style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) refactor: A code change that neither fixes a bug nor adds a feature perf: A code change that improves performance test: Adding missing tests or correcting existi
更换适配器 cz-conventional-changelog 适配器提示信息都是英文的,不能自定义配置,我们使用更灵活的 cz-customizable 适配器。
1 pnpm i -wD cz-customizable
更换适配器:
package.json 1 2 3 4 5 "config" : { "commitizen" : { "path" : "cz-customizable" } } ,
在 root 下新建 .cz-config.js
配置文件,配置适配器。配置选项文档 。
吐槽,.cz-config.js 只能是 CJS 模块,因为 cz-customizable 用的是 require 引入。
.cz-config.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 module .exports = { types : [ { value : 'feat' , name : 'feat: 新功能' , }, { value : 'fix' , name : 'fix: 修复bug' , }, { value : 'init' , name : 'init: 初始化' , }, { value : ':pencil2: docs' , name : 'docs: 文档变更' , }, { value : 'style' , name : 'style: 代码的样式美化' , }, { value : 'refactor' , name : 'refactor: 重构' , }, { value : 'perf' , name : 'perf: 性能优化' , }, { value : 'test' , name : 'test: 测试' , }, { value : 'revert' , name : 'revert: 回退' , }, { value : 'build' , name : 'build: 打包' , }, { value : 'chore' , name : 'chore: 构建/工程依赖/工具' , }, { value : 'ci' , name : 'ci: CI related changes' , }, ], messages : { type : '请选择提交类型(必填)' , customScope : '请输入文件修改范围(可选)' , subject : '请简要描述提交(必填)' , body : '请输入详细描述(可选)' , breaking : '列出任何BREAKING CHANGES(可选)' , footer : '请输入要关闭的issue(可选)' , confirmCommit : '确定提交此说明吗?' , }, allowCustomScopes : true , allowBreakingChanges : ['feat' , 'fix' ], subjectLimit : 72 , };
再次运行,现在可以看到自定义的提示信息。cz -> lint -> commit,一套流程行云流水。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 > pnpm run commit > pnpm-workspace-test@ commit C:\chuckle\qx\study_demo\Monorepo\pnpmWorkspaceTest > cz cz-cli@4.3.0, cz-customizable@7.2.1 All lines except first will be wrapped after 100 characters. ? 请选择提交类型(必填) feat: 新功能 ? 请简要描述提交(必填) 集成 commitizen ? 请输入详细描述(可选) ? 列出任何BREAKING CHANGES(可选) ? 请输入要关闭的issue(可选) feat(custom): 集成 commitizen ? 确定提交此说明吗? Yes [STARTED] Preparing lint-staged... [COMPLETED] Preparing lint-staged... [STARTED] Running tasks for staged files... [STARTED] lint-staged.config.mjs — 3 files [STARTED] **/*.{js,jsx,tsx,ts} — 1 file [STARTED] **/*.{scss,css} — 0 files [STARTED] **/*.vue — 0 files [STARTED] **/* — 3 files [SKIPPED] **/*.{scss,css} — no files [SKIPPED] **/*.vue — no files [STARTED] eslint --fix [STARTED] prettier --write [COMPLETED] prettier --write [COMPLETED] **/* — 3 files [COMPLETED] eslint --fix [COMPLETED] **/*.{js,jsx,tsx,ts} — 1 file [COMPLETED] lint-staged.config.mjs — 3 files [COMPLETED] Running tasks for staged files... [STARTED] Applying modifications from tasks... [COMPLETED] Applying modifications from tasks... [STARTED] Cleaning up temporary files... [COMPLETED] Cleaning up temporary files... [main c0c24d9] feat(custom): 集成 commitizen 3 files changed, 815 insertions(+) create mode 100644 .cz-config.js
CHANGELOG 自动生成 CHANGELOG 用于记录项目所有的 commit 信息并归类版本。
可以使用 VSCode 插件 whatchanged 或 commit-and-tag-version 、conventional-changelog 自动生成 CHANGELOG。