Git 标准

组件库是一个多人合作的我的项目,Git 的提交阐明精准,在前期合作以及 Bug 解决时会变得有据可查,我的项目的开发能够依据标准的提交阐明疾速生成开发日志,从而不便开发者或用户追踪我的项目的开发信息和性能个性。提交标准应用的是 Angular 团队标准

commit message 提交合乎 Angular 团队标准,须要在 comit 之前做校验,husky 工具能够定义拦挡 git 钩子,对提交的文件和信息做校验和主动修复

husky

我的项目的 husky 版本是 ^7.0.4

husky 装置到开发依赖中

yarn add husky -D

装置完后,咱们须要在以后我的项目中创立一个.husky 目录,并指定该目录为 git hooks 所在的目录。

应用以下命令疾速创立

npx --no-install husky install

--no-install 参数示意强制 npx 应用我的项目中 node_modules 目录下的husky依赖包

应用以下命令疾速创立 pre-commit

npx --no-instal husky add .husky/pre-commit "npm run lint"

pre-commit 在 commit 之前会执行 npm run lint 校验代码,能够定义你的执行脚本,校验不通过不容许 commit 提交

commitizen

commitizen 是一个撰写合乎 Commit Message 规范的一款工具。通过它能够实现交互式撰写标准的 Commit Message。

我的项目装置 commitizen

yarn add commitizen -D

装置实现后,个别咱们都采纳合乎 Angular 的 Commit message 格局的提交标准,运行以下命令生成合乎 Angular 提交标准格局的 Commit message

npx --no-install commitizen init cz-conventional-changelog --save-dev --save-exact

运行了上述命令后,它将为你我的项目装置 cz-conventional-changelog 适配器模块,把 config.commitizen 的密钥增加到文件的根目录增加到 package.json

能够在 package.json 中看到,主动的新增了以下内容

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

package.json scrips 增加 "commit": "git-cz" 命令

scripts: {  "commit": "git-cz"}

运行 yarn commit 能够通过以下交互式的撰写 commit messag 而后提交

限度 commitlint

因为 commitizen 并不是强制应用的,依然能够通过 git commit 来提交,所以不论是 git-cz 还是 git commit 提交前,都要对 commit messag 进行一次校验,不符合规范的状况下是不容许进行 commit

首先咱们须要装置 commitlint, commitlint/config-conventional

yarn add @commitlint/cli @commitlint/config-conventional -D

应用以下命令疾速创立 git hooks 的 commit-msg 钩子
这样每次 commit 的时候都会由 commitlint 对 commit message 进行一次测验

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

而后在我的项目根目录创立一个 commitlint 配置文件 commitlint.config.js,能够对这个文件进行配置

module.exports = {  ignores: [(commit) => commit.includes('init')],  extends: ['@commitlint/config-conventional', 'cz'],  rules: {    'body-leading-blank': [2, 'always'],    'footer-leading-blank': [1, 'always'],    'header-max-length': [2, 'always', 108],    'subject-empty': [2, 'never'],    'type-empty': [2, 'never'],    'subject-case': [0],    'type-enum': [      2,      'always',      [        'feat',        'fix',        'perf',        'style',        'docs',        'test',        'refactor',        'build',        'ci',        'chore',        'revert',        'wip',        'workflow',        'types',        'release'      ]    ]  }}

下面的提醒都是英文的,如果想自定义翻译成中文,须要装置 cz-customizable 来实现自定义 commit message 规定,以及装置对应的 commitlint-config-cz 来配套校验

yarn add commitlint-config-cz -D

在我的项目根目录,创立一个 .cz-config.js 文件,并复制 cz-config-EXAMPLE.js 中的内容到其中。而后改成本人想要的规定即可。

// .cz-config.jsmodule.exports = {  types: [    { value: ':sparkles: feat', name: '✨ feat: 一项新性能' },    { value: ':bug: fix', name: ' fix: 修复一个Bug' },    { value: ':memo: docs', name: ' docs: 文档变更' },    { value: ':lipstick: style', name: ' style: 代码格调,格局修复' },    { value: ':recycle: refactor', name: '♻️ refactor: 代码重构,留神和feat、fix辨别开' },    { value: ':zap: perf', name: '⚡️ perf: 代码优化,改善性能' },    { value: ':white_check_mark: test', name: '✅ test: 测试' },    { value: ':rocket: chore', name: ' chore: 变更构建流程或辅助工具' },    { value: ':rewind: revert', name: ':rewind: revert: 代码回退' },    { value: ':tada: init', name: ' init: 我的项目初始化' },    { value: ':construction_worker: ci', name: ' 对CI配置文件和脚本的更改' },    { value: ':package: build', name: '️ build: 变更我的项目构建或内部依赖' },    { value: ':construction: WIP', name: ' WIP: 进行中的工作' }  ],  scopes: [    { name: 'component' },    { name: 'config' },    { name: 'docs' },    { name: 'src' },    { name: 'examples' },    { name: 'play' }  ],  // allowTicketNumber: false,  // isTicketNumberRequired: false,  // ticketNumberPrefix: 'TICKET-',  // ticketNumberRegExp: '\\d{1,5}',  // it needs to match the value for field type. Eg.: 'fix'  // scopeOverrides: {  //   feat: [  //     { name: 'element' }  //   ],  //   fix: [  //     { name: 'element' },  //     { name: 'style' },  //   ]  // },  // override the messages, defaults are as follows  messages: {    type: '请抉择提交类型(必填):',    scope: '请抉择一个scope (可选):',    customScope: '请输出文件批改范畴(可选):',    // used if allowCustomScopes is true    subject: '请简要形容提交(必填):',    body: '请输出详细描述,应用"|"换行(可选):\n',    breaking: '列出工作非兼容性阐明 (可选):\n',    footer: '请输出要敞开的issue,例如:#12, #34(可选):\n',    confirmCommit: '确定提交此阐明吗?'  },  allowCustomScopes: true,  allowBreakingChanges: ['feat', 'fix'],  // 限度 subject 长度  subjectLimit: 72  // 跳过问题 skip any questions you want  // skipQuestions: ['body', 'footer'],  // breaklineChar: '|', // It is supported for fields body and footer.  // footerPrefix : 'ISSUES CLOSED:'  // askForBreakingChangeFirst : true, // default is false}

创立完 .cz-config.js 文件后,咱们须要回到 package.json 文件中,将 config.commitizen.path 更改为 node_modules/cz-customizable

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

对于 commitlint-config-cz 更高级的用法能够查看 commitlint-config-cz

为了提交更好看,在 commit 头部增加了表情 gitmoji,须要装置这个插件 commitlint-config-gitmoji

yarn add commitlint-config-gitmoji -D

批改 .commitlintrc.js 内容

// .commitlintrc.jsmodule.exports = {  // extends: ['@commitlint/config-conventional', 'cz'],  extends: ['gitmoji']}

执行 yarn commit 能够看到带表情的中文 commit message

提交 github 显示成果

comitmit 标准介绍

<type  >(<scope    >):    <subject>      <BLANK LINE>        <body>          <BLANK LINE> <footer></footer></BLANK></body></BLANK></subject></scope></type>

介绍一下内容标准,大抵分为三个局部(应用空行宰割):

  1. 题目行: 必填, 形容次要批改类型和内容
  2. 主题内容: 形容为什么批改, 做了什么样的批改, 以及开发的思路等等
  3. 页脚正文: 能够写正文,BUG 号链接
  • type: commit 的类型

    • feat: 新性能、新个性
    • fix: 批改 bug
    • perf: 更改代码,以进步性能
    • refactor: 代码重构(重构,在不影响代码外部行为、性能下的代码批改)
    • docs: 文档批改
    • style: 代码格局批改, 留神不是 css 批改(例如分号批改)
    • test: 测试用例新增、批改
    • build: 影响我的项目构建或依赖项批改
    • revert: 复原上一次提交
    • ci: 继续集成相干文件批改
    • chore: 其余批改(不在上述类型中的批改)
    • release: 公布新版本
    • workflow: 工作流相干文件批改
    • scope: commit 影响的范畴, 比方: route, component, utils, build…
    • subject: commit 的概述
    • body: commit 具体批改内容, 能够分为多行.
    • footer: 一些备注, 通常是 BREAKING CHANGE 或修复的 bug 的链接.
  • scope: commit 影响的范畴, 比方: route, component, utils, build…
  • subject: commit 的概述
  • body: commit 具体批改内容, 能够分为多行.
  • footer: 一些备注, 通常是 BREAKING CHANGE 或修复的 bug 的链接.

例如

  1. fix(修复 BUG)

如果修复的这个 BUG 只影响以后批改的文件,可不加范畴。如果影响的范畴比拟大,要加上范畴形容。

例如这次 BUG 修复影响到全局,能够加个 global。如果影响的是某个目录或某个性能,能够加上该目录的门路,或者对应的性能名称。

// 示例1fix(global):修复checkbox不能复选的问题// 示例2 上面圆括号里的 common 为通用治理的名称fix(common): 修复字体过小的BUG,将通用治理下所有页面的默认字体大小批改为 14px// 示例3fix: value.length -> values.length
  1. feat(增加新性能或新页面)
feat: 增加button组件这是一个示例,假如对组件性能进行了一些形容。这里是备注,能够是放BUG链接或者一些重要性的货色。
  1. chore(其余批改)

chore 的中文翻译为日常事务、例行工作,顾名思义,即不在其余 commit 类型中的批改,都能够用 chore 示意。

其余类型的 commit 和下面三个示例差不多,就不说了。

lint-staged

lint-staged 相当于一个文件过滤器,每次提交时只查看本次提交的暂存区的文件,它不能格式化代码和校验文件,须要本人配置一下,如:.eslintrc.stylelintrc 等,而后在 package.json 中引入。

 "lint-staged": {    "*.js": ["eslint --fix", "git add"]  }

当文件变动,执行 git commitpre-commit 钩子会启动,执行 lint-staged 命令,咱们对于 lint-staged 如上文配置,对本次被 commited 中的所有 .js 文件,执行 eslint --fixgit add 命令,前者的的目标是格式化,后者是对格式化之后的代码从新提交。

应用步骤

  1. 装置应用
yarn add -D lint-staged
  1. 增加脚本命令
// package.json"scripts": {  "lint:lint-staged": "lint-staged -c ./.husky/lint-staged.config.js"}
  1. 在 pre-commit 的钩子上增加 lint-staged 命令
#!/bin/sh. "$(dirname "$0")/_/husky.sh". "$(dirname "$0")/common.sh"[ -n "$CI" ] && exit 0npm run lint:lint-staged
  1. 增加 lint-staged 配置文件
// .husky/lint-staged.config.jsmodule.exports = {  '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],  '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],  'package.json': ['prettier --write'],  '*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],  '*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],  '*.md': ['prettier --write']}

CHANGELOG 主动生成

CHANGELOG 记录我的项目所有的 commit 信息并归类版本,能够疾速跳转到该条 commit 记录,不便晓得我的项目哪个版本做了哪些性能有哪些 bug 等信息。也不便排查 bug,对于提交记录高深莫测,不必一个一个去翻去查

用 standard-version 来实现主动生成 CHANGELOG,conventional-changelog 也能够生产 CHANGELOG,不过它举荐用 standard-version (这都是同一个团队的货色,基于 conventional-changelog 实现的)

装置

npm i -D standard-version

package.json

{  "scripts": {    "standard-version": "standard-version"  }}

commit typefeatfix 的时候执行这个命令,它会自增版本号

standard-version 提供自定义配置不同类型对应显示文案,在根目录新建 .versionrc.js 文件

module.exports = {  types: [    { type: 'feat', section: '✨ Features | 新性能' },    { type: 'fix', section: ' Bug Fixes | Bug 修复' },    { type: 'init', section: ' Init | 初始化' },    { type: 'docs', section: '✏️ Documentation | 文档' },    { type: 'style', section: ' Styles | 格调' },    { type: 'refactor', section: '♻️ Code Refactoring | 代码重构' },    { type: 'perf', section: '⚡ Performance Improvements | 性能优化' },    { type: 'test', section: '✅ Tests | 测试' },    { type: 'revert', section: '⏪ Revert | 回退' },    { type: 'build', section: ' Build System | 打包构建' },    { type: 'chore', section: ' Chore | 构建/工程依赖/工具' },    { type: 'ci', section: ' Continuous Integration | CI 配置' }  ]}

执行以下命令,就会依据你的 commit 信息主动生成 CHANGELOG.md 文件

npm run standard-version

Lint 标准校验

ls-lint 校验文件命名

ls-lint 能够校验文件命名标准,例如 kebab-casePascalCase

装置应用

yarn add @ls-lint/ls-lint -D

在根我的项目创立 .ls-lint.yml 文件

ls:  packages/**:    .js: kebab-case    .ts: kebab-case    .d.ts: kebab-caseignore:  - .git  - node_modules

配置 package.json 脚本命令 "lint:ls-lint": "ls-lint",而后退出 .husky/pre-commit

#!/bin/sh. "$(dirname "$0")/_/husky.sh". "$(dirname "$0")/common.sh"[ -n "$CI" ] && exit 0npm run lint:ls-lint# Format and submit code according to lintstagedrc.js configurationnpm run lint:lint-staged

ESLint 校验

Eslint 是针对 EScript 的一款代码检测工具,它能够检测我的项目中编写不标准的代码,如果写出不符合规范的代码会被正告

装置依赖

  • eslint - Eslint 本体
  • eslint-plugin-vue - 实用于 Vue 文件的 ESLint 插件
  • vue-eslint-parser - 应用 eslint-plugin-vue 时必须装置的 eslint 解析器
yarn add eslint eslint-plugin-vue vue-eslint-parser -D

增加 ESLint 配置文件,根目录创立配置文件 .eslintrc.js

module.exports = {  root: true,  env: {    browser: true,    es6: true,    node: true  },  extends: ['eslint:recommended', 'plugin:vue/recommended'],  parser: 'vue-eslint-parser',  parserOptions: {    ecmaVersion: 12,    sourceType: 'module',    parser: 'babel-eslint'  },  rules: {}}

.eslintignore 配置不想被 eslint 校验的文件

*.shnode_modules*.md*.woff*.ttf.vscode.ideadist/public/docs.husky.local/binDockerfile

.husky/lint-staged.config.js 增加脚本命令 eslint --fix

增加 --fix 能够开启 eslint 的主动修复性能。
如果您应用的编辑起是 vscode ,请装置 eslint 的插件进行应用喔
有时候编辑器的问题,配置不会立马失效,须要敞开编辑器从新开启我的项目,让编辑器从新加载配置。

Prettier

Prettier 对 js 或者 css 等代码进行格式化,能够保障团队的代码格调保持一致。

装置

yarn add -D prettier

根目录新建 prettier.config.js 文件

module.exports = {  // 单行代码的最大宽度  printWidth: 120,  // 指定每个缩进级别的空格数  tabWidth: 2,  // 应用制表符 (tab) 缩进  useTabs: false,  // 在语句开端打印分号  semi: true,  // 多行时尽可能打印尾随逗号  trailingComma: 'none',  // 应用单引号而不是双引号  singleQuote: true,  // 在对象文字中打印括号之间的空格  bracketSpacing: true,  // 将 > 多行 JSX 元素放在最初一行的开端,而不是独自放在下一行(不适用于自闭元素)。  jsxBracketSameLine: false,  // auto | lf | crlf | cr  endOfLine: 'lf'}

.husky/lint-staged.config.js 配置命令格式化 prettier --write

.prettierignore 疏忽格式化

# 以下文件夹不会被格式化/dist/*.local.output.js/node_modules/****/*.svg**/*.sh/public/*

ESLint 配合 Prettier

装置依赖

  • eslint-config-prettier - 敞开所有与 eslint 抵触的规定,请留神,该插件只有敞开抵触的规定的作用
  • eslint-plugin-prettier - 如果您禁用与代码格局相干的所有其余 ESLint 规定,并且仅启用检测潜在谬误的规定,则此插件成果最佳。换句话说,就是你想独自配置某一项时,应用这个插件。值得一提的是,这个插件附带了一个 plugin:prettier/recommended 配置,能够和 eslint-config-prettier 一次性设置插件。该配置最次要的就是解决回调函数的格式化问题
yarn add eslint-config-prettier eslint-plugin-prettier -D
  1. 批改 .eslintrc.js
{  extends: [    'eslint:recommended',    'plugin:vue/recommended',    'plugin:prettier/recommended',  ],}

Stylelint

Stylelint 是一款弱小的古代 linter,可帮忙您防止谬误并强制执行款式中的约定,帮忙对立团队中书写款式代码的规定。

Stylelint 是一个弱小、先进的 CSS 代码查看器(linter),能够帮忙你躲避 CSS 代码中的谬误并保持一致的编码格调。

装置依赖

  • stylelint - Stylelint 本体
  • stylelint-config-prettier - 敞开 Stylelint 中与 Prettier 中会发生冲突的规定。
  • stylelint-config-rational-order - 对 CSS 申明进行排序
  • stylelint-config-standard - Stylelint 官网举荐规定
  • stylelint-order 应用 stylelint-config-rational-order 时依赖的模块

装置

yarn add stylelint stylelint-config-prettier stylelint-config-standardstylelint-config-rational-order stylelint-order -D

stylelint.config.js 配置文件

module.exports = {  root: true,  plugins: ['stylelint-order'],  extends: ['stylelint-config-standard'],  rules: {    'selector-pseudo-class-no-unknown': [      true,      {        ignorePseudoClasses: ['global']      }    ],    'selector-pseudo-element-no-unknown': [      true,      {        ignorePseudoElements: ['v-deep']      }    ],    'at-rule-no-unknown': [      true,      {        ignoreAtRules: ['function', 'if', 'each', 'include', 'mixin']      }    ],    'no-empty-source': null,    'named-grid-areas-no-invalid': null,    'unicode-bom': 'never',    'no-descending-specificity': null,    'font-family-no-missing-generic-family-keyword': null,    'declaration-colon-space-after': 'always-single-line',    'declaration-colon-space-before': 'never',    'declaration-block-trailing-semicolon': 'always',    'rule-empty-line-before': [      'always',      {        ignore: ['after-comment', 'first-nested']      }    ],    'unit-no-unknown': [true, { ignoreUnits: ['rpx'] }],    'order/order': [      [        'dollar-variables',        'custom-properties',        'at-rules',        'declarations',        {          type: 'at-rule',          name: 'supports'        },        {          type: 'at-rule',          name: 'media'        },        'rules'      ],      { severity: 'warning' }    ],    // Specify the alphabetical order of the attributes in the declaration block    'order/properties-order': [      'position',      'top',      'right',      'bottom',      'left',      'z-index',      'display',      'float',      'width',      'height',      'max-width',      'max-height',      'min-width',      'min-height',      'padding',      'padding-top',      'padding-right',      'padding-bottom',      'padding-left',      'margin',      'margin-top',      'margin-right',      'margin-bottom',      'margin-left',      'margin-collapse',      'margin-top-collapse',      'margin-right-collapse',      'margin-bottom-collapse',      'margin-left-collapse',      'overflow',      'overflow-x',      'overflow-y',      'clip',      'clear',      'font',      'font-family',      'font-size',      'font-smoothing',      'osx-font-smoothing',      'font-style',      'font-weight',      'hyphens',      'src',      'line-height',      'letter-spacing',      'word-spacing',      'color',      'text-align',      'text-decoration',      'text-indent',      'text-overflow',      'text-rendering',      'text-size-adjust',      'text-shadow',      'text-transform',      'word-break',      'word-wrap',      'white-space',      'vertical-align',      'list-style',      'list-style-type',      'list-style-position',      'list-style-image',      'pointer-events',      'cursor',      'background',      'background-attachment',      'background-color',      'background-image',      'background-position',      'background-repeat',      'background-size',      'border',      'border-collapse',      'border-top',      'border-right',      'border-bottom',      'border-left',      'border-color',      'border-image',      'border-top-color',      'border-right-color',      'border-bottom-color',      'border-left-color',      'border-spacing',      'border-style',      'border-top-style',      'border-right-style',      'border-bottom-style',      'border-left-style',      'border-width',      'border-top-width',      'border-right-width',      'border-bottom-width',      'border-left-width',      'border-radius',      'border-top-right-radius',      'border-bottom-right-radius',      'border-bottom-left-radius',      'border-top-left-radius',      'border-radius-topright',      'border-radius-bottomright',      'border-radius-bottomleft',      'border-radius-topleft',      'content',      'quotes',      'outline',      'outline-offset',      'opacity',      'filter',      'visibility',      'size',      'zoom',      'transform',      'box-align',      'box-flex',      'box-orient',      'box-pack',      'box-shadow',      'box-sizing',      'table-layout',      'animation',      'animation-delay',      'animation-duration',      'animation-iteration-count',      'animation-name',      'animation-play-state',      'animation-timing-function',      'animation-fill-mode',      'transition',      'transition-delay',      'transition-duration',      'transition-property',      'transition-timing-function',      'background-clip',      'backface-visibility',      'resize',      'appearance',      'user-select',      'interpolation-mode',      'direction',      'marks',      'page',      'set-link-source',      'unicode-bidi',      'speak'    ]  },  ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts']}

.stylelintignore 疏忽校验目录文件

/dist/*/public/*public/*

.husky/lint-staged.config.js 减少命令 stylelint --fix

与 Prettier 配合

stylelint 会与 prettier 产生抵触,要做兼容

装置

yarn add stylelint-config-prettierstylelint-scss stylelint-config-standard-scss postcss postcss-html postcss-scss -D
  • stylelint-config-prettier ---- 基于 prettier 代码格调的 stylelint 规定
  • stylelint-config-standard-scss ---- 针对 scss 的规范可共享配置。
  • postcss ---- 用于 postcss-html 和 postcss-scss 的反对
  • postcss-html ---- 解析 <style>vue、html 文件标签中的款式
  • postcss-scss ---- 解析 <style lang=“scss”> 下的 scss 款式

批改 stylelint.config.js

module.exports = {  plugins: ['stylelint-order'],  customSyntax: 'postcss-html',  extends: ['stylelint-config-standard', 'stylelint-config-standard-scss']}

Lint 配置上可能不欠缺,在遇到问题后会持续欠缺和补充