前端规范化-eslint/stylelint/husky

94 阅读3分钟

1. 创建项目

执行npm init vue@next创建项目

√ Project name: ... root
√ Add TypeScript? ... Yes
√ Add JSX Support? ... Yes
√ Add Vue Router for Single Page Application development? ... Yes
√ Add Pinia for state management? ... Yes
√ Add Vitest for Unit Testing? ... NoAdd Cypress for both Unit and End-to-End testing? ... NoAdd ESLint for code quality? ... Yes
√ Add Prettier for code formatting? » Yes

2. 集成 eslint/prettier

新建.editorconfig,统一编辑器规范

因为根目录是用 npm init vue@next 创建的,自带了 eslint/prettier,因此我们只需要对齐进行配置即可。

新建.prettierrc.cjs.prettierignore,统一配置

对于 eslint,我们常用更加严格的检查,使用 recommended 语法检查

module.exports = {
  extends: ['plugin:vue/vue3-recommended'],
};

接着新建/packages/eslint-config-vue3项目,里面配置更细节的 rules

module.exports = {
  rules: {
    // ...
  },
};

然后在根目录安装pnpm add @mono/eslint-config-vue3 -wD,既可以在跟目录的.eslintrc.cjs中使用

module.exports = {
  root: true,
  extends: ['@mono/eslint-config-vue3'],
};

3、集成 stylelint

  1. 安装: pnpm i -Dw stylelint postcss-html postcss stylelint-config-recommended-scss stylelint-order stylelint-config-rational-order
  • stylelint-config-recommended-scss: scss 标准规范,如果项目用的是纯 css 则使用stylelint-config-standard标准
  • stylelint-scss: 配合 scss 的
  • stylelint-order: 检查顺序的
  • stylelint-config-rational-order: 别人写好的 order 顺序,就不用自己写了
  • postcss: postcss-htmlpostcss-scss的前置依赖
  • postcss-html: 解析<style>类 vue、html 文件标签中的样式

下面是网上的其他插件,现在项目还没用到,后续观察下:

  • postcss-scss: 解析<style lang=“scss”>下的 scss 样式
  1. 配置.stylelintrc.js.stylelintignore

  2. 配置package.json的命令

{
  "lint:style": "stylelint src/**/*.{html,vue,css,sass,scss} --fix --cache --cache-location node_modules/.cache/.stylelintignore"
}

5、结合 git 自动校验

推荐使用 mrm 来安装,会自动为项目安装husky/lint-staged,并且自动根据项目已经有的eslint/stylelint/prettier来生成配置

  1. 执行npx mrm lint-staged

  2. 执行结束后,可以看到 package.json 配置如下:

{
  "lint-staged": {
    "*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}": "eslint --cache --fix",
    "*.{js,css,md}": "prettier --write",
    "*.css": "stylelint --fix"
  }
}

6、约束 git commit 信息规范

  1. 支持 gz 命令
pnpm i commitizen -Dw

npx commitizen init cz-conventional-changelog -Dw

上面命令安装了 commitizen/cz-conventional-changelog 这 2 个库,并修改了package.json

{
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  }
}

以前提交代码都是 git commit,现在改为 npx cz,然后按照终端操作提示。

  1. 约束 commit 规范经过第 1 步之后,可能有的同事还是通过git commit去提交规范,所以我们要多加一层校验
npm i @commitlint/config-conventional @commitlint/cli -D

npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"

新建commitlint.config.js,配置如下:

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

当同事使用git commit提交的时候,也不许符合规范才能提交

  1. 中文以及自定义配置
npx commitizen init cz-customizable -D --force

上面命令安装cz-customizable依赖外,会将package.json里面的config.commitizen改为下面的值

{
  "config": {
    "commitizen": {
      // 原来的是 "path": "./node_modules/cz-conventional-changelog"
      "path": "./node_modules/cz-customizable"
    }
  }
}

新建.cz-config.js,可以参考官方示例配置

module.exports = {
  // type 类型(定义之后,可通过上下键选择)
  types: [
    { value: 'feat', name: 'feat:     新增功能' },
    { value: 'fix', name: 'fix:      修复 bug' },
    { value: 'docs', name: 'docs:     文档变更' },
    { value: 'style', name: 'style:    代码格式(不影响功能,例如空格、分号等格式修正)' },
    { value: 'refactor', name: 'refactor: 代码重构(不包括 bug 修复、功能新增)' },
    { value: 'perf', name: 'perf:     性能优化' },
    { value: 'test', name: 'test:     添加、修改测试用例' },
    { value: 'build', name: 'build:    构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)' },
    { value: 'ci', name: 'ci:       修改 CI 配置、脚本' },
    { value: 'chore', name: 'chore:    对构建过程或辅助工具和库的更改(不影响源文件、测试用例)' },
    { value: 'revert', name: 'revert:   回滚 commit' },
  ],

  // scope 类型(定义之后,可通过上下键选择)
  scopes: [
    ['components', '组件相关'],
    ['hooks', 'hook 相关'],
    ['utils', 'utils 相关'],
    ['element-ui', '对 element-ui 的调整'],
    ['styles', '样式相关'],
    ['deps', '项目依赖'],
    ['auth', '对 auth 修改'],
    ['other', '其他修改'],
    // 如果选择 custom,后面会让你再输入一个自定义的 scope。也可以不设置此项,把后面的 allowCustomScopes 设置为 true
    ['custom', '以上都不是?我要自定义'],
  ].map(([value, description]) => {
    return {
      value,
      name: `${value.padEnd(30)} (${description})`,
    };
  }),

  // 是否允许自定义填写 scope,在 scope 选择的时候,会有 empty 和 custom 可以选择。
  // allowCustomScopes: true,

  // allowTicketNumber: false,
  // isTicketNumberRequired: false,
  // ticketNumberPrefix: 'TICKET-',
  // ticketNumberRegExp: '\\d{1,5}',

  // 针对每一个 type 去定义对应的 scopes,例如 fix
  /*
  scopeOverrides: {
    fix: [
      { name: 'merge' },
      { name: 'style' },
      { name: 'e2eTest' },
      { name: 'unitTest' }
    ]
  },
  */

  // 交互提示信息
  messages: {
    type: '确保本次提交遵循 Angular 规范!\n选择你要提交的类型:',
    scope: '\n选择一个 scope(可选):',
    // 选择 scope: custom 时会出下面的提示
    customScope: '请输入自定义的 scope:',
    subject: '填写简短精炼的变更描述:\n',
    body: '填写更加详细的变更描述(可选)。使用 "|" 换行:\n',
    breaking: '列举非兼容性重大的变更(可选):\n',
    footer: '列举出所有变更的 ISSUES CLOSED(可选)。 例如: #31, #34:\n',
    confirmCommit: '确认提交?',
  },

  // 设置只有 type 选择了 feat 或 fix,才询问 breaking message
  allowBreakingChanges: ['feat', 'fix'],

  // 公司项目不需要管理issue,跳过body和footer
  skipQuestions: ['body', 'breaking', 'footer'],

  // subject 限制长度
  subjectLimit: 100,
  breaklineChar: '|', // 支持 body 和 footer
  // footerPrefix : 'ISSUES CLOSED:'
  // askForBreakingChangeFirst : true,
};

这样就可以选择跳过某些环节,并且限制 scope 在指定范围内。