【pre-commit/husky】配置

443 阅读2分钟

下面介绍 :

一、.git 跟 package.json 不在同一级目录下,怎么初始化husky以及多人协作下统一配置 ~~

projectRoot/
├── .git/
├── .gitignore
├── .nx
├── deploy/.gitkeep
├── src/
            ├── my-service/
                        |── src/
                       ├── mvnw.cmd
                        ├── pom.xml

            
            ├── my-ui/
                       ├── node_modules
                       ├── package.json 
                        |── src/
                        ├── pnpm-lock.yaml

my-ui 目录位于 src/ 子目录下,因此 my-ui 目录的相对路径到 .git 目录是 ../../.git。
基于.git 跟 package.json 不在同一层的目录,这种情况下, 如果在多人协作的项目中, 不可能让每个人都去.git/hooks/pre-commit 和 root/src/my-ui/.husky/pre-commit
这两个文件下去修改内容, 所以还是需要一个执行脚本去生成。

以下是一个脚本,用于统一管理和自动设置 pre-commit 钩子,以便在多人协作的项目中避免手动修改两个文件的内容。我们可以创建一个脚本,自动将 pre-commit 钩子同步到 .git/hooks/pre-commitsrc/my-ui/.husky/pre-commit 文件中。

脚本内容

#!/bin/bash

# Define paths
GIT_HOOKS_PATH=".git/hooks/pre-commit"
HUSKY_HOOK_PATH="src/my-ui/.husky/pre-commit"

# Define the common pre-commit content
PRE_COMMIT_CONTENT="#!/bin/sh
# Pre-commit hook to ensure consistent behavior in both locations
echo 'Running pre-commit hook...'
# Add your custom commands here, e.g., linting, formatting, tests
pnpm lint
"

# Function to create or update the hook file
update_hook() {
  local hook_path=$1
  echo "Updating $hook_path..."
  # Ensure the parent directory exists
  mkdir -p "$(dirname "$hook_path")"
  # Write the content to the hook file
  echo "$PRE_COMMIT_CONTENT" > "$hook_path"
  # Make the hook file executable
  chmod +x "$hook_path"
}

# Update both hooks
update_hook "$GIT_HOOKS_PATH"
update_hook "$HUSKY_HOOK_PATH"

echo "Pre-commit hooks have been updated successfully."

1. 使用说明

  1. 将此脚本保存为 update-hooks.sh 并放在项目根目录。

  2. 确保脚本有执行权限,运行以下命令:

    chmod +x update-hooks.sh
    
  3. 每次需要更新 pre-commit 钩子时,运行脚本:

    ./update-hooks.sh
    

2. 如何管理内容

  • PRE_COMMIT_CONTENT 变量中添加你的钩子逻辑,比如代码格式化、lint 或运行测试等。
  • 运行此脚本后,pre-commit 钩子的内容会同时更新到 .git/hooks/pre-commitsrc/my-ui/.husky/pre-commit 文件。

二、配置完成后需要的操作和验证步骤

在运行上述脚本并确保 pre-commit 钩子已经生成和更新后,接下来你需要做以下操作来确保 Husky 和钩子功能正常。


1. 确保项目依赖已安装

确保 my-ui 项目中的依赖(包括 huskypnpm)已经正确安装。

运行以下命令安装依赖:

cd src/my-ui
pnpm install

2. 验证 pre-commit 钩子是否正确配置

检查文件内容

手动检查生成的 pre-commit 文件内容是否正确。

  1. 查看 .git/hooks/pre-commit

    cat .git/hooks/pre-commit
    

    输出应为:

    #!/bin/sh
    # Pre-commit hook to ensure consistent behavior in both locations
    echo 'Running pre-commit hook...'
    # Add your custom commands here, e.g., linting, formatting, tests
    pnpm lint
    
  2. 查看 src/my-ui/.husky/pre-commit

    cat src/my-ui/.husky/pre-commit
    

    输出应相同。

确保文件可执行

检查这两个文件的权限:

ls -l .git/hooks/pre-commit src/my-ui/.husky/pre-commit

输出应显示 -rwxr-xr-x 权限,表示文件是可执行的。

如果权限不足,运行以下命令手动修复:

chmod +x .git/hooks/pre-commit src/my-ui/.husky/pre-commit

3. 测试 pre-commit 钩子

(1)创建一个测试文件并尝试提交
  1. my-ui 中创建一个文件并添加到 Git 暂存区:

    echo "Test file" > src/my-ui/test.txt
    git add src/my-ui/test.txt
    
  2. 提交更改:

    git commit -m "Test Hus
    

(2) 测试钩子

测试 .git/hooks/pre-commit
  1. 创建或修改一个文件。

  2. 尝试提交更改:

    git add .
    git commit -m "Test pre-commit hook"
    
  3. 如果钩子生效,终端会输出 Running pre-commit hook...,并运行 pnpm lint 命令。

测试 src/my-ui/.husky/pre-commit
  1. 如果你的项目配置了 husky,可以通过运行以下命令测试钩子:

    pnpm husky add src/my-ui/.husky/pre-commit "echo 'Husky pre-commit hook test'"
    
  2. 提交代码,看是否运行新的逻辑。


脚本作用

  • 脚本运行后会同步两个位置的 pre-commit 文件,避免手动管理。
  • 你可以通过运行和观察测试结果,验证钩子是否按照预期运行。

三、update.hooks.sh 脚本 , 还需要在 scripts里面加命令么

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

如果你已经有了 update-hooks.sh 脚本并用它来统一更新 Git 钩子和 Husky 配置,那么在 scripts 中添加 "prepare": "husky install"不必要的。以下是原因和场景分析:


为什么不需要再添加 "prepare": "husky install"

  1. update-hooks.sh 脚本已经覆盖了钩子配置:

    • 你的脚本 update-hooks.sh 会自动更新 .git/hooks/pre-commitsrc/my-ui/.husky/pre-commit
    • 这使得 Husky 的初始化由脚本集中管理,无需额外的 prepare 脚本。
  2. 避免冲突和重复:

    • 如果同时存在 update-hooks.sh"prepare": "husky install",可能导致路径或行为上的冲突。
    • 统一管理钩子的方式更清晰(即只通过 update-hooks.sh 来初始化或更新)。

何时需要 "prepare": "husky install"

  • 如果没有 update-hooks.sh 脚本:

    • 此时,需要通过 prepare 脚本确保 Husky 钩子自动安装到 .git/hooks
  • 团队需要自动化安装流程:

    • 如果团队成员克隆项目后直接运行 pnpm install,自动完成 Husky 初始化是一个便利的选择。

推荐方案

如果保留 update-hooks.sh
  1. 不要在 scripts 中添加 prepare

    • 通过运行 ./update-hooks.sh 管理钩子。
    • 确保团队成员在每次拉取代码后运行此脚本。
  2. 更新项目文档:

    • 在团队文档中明确说明,需要运行 ./update-hooks.sh 来初始化钩子。
如果更喜欢自动化方式(不使用脚本):
  1. 移除 update-hooks.sh

    • src/my-ui/package.json 中添加以下内容:

      "scripts": {
        "prepare": "husky install src/my-ui/.husky"
      }
      
    • 每次运行 pnpm install 时,钩子会自动安装。

  2. 手动运行 Husky 命令初始化:

    cd src/my-ui
    pnpm install
    

总结

  • 如果你有 update-hooks.sh,就 不需要 再添加 "prepare" 脚本。
  • 如果想要更自动化的流程并愿意移除脚本,则可以使用 "prepare": "husky install"

四、需要加入 .gitignore 么?

.git/hooks/pre-commit src/my-ui/.husky/pre-commit 这两个文件需要在 .gitignore 中忽略么?

以下是关于是否需要忽略 .git/hooks/pre-commitsrc/my-ui/.husky/pre-commit 的建议:


1. .git/hooks/pre-commit 是否需要忽略?

建议:不需要忽略

.git/hooks/pre-commit 是 Git 的本地钩子文件,通常不会被版本控制系统管理,因为它是每个开发者本地的配置。即使你不在 .gitignore 中明确忽略它,.git/ 目录本身也不会被 Git 管理,因此不需要额外处理。


2. src/my-ui/.husky/pre-commit 是否需要忽略?

建议:不要忽略

  • Husky 的钩子文件(如 src/my-ui/.husky/pre-commit)是由 npx husky add 创建的,它通常需要被版本控制管理。

  • 原因:

    • 团队成员克隆项目时需要这些钩子来确保一致性。
    • Husky 本身依赖这些文件来工作。

因此,src/my-ui/.husky/pre-commit 应该提交到版本控制中,不需要在 .gitignore 中忽略。


总结

不需要在 .gitignore 中添加的文件:
  • .git/hooks/pre-commit(已被 .git 排除)
  • src/my-ui/.husky/pre-commit(需要被版本控制管理)

补充说明:Husky 的依赖管理

为了保证团队成员的环境一致性:

  1. 确保项目的 pnpm-lock.yaml 被提交到版本控制中。

  2. package.json 中,添加一个 prepare 脚本(如果未添加):

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

    这样,当团队成员克隆项目并运行 pnpm install 时,Husky 会自动安装。

五、更新 PRE_COMMIT_CONTENT的规则内容 :

PRE_COMMIT_CONTENT 中,我们定义了 pre-commit 钩子的一些基本操作,通常包括代码格式检查(linting)、单元测试、代码格式化等。为了确保钩子在各种环境下的兼容性并实现最佳实践,可以进行以下几点调整:

改进后的 PRE_COMMIT_CONTENT

#!/bin/sh
# Ensure that the script stops if any command fails
set -e

# Output message for debugging purposes
echo 'Running pre-commit hook...'

# Run linting
echo 'Running linting checks...'
pnpm lint

# Optionally, run tests (if you have tests set up)
# echo 'Running tests...'
# pnpm test

# Optionally, run formatting (if you use a code formatter like Prettier)
# echo 'Running code formatting checks...'
# pnpm format:check

# Exit successfully
echo 'Pre-commit checks passed!'

具体改进点:

  1. set -e

    • 这个命令会使脚本在遇到任何错误时立即退出,这样可以确保不会跳过潜在的错误。
  2. 显示的 echo 输出

    • 为了调试和清晰地知道钩子执行了哪些步骤,增加了 echo 输出,帮助在执行钩子时看到运行到哪个阶段。
  3. Linting

    • pnpm lint 被保留来运行 lint 检查,确保代码质量。
  4. 测试(可选):

    • 如果项目中有单元测试,可以考虑在钩子中添加 pnpm test 来运行测试,确保提交的代码没有破坏任何功能。这个部分是注释掉的,如果你想启用它,可以取消注释。
  5. 代码格式化检查(可选):

    • 如果你使用了代码格式化工具(如 Prettier),可以添加 pnpm format:check 来检查代码是否符合格式。如果你的项目有格式化命令,可以在钩子中添加它。
  6. 确保成功退出

    • echo 'Pre-commit checks passed!' 表示检查成功,通过显示信息来告诉开发者提交检查通过。

示例:修改后的 update-hooks.sh 脚本

如果你需要在 update-hooks.sh 中更新 pre-commit 钩子的内容,可以按照以下方式进行修改:

#!/bin/bash

# Define paths
GIT_HOOKS_PATH=".git/hooks/pre-commit"
HUSKY_HOOK_PATH="src/my-ui/.husky/pre-commit"

# Define the common pre-commit content
PRE_COMMIT_CONTENT="#!/bin/sh
# Ensure that the script stops if any command fails
set -e

# Output message for debugging purposes
echo 'Running pre-commit hook...'

# Run linting
echo 'Running linting checks...'
pnpm lint

# Optionally, run tests (if you have tests set up)
# echo 'Running tests...'
# pnpm test

# Optionally, run formatting (if you use a code formatter like Prettier)
# echo 'Running code formatting checks...'
# pnpm format:check

# Exit successfully
echo 'Pre-commit checks passed!'
"

# Function to create or update the hook file
update_hook() {
  local hook_path=$1

  echo "Updating $hook_path..."

  # Ensure the parent directory exists
  mkdir -p "$(dirname "$hook_path")"

  # Remove existing hook file if it exists
   # 添加文件存在检查并删除:
  if [ -f "$hook_path" ]; then
    echo "Existing hook found at $hook_path. Deleting..."
    rm -f "$hook_path"
  fi

  # Write the new content to the hook file
  echo "$PRE_COMMIT_CONTENT" > "$hook_path"

  # Make the hook file executable
  chmod +x "$hook_path"
}

# Update both hooks
update_hook "$GIT_HOOKS_PATH"
update_hook "$HUSKY_HOOK_PATH"

echo "Pre-commit hooks have been updated successfully."

其他注意事项

  • 确保 pnpm 命令有效:确认团队所有成员都安装了 pnpm,并且在 package.json 中定义了相应的脚本命令(如 linttestformat:check)。
  • 团队协作:建议将 update-hooks.sh 脚本和修改后的钩子文件提交到版本控制,以便团队成员在新的工作环境中能够自动更新钩子。

这样修改后的 pre-commit 钩子不仅完成了 lint 检查,还提供了可选的测试和格式化步骤,并且确保了脚本出错时立即退出,从而避免提交错误代码。