Nx添加pre-commit check能力

一个Repo的质量可以简单从其CommitMessage规范化就可以看出。

由于Nx所包含的东西太多,技术密度过高,在此介绍Nx将会花去大量篇幅,因此如有读者对Nx感兴趣,请阅读Nx Tutorial

本文为快速笔记,仅用于博主备忘,如读者对文章内容感兴趣,请仔细阅读拓展连接

Nx frontpage

最近在尝试写一个新项目时,使用了一个非常好用的Monoreps脚手架Nx,这个脚手架可以通过简单的几行命令搭建起主流的前端项目(包括全栈项目),Nx中所有项目模板均是以plugin的形式出现。Nx拥有主流前端开发环境项目generator,用户可以通过简单的 npx nx generate xxx就可以创建一个lib或者一个component等。

Nx GettingStart 中关于GenerateCode描述

基本前端主流的项目环境(比如Next.js、Vue、Angular、React等)均可以通过简单的npm install @nwrl/xxxx 进行快速项目搭建。同时community中拥有一些常见devkit的第三方plugin,比如storybook等。同时,开发者可以通过使用npx nx命令快速的创建component template和lib,而Nx将会为你管理好export等问题,开发者仅需要关注编程就可以了。下面为我使用Nx快速搭建的Next.js项目模板。

项目模板

可以看出,基本可以达到零配置开箱即用的状态,同时VisualStudioCode有一个为Nx设计的Nx Console插件,可以快速的运行Nx命令:

Nx Console使用Nx run命令时打开的配置栏

在此不再过多展开,本文专注于进行Nx项目CommitMessage规范化。

一、DevKit介绍

在开发过程中,在commit时如果没有任何pre-commit check进行干预的情况下,repository中可能会被commit一些没有lint、format的代码,同时commit message每个人有每个人的写法,导致查错困难。因此在项目中构建一套完整的pre-commit check体系是很有必要的。而本次将实现的整个CommitMessage规范化将以以下流程实现:

(一)、CommitMessage规范化

CommitMessage规范化有两个方面:

  1. 阻止不符合规范的CommitMessage提交(CommitLint)
  2. 自动生成规范的CommitMessage(Commitizen)

这两个方面构成了对提交信息的自动化检测和规划化生成,可以提高提交信息的可读性,在回溯差错时提供语义化规范化commit message,有巨大帮助。

1、CommitLint

CommitLint是用于对CommitMessage进行校验的DevKit,而CommitLint为我们提供了一个基于AngularContribute规范的规则集@commitlint/config-conventional,什么是Angular规范请自行百度。

(1)、安装

npm安装命令,直接将commitlint和augular规则集安装到devleop依赖

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

(2)、配置

在项目根目录下创建 commitlint.config.js用于制定使用 @commitlint/config-conventional规则集:

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

(3)、测试

在控制台中执行 npm commitlint "这是一个不规范的CommitMessage" 进行测试:

Commitlint测试

到此Commitlint就安装配置好了,但由于在单独使用情况下,commitlint仅仅只能使用以上命令进行lint,基本没有什么作用。但当其与一些git hooks包配合起来就会产生巨大的作用。这里接下来介绍Husky。

2、Husky

Husky是一种用于提供git hooks服务的DevKit,安装Husky后可以通过其提供的pre-commit hook快速添加校验命令。本文使用Husky v5 作为git hook provider。

(1)、安装

安装命令如下:

npm install husky --save-dev

(2)、配置

使用以下命令进行自动配置(npx readme):

npx husky init
执行结果

可以看到在项目根目录下新建了一个 .husky 文件夹,里面包含一个pre-commit文件,在pre-commit文件中使用者可以自行添加需要在git commit之前执行的命令,在此处即使用commitlint:

文件目录

添加commitlint命令($1 为 husky v4 中 HUSKY_GIT_PARAMS参数):

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

npx --no-install commitlint --edit "$1"
commitlint命令

(3)、测试

完成上述配置即可直接进行git commit 测试,commitlint和husky安装后将会拦截(hook)git commit操作,并对提交的commit message进行校验,如果校验失败则终止commit。

不符合规范的commit message测试

3、Commitizen

Commitizen是用于格式化生成CommitMessage的工具,通过commitizen+cz-customizable用户可以自定义Angular风格commit message生成。该DevKit为开发者提供了一个可交互的CommitMessage生成过程,极大方便并规范化了CommitMessage的使用。在使用commitizen时需要用git cz 命令取代git commit 命令提供交互式CommitMessage生成。

(1)、安装

npm install commitizen cz-customizable --save-dev

(2)、配置

在package.json中添加:

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

在根目录下新建 .cz-config.js ,该文件用于cz-customizable自定义commit message生成提示:具体配置请参考 cz-config-EXAMPLE.js

'use strict';

module.exports = {

  types: [
    {value: 'feat',     name: 'feat:     A new feature'},
    {value: 'fix',      name: 'fix:      A bug fix'},
    {value: 'docs',     name: 'docs:     Documentation only changes'},
    {value: 'style',    name: 'style:    Changes that do not affect the meaning of the code\n            (white-space, formatting, missing semi-colons, etc)'},
    {value: 'refactor', name: 'refactor: A code change that neither fixes a bug nor adds a feature'},
    {value: 'perf',     name: 'perf:     A code change that improves performance'},
    {value: 'test',     name: 'test:     Adding missing tests'},
    {value: 'chore',    name: 'chore:    Changes to the build process or auxiliary tools\n            and libraries such as documentation generation'},
    {value: 'revert',   name: 'revert:   Revert to a commit'},
    {value: 'WIP',      name: 'WIP:      Work in progress'}
  ],

  scopes: [
    {name: 'accounts'},
    {name: 'admin'}
  ],

  // it needs to match the value for field type. Eg.: 'fix'
  /*
  scopeOverrides: {
    fix: [
      {name: 'merge'},
      {name: 'style'},
      {name: 'e2eTest'},
      {name: 'unitTest'}
    ]
  },
  */
  // override the messages, defaults are as follows
  messages: {
    type: 'Select the type of change that you\'re committing:',
    scope: '\nDenote the SCOPE of this change (optional):',
    // used if allowCustomScopes is true
    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):\n',
    footer: 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n',
    confirmCommit: 'Are you sure you want to proceed with the commit above?'
  },

  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix'],

  // limit subject length
  subjectLimit: 100
  
};

(3)、测试

输入 git cz 命令:

git cz执行结果
commit history结果

到此为止第一部分,即CommitMessage规范化就结束了,下面将添加pre-commit hook的lint 和 format功能

(二)、LintStaged

在可以规范的CommitMessage提交后,我们继续构建pre-commit自动lint和format功能,而这两种功能都需要使用LintStaged包,这个DevKit可以仅对在Staged中的UncommitedFile进行命令执行,并且可以对特定文件夹特定后缀特定配置,这对结构比较复杂的Nx项目非常有用。而后在LintStaged配置中添加对Staged文件lint和format命令,即可完成所需功能。

1、LintStaged

引用LintStaged的描述:Run linters against staged git files and don’t let ? slip into your code base! 非常形象的描述出LintStaged的功能,避免将糟糕的代码带入你的Repo。

(1)、安装(npx readme)

npx mrm lint-staged

(2)、配置

配置LintStaged主要分为一下两个步骤:

A.在package.json 中添加需要执行命令的文件及命令,该文件匹配规则由micromatch提供:

lint-staged

如果以Nx项目举例(暂时没有加入conventional-changelog),则为:

Nx workspace lint-staged

B.在 .husky/pre-commit 中添加 npx lint-staged :

pre-commit 文件

(3)、测试

在命令行以 git cz 代替 git commit 执行整个commit流程,以下为实际项目中一次commit:


git cz

以上则为整个pre-commit-check流程所需配置,记录的不是很详细,但这些配置因人而异,希望读者自行研读以上pre-commit DevKit在Github上的Documentations,自己定制化个人Commit规范。

更新记录:

  • v1.0wep 新建并完成文章基本内容 2021/3/24 22:00

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注