小白篇 -- husky 6.x 版本升级指南

795 阅读2分钟

1. 初始化husky && 安装 husky

npx husky-init && yarn

package.json 的 scripts 自动插入了 prepare 的 script pre hook:

package.json

  "scripts": {
     ...
+    "prepare": "husky install"
     ...
  },

这个 hook 的执行时机有两个:

  1. 安装依赖时,也就是 yarnyarn add ** 时。
  2. 发布前,也就是 yarn publish 前。

2. 修改已自动生成的 ./husky/pre-commit 钩子

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
​
yarn lint-staged --verbose

3. 手动生成 commit-msg 并修改

yarn husky add .husky/commit-msg 'yarn commitlint --edit $1'

修改 commit-msg 文件

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
​
yarn commitlint --edit $1
  1. 此处用到了 commitlint 包,故安装下 yarn add -D @commitlint/cli @commitlint/config-conventional
  2. 通过这行命令,你可以把等价于以前 "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 的 commit 检测功能复现。

4. 在根目录下生成 commitlint 配置文件

commitlint.config.js

module.exports = {
  parserPreset: 'conventional-changelog-conventionalcommits',
  rules: {
    'body-leading-blank': [1, 'always'],
    'body-max-line-length': [2, 'always', 100],
    'footer-leading-blank': [1, 'always'],
    'footer-max-line-length': [2, 'always', 100],
    'header-max-length': [2, 'always', 100],
    'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
    'subject-empty': [2, 'never'],
    'subject-full-stop': [2, 'never', '.'],
    'type-case': [2, 'always', 'lower-case'],
    'type-empty': [2, 'never'],
    'type-enum': [
      2,
      'always',
      ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test'],
    ],
  },
  prompt: {
    questions: {
      type: {
        description: "Select the type of change that you're committing",
        enum: {
          feat: {
            description: 'A new feature',
            title: 'Features',
            emoji: '✨',
          },
          fix: {
            description: 'A bug fix',
            title: 'Bug Fixes',
            emoji: '🐛',
          },
          docs: {
            description: 'Documentation only changes',
            title: 'Documentation',
            emoji: '📚',
          },
          style: {
            description:
              'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
            title: 'Styles',
            emoji: '💎',
          },
          refactor: {
            description: 'A code change that neither fixes a bug nor adds a feature',
            title: 'Code Refactoring',
            emoji: '📦',
          },
          perf: {
            description: 'A code change that improves performance',
            title: 'Performance Improvements',
            emoji: '🚀',
          },
          test: {
            description: 'Adding missing tests or correcting existing tests',
            title: 'Tests',
            emoji: '🚨',
          },
          build: {
            description:
              'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
            title: 'Builds',
            emoji: '🛠',
          },
          ci: {
            description:
              'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
            title: 'Continuous Integrations',
            emoji: '⚙️',
          },
          chore: {
            description: "Other changes that don't modify src or test files",
            title: 'Chores',
            emoji: '♻️',
          },
          revert: {
            description: 'Reverts a previous commit',
            title: 'Reverts',
            emoji: '🗑',
          },
        },
      },
      scope: {
        description: 'What is the scope of this change (e.g. component or file name)',
      },
      subject: {
        description: 'Write a short, imperative tense description of the change',
      },
      body: {
        description: 'Provide a longer description of the change',
      },
      isBreaking: {
        description: 'Are there any breaking changes?',
      },
      breakingBody: {
        description: 'A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself',
      },
      breaking: {
        description: 'Describe the breaking changes',
      },
      isIssueAffected: {
        description: 'Does this change affect any open issues?',
      },
      issuesBody: {
        description:
          'If issues are closed, the commit requires a body. Please enter a longer description of the commit itself',
      },
      issues: {
        description: 'Add issue references (e.g. "fix #123", "re #123".)',
      },
    },
  },
};
​
  1. 该配置为官方示例配置,可参考官网另行配置。
  2. 此处用到了 conventional-changelog-conventionalcommits 包,故安装下 yarn add -D conventional-changelog-conventionalcommits

5. 清理 package.json 中 husky 字段内容

// "husky": {
//  "hooks": {
//    "pre-commit": "lint-staged"
//    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
//  }
// },
  "lint-staged": {
    "*.{ts,tsx,js}": [
      "eslint --config .eslintrc.js"
    ],
    "*.{css,less}": [
      "stylelint --config stylelint.config.js"
    ],
    "*.{js,jsx,tsx,ts,md,json}": [
      "prettier --write"
    ]
  },
  "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
  },