JavaScript内核与高级编程之:`JavaScript`的`Husky`:其在 `Git Hook` 中的配置与工作流。

各位靓仔靓女们,晚上好!我是你们的老朋友,今晚咱们来聊聊 JavaScript 界的“二哈”—— Husky

别误会,此“二哈”非彼“二哈”,它可不是那种拆家捣蛋的宠物,而是 Git Hook 的好帮手,能让你的代码提交变得更加规范和可靠。简单来说,它就像一个尽职尽责的门卫,帮你把控代码质量的最后一道关卡。

一、Husky 是个啥?为什么要用它?

首先,我们得明白 Git Hook 是什么。Git Hook 就像 Git 的钩子函数,在特定的 Git 事件发生时(例如 commitpush 等),会自动触发你预先设定的脚本。

但是,手动配置和管理 Git Hook 非常麻烦,容易出错,而且需要对每个开发者都进行设置。这时候,Husky 就闪亮登场了。

Husky 就像一个 Git Hook 管理器,它能:

  • 简化 Git Hook 的配置: 用简单的 npm 命令就能安装和配置,无需手动修改 .git/hooks 目录。
  • 项目级别配置: Husky 的配置保存在 package.json 文件中,跟随项目一起版本控制,保证团队成员使用相同的 Hook 设置。
  • 支持各种脚本语言: 你可以使用 JavaScriptShellPython 等任何你喜欢的脚本语言来编写 Hook 脚本。
  • 提高代码质量: 通过 Hook 脚本,你可以自动化地执行代码检查、单元测试、代码格式化等操作,从而避免低级错误和风格不一致的代码被提交。

举个例子,你可能希望在每次提交代码前,都自动运行 ESLint 来检查代码风格,或者运行 Jest 来进行单元测试。有了 Husky,这些都能轻松实现。

二、如何安装和配置 Husky

  1. 安装 Husky

    首先,确保你的项目已经初始化了 npmyarn。 然后,在你的项目根目录下运行以下命令:

    npm install husky --save-dev
    # 或者
    yarn add husky --dev
  2. 启用 Git Hook

    安装完成后,你需要启用 Git Hook。运行以下命令:

    npx husky install
    # 或者
    yarn husky install

    这会在你的项目根目录下创建一个 .husky 文件夹,用于存放 Hook 脚本。

  3. 添加 Hook 脚本:

    现在,你可以添加你想要的 Hook 脚本了。 Husky 支持的 Hook 类型有很多,常用的包括:

    • pre-commit:在 commit 之前运行。
    • commit-msg:在 commit 消息编辑后运行。
    • pre-push:在 push 之前运行。
    • prepare-commit-msg: 在 commit message 准备阶段运行

    例如,如果你想在每次 commit 之前运行 ESLint 检查代码风格,可以这样做:

    npx husky add .husky/pre-commit "npm run lint"
    # 或者
    yarn husky add .husky/pre-commit "yarn lint"

    这个命令会在 .husky/pre-commit 文件中创建一个脚本,内容是 npm run lintyarn lint。 假设你的 package.json 文件中有如下配置:

    {
      "scripts": {
        "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
      }
    }

    那么,每次你运行 git commit 命令时,Husky 都会自动执行 eslint . --ext .js,.jsx,.ts,.tsx 命令来检查你的代码风格。 如果 ESLint 发现了任何错误,commit 就会被阻止,直到你修复了错误为止。

  4. 简化配置方式(Husky v6+):

    Husky v6 引入了一种更简洁的配置方式,直接在 package.json 文件中配置 Hook。 首先,在 package.json 中添加 husky 配置:

    {
      "husky": {
        "hooks": {
          "pre-commit": "lint-staged"
        }
      },
      "scripts": {
        "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
        "format": "prettier --write ."
      },
      "devDependencies": {
        "husky": "^6.0.0",
        "lint-staged": "^10.0.0",
        "eslint": "^7.0.0",
        "prettier": "^2.0.0"
      }
    }

    然后,运行 npm installyarn install 安装依赖。

    这种方式更加清晰明了,方便管理和维护。

三、Husky + lint-staged:黄金搭档

通常,我们不会对所有文件都进行代码检查和格式化,而是只关注那些被修改的文件。 这时候,lint-staged 就派上用场了。

lint-staged 是一个只对 Git 暂存区(stage)中的文件执行 lint 命令的工具。 它可以显著提高 lint 的速度,避免对未修改的文件进行不必要的检查。

  1. 安装 lint-staged

    npm install lint-staged --save-dev
    # 或者
    yarn add lint-staged --dev
  2. 配置 lint-staged

    package.json 文件中添加 lint-staged 配置:

    {
      "lint-staged": {
        "*.{js,jsx,ts,tsx}": [
          "eslint --fix",
          "prettier --write",
          "git add"
        ]
      }
    }

    这个配置表示,对所有 .js.jsx.ts.tsx 文件,先运行 eslint --fix 来自动修复代码风格问题,然后运行 prettier --write 来格式化代码,最后运行 git add 将修改后的文件重新添加到暂存区。

  3. lint-staged 集成到 Husky 中:

    修改 husky 配置,将 pre-commit 钩子指向 lint-staged

    {
      "husky": {
        "hooks": {
          "pre-commit": "lint-staged"
        }
      }
    }

    现在,每次你运行 git commit 命令时,Husky 都会自动执行 lint-staged,只对暂存区中的文件进行代码检查和格式化。

四、一些进阶用法和注意事项

  1. 跳过 Hook

    有时候,你可能需要临时跳过 Hook,例如当你需要提交一些未完成的代码时。 你可以使用 git commit --no-verifygit push --no-verify 命令来跳过 Hook

  2. 自定义 Hook 脚本:

    你可以编写自己的 Hook 脚本来实现更复杂的功能。 例如,你可以编写一个 Hook 脚本来检查 commit 消息的格式,或者检查代码中是否包含敏感信息。

    举个例子,我们可以编写一个 commit-msg 钩子来检查 commit 消息是否符合规范:

    #!/bin/sh
    COMMIT_MSG_FILE=$1
    COMMIT_MSG=$(cat $COMMIT_MSG_FILE)
    
    # 检查 commit 消息是否以 "feat:", "fix:", "docs:", "style:", "refactor:", "test:", "chore:" 开头
    if ! echo "$COMMIT_MSG" | grep -E "^(feat|fix|docs|style|refactor|test|chore)(([a-z]+))?:s.+"; then
      echo "Error: Commit message must start with feat:, fix:, docs:, style:, refactor:, test:, or chore: followed by a description."
      exit 1
    fi
    
    exit 0

    然后,将这个脚本添加到 .husky/commit-msg 文件中,并赋予执行权限:

    chmod +x .husky/commit-msg

    现在,每次你提交代码时,Husky 都会自动运行这个脚本来检查 commit 消息的格式。

  3. 处理 Hook 失败:

    默认情况下,如果 Hook 脚本执行失败,commitpush 操作会被阻止。 你可以使用 husky.allowEmpty 配置来允许空的 commit,即使 Hook 失败。

    {
      "husky": {
        "hooks": {
          "pre-commit": "lint-staged",
          "commit-msg": "your-commit-msg-script"
        },
        "allowEmpty": true
      }
    }

    但通常不推荐这样做,因为这会降低代码质量的保证。

  4. 与 CI/CD 集成:

    Husky 也可以与 CI/CD 工具集成,例如 Jenkins、Travis CI、GitHub Actions 等。 这样,你可以在每次构建或部署时,都自动运行 Hook 脚本来检查代码质量。

五、一个完整的例子

假设我们有一个 React 项目,使用 ESLintPrettierJest 来进行代码检查、格式化和单元测试。 我们可以这样配置 Husky

  1. 安装依赖:

    npm install husky lint-staged eslint prettier jest --save-dev
    # 或者
    yarn add husky lint-staged eslint prettier jest --dev
  2. 配置 package.json

    {
      "scripts": {
        "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
        "format": "prettier --write .",
        "test": "jest",
        "prepare": "husky install"
      },
      "husky": {
        "hooks": {
          "pre-commit": "lint-staged"
        }
      },
      "lint-staged": {
        "*.{js,jsx,ts,tsx}": [
          "eslint --fix",
          "prettier --write",
          "jest --findRelatedTests",
          "git add"
        ]
      },
      "devDependencies": {
        "eslint": "^7.0.0",
        "prettier": "^2.0.0",
        "jest": "^26.0.0",
        "husky": "^6.0.0",
        "lint-staged": "^10.0.0"
      }
    }

    注意:prepare 脚本会在 npm installyarn install 之后自动运行 husky install,这样可以确保在安装依赖后,Husky 能够正确地启用 Git Hook

  3. 初始化 ESLintPrettier

    运行以下命令来初始化 ESLintPrettier

    npx eslint --init
    npx prettier --write .

    根据提示选择合适的配置。

  4. 编写单元测试:

    编写一些单元测试来测试你的代码。

现在,每次你运行 git commit 命令时,Husky 都会自动执行以下操作:

  1. 只对暂存区中的 .js.jsx.ts.tsx 文件进行代码检查和格式化。
  2. 运行 Jest 来测试与这些文件相关的单元测试。
  3. 如果一切顺利,commit 就会成功。 否则,commit 会被阻止,直到你修复了错误为止。

六、Husky 的优点和缺点

优点 缺点
提高代码质量 如果 Hook 脚本执行时间过长,会影响开发效率。
自动化代码检查和格式化 需要配置和维护 Hook 脚本。
强制团队成员遵循相同的代码风格 有些开发者可能不喜欢强制性的代码检查和格式化。
简化 Git Hook 的配置和管理 如果 Hook 脚本编写不当,可能会导致意外的错误。
可以与 CI/CD 工具集成,实现自动化代码质量控制 在某些情况下,Husky 可能会与其他的 Git Hook 工具冲突。

七、总结

Husky 是一个非常实用的 Git Hook 管理工具,可以帮助你提高代码质量、自动化代码检查和格式化,并强制团队成员遵循相同的代码风格。 配合 lint-staged 使用,可以显著提高 lint 的速度。

虽然 Husky 也有一些缺点,但总体来说,它的优点远大于缺点。 如果你还没有使用 Husky,强烈建议你尝试一下,相信它会给你的开发工作带来很大的帮助。

好了,今天的讲座就到这里。 希望大家都能成为代码界的“猛男”和“靓女”,写出高质量的代码! 感谢大家的聆听! 记得点赞收藏加关注哦! 下次再见!

发表回复

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