当咱们的代码库由很多人保护时,常常会呈现代码格调不统一或者代码品质不过关,提交信息错乱的状况,当然啦,即便是一个人的代码库,有的时候,本人写代码时不太留神细节,也会呈现格调不统一的状况。

本文正是为了解决这个问题而生,浏览本篇文章并不需要很长时间,花几分钟的工夫浏览一下,如果你的代码库还没有进行这些配置,正是你大展身手的好时机,武装一下你的代码库。


如果感觉看完文章有所播种的话,能够关注我一下哦
知乎:秃顶之路
b站:linux亦有归途
每天都会更新咱们的公开课录播以及编程干货和大厂面经
或者间接点击链接c/c++ linux服务器开发高级架构师
来课堂上跟咱们讲师面对面交换
须要大厂面经跟学习纲要的小伙伴能够加群973961276获取


1. 标准 commit 信息

首先,看下 angular 的代码库的 commit 记录,如图:

咱们能够利用 commitizenhusky 来标准代码库的 commit

装置以下依赖:
npm install @commitlint/cli @commitlint/config-conventional husky  -D复制代码

如果你还没有装置过 commitizen,那么先全局装置:

npm install commitizen -g复制代码
在 package.json 中减少 husky 字段。
{    "husky": {        "hooks": {            "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"        }    },}复制代码

huskygit hook 工具,应用 husky,咱们能够不便的在 package.json 中配置 git hook 脚本,例如: pre-commitpre-pushcommit-msg 等的。

创立 commitlint.config.js 文件
module.exports = {    extends: ["@commitlint/config-conventional"],};复制代码

此刻开始,请应用 git cz 来代替 git commit 提交信息,咱们来看看,假如咱们轻易写一个 git commit -m 'fixbug' 会提醒什么?

应用 git cz 来进行填写 commit 的内容。

git cztype 阐明:

尽管,咱们当初曾经能够标准提交信息了,然而咱们可能不喜爱默认的交互,例如,一个精简的形容就能够了,不心愿再提醒我去写具体的形容,那么就能够应用 cz-customizable 来进行定制。

自定义提交阐明

装置 cz-customizable
npm install cz-customizable -D复制代码

cz-customizable 是可自定义的 Commitizen 插件,可帮忙实现统一的 commit message

cz-customizable 适宜大型团队去自定义 scope,和 commit type

新建 .cz-config.js

在我的项目根目录下创立 .cz-config.js 文件:

官网提供了一份配置信息,能够去这个地址查看:https://github.com/leoforfree...

//.cz-config.jsmodule.exports = {  types: [    { value: 'feat', name: 'feat:     A new feature' },    { value: 'fix', name: 'fix:      A bug fix' },    { value: 'docs', name: 'docs:     Documentation only changes' },    {      value: 'style',      name:        'style:    Changes that do not affect the meaning of the coden            (white-space, formatting, missing semi-colons, etc)',    },    {      value: 'refactor',      name: 'refactor: A code change that neither fixes a bug nor adds a feature',    },    {      value: 'perf',      name: 'perf:     A code change that improves performance',    },    { value: 'test', name: 'test:     Adding missing tests' },    {      value: 'chore',      name:        'chore:    Changes to the build process or auxiliary toolsn            and libraries such as documentation generation',    },    { value: 'revert', name: 'revert:   Revert to a commit' },    { value: 'WIP', name: 'WIP:      Work in progress' },  ],  scopes: [{ name: 'accounts' }, { name: 'admin' }, { name: 'exampleScope' }, { name: 'changeMe' }],  allowTicketNumber: false,  isTicketNumberRequired: false,  ticketNumberPrefix: 'TICKET-',  ticketNumberRegExp: 'd{1,5}',  // it needs to match the value for field type. Eg.: 'fix'  /*  scopeOverrides: {    fix: [      {name: 'merge'},      {name: 'style'},      {name: 'e2eTest'},      {name: 'unitTest'}    ]  },  */  // override the messages, defaults are as follows  messages: {    type: "Select the type of change that you're committing:",    scope: 'nDenote the SCOPE of this change (optional):',    // used if allowCustomScopes is true    customScope: 'Denote the SCOPE of this change:',    subject: 'Write a SHORT, IMPERATIVE tense description of the change:n',    body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:n',    breaking: 'List any BREAKING CHANGES (optional):n',    footer: 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:n',    confirmCommit: 'Are you sure you want to proceed with the commit above?',  },  allowCustomScopes: true,  allowBreakingChanges: ['feat', 'fix'],  // skip any questions you want  skipQuestions: ['body'],  // limit subject length  subjectLimit: 100,};复制代码
  • types: 形容批改的性质是什么,是bugfix还是feat,在这里进行定义。
  • scopes: 定义之后,咱们就能够通过高低键去抉择 scope
  • scopeOverrides: 针对每一个type去定义scope
  • allowBreakingChanges: 如上设置为 ['feat', 'fix'],只有咱们type抉择了 feat 或者是 fix,才会询问咱们 breaking message.
  • allowCustomScopes: 设置为 true,在 scope 抉择的时候,会有 emptycustom 能够抉择,顾名思义,抉择 empty 示意 scope 缺省,如果抉择 custom,则能够本人输出信息
  • skipQuestions: 指定跳过哪些步骤,例如跳过咱们刚刚说的详细描述,设置其为 scope: ['body'],假如咱们的我的项目也不会波及到关联 issue,咱们能够设置其为 scope: ['body', 'footer']
  • subjectLimit: 形容的长度限度

这里我就不一一演示每个字段批改之后的状况了,依据字段的阐明,倡议如果想自定义提交规定,在本地进行批改验证,公司外部的代码库不须要治理 issue,另外,我不喜爱写长形容,所以我把 bodyfooterskip 掉了。

cz-customizable 会首先在我的项目根目录下寻找: .cz-config.js.config/cz-config.js,如果找不到,会去主目录寻找。咱们也能够在 package.json 中手动去指定配置文件的门路。

"config": {    "commitizen": {         "path": "node_modules/cz-customizable"    },    "cz-customizable": {        "config": "config/path/to/my/config.js"    }}复制代码

当初,咱们曾经标准了 commit 信息,然而没有对提交的代码进行标准,在一个代码库中,经常出现2个空格/4个空格混用,有些中央写 ;,有些不写 ;,格调不对立。例如,咱们心愿提交到git库的代码,都可能通过 eslint 查看或者是通过测试。咱们能够借助于 pre-commit 这个钩子来做这些事件。

2. 代码提交前查看

装置依赖
npm install lint-staged -D复制代码
应用 pre-commit 的 hook
"husky": {    "hooks": {        "pre-commit": "lint-staged"    }},"lint-staged": {    "**/*.js": [        "prettier --write",         "eslint"    ]}复制代码

这样配置之后,每次提交的时候,都会对要提交的文件(并不是对整个我的项目)进行 prettier 格式化和 eslint 查看,都通过之后,能力 commit 胜利。

eslint 和 prettier 配置

我的我的项目是 react 我的项目,上面是我进行的配置。

装置 eslintprettier 相干依赖:

npm install eslint eslint-config-prettier eslint-plugin-promise eslint-plugin-react eslint-plugin-react-hooks prettier babel-eslint -D复制代码
新建 .prettierrc.js

当然啦,你也能够在 package.jsonprettier 字段中配置,这里我配置成了独立的文件,以便前期保护。

module.exports = {  printWidth: 100, //长度超过100断行  singleQuote: true,//应用单引号};复制代码

如果你有一些文件不须要 prettier 进行格式化,那么能够新建一个 .prettierignore 文件,如下:

distnode_modulespublic复制代码
新建 .eslintrc.js 文件

以下是我的配置:

module.exports = {  settings: {    react: {      pragma: 'React',      version: 'detect'    }  },  // babel parser to support ES6/7 features  parser: 'babel-eslint',  parserOptions: {    ecmaVersion: 7,    ecmaFeatures: {      experimentalObjectRestSpread: true,      jsx: true    },    sourceType: 'module'  },  extends: [    'prettier',     'prettier/react'  ],  plugins: [    'promise',     'react',     'react-hooks'  ],  env: {    browser: true,    es6: true,    node: true  },  rules: {    'no-compare-neg-zero': 2, //禁止与 -0 进行比拟    'no-cond-assign': 2, //禁止条件表达式中呈现赋值操作符    'no-console': 1, //禁用 console    'no-constant-condition': 1, //禁止在条件中应用常量表达式    'no-control-regex': 1, //禁止在正则表达式中应用控制字符    'no-debugger': 2, //禁用 debugger    'no-dupe-args': 2, //禁止 function 定义中呈现重名参数    'no-dupe-keys': 2, //禁止对象字面量中呈现反复的 key    'no-duplicate-case': 2, //禁止呈现反复的 case 标签    'no-const-assign': 1, //禁止批改const申明的变量    'no-empty': 1, //禁止呈现空语句块    'no-empty-character-class': 2, //禁止在正则表达式中应用空字符集    'no-ex-assign': 2, //禁止对 catch 子句的异样参数从新赋值    'no-extra-boolean-cast': 1, //禁止不必要的布尔转换    'no-extra-semi': 1, //禁止不必要的分号    'no-func-assign': 2, //禁止对 function 申明从新赋值    'no-inner-declarations': 0, //禁止在嵌套的块中呈现变量申明或 function 申明,ES6中无需禁止    'no-invalid-regexp': 2, //禁止 RegExp 构造函数中存在有效的正则表达式字符串    'no-irregular-whitespace': 1, //禁止在字符串和正文之外不规则的空白    'no-obj-calls': 2, //禁止把全局对象作为函数调用,比方Math() JSON()    'no-regex-spaces': 1, //禁止正则表达式字面量中呈现多个空格    'no-sparse-arrays': 1, //禁用稠密数组    'no-unexpected-multiline': 1, //禁止呈现令人困惑的多行表达式    'no-unreachable': 1, //禁止在return、throw、continue 和 break 语句之后呈现不可达代码    'no-unsafe-finally': 2, //禁止在 finally 语句块中呈现控制流语句    'no-unsafe-negation': 1, //禁止对关系运算符的左操作数应用否定操作符    'use-isnan': 2, //要求应用 isNaN() 查看 NaN,如 isNaN(foo),而非foo == NaN    'valid-typeof': 2, //强制 typeof 表达式与无效的字符串(如: 'undefined', 'object', 'boolean', 'number', 'string', 'function','symbol')进行比拟    'no-case-declarations': 1, //不容许在 case 子句中应用词法申明    'no-empty-pattern': 2, //禁止应用空解构模式    'no-fallthrough': 2, //禁止 case 语句落空    'no-global-assign': 2, //禁止对原生对象或只读的全局对象进行赋值    'no-octal': 1, //禁用八进制字面量    'no-redeclare': 1, //禁止屡次申明同一变量    'no-self-assign': 1, //禁止自我赋值    'no-unused-labels': 1, //禁用呈现未应用过的标    'no-useless-escape': 1, //禁用不必要的转义字符    'no-delete-var': 2, //禁止删除变量    'no-undef': 2, //禁用应用未声明的变量,除非它们在 /*global */ 正文中被提到    'no-unused-vars': 1, //禁止呈现未应用过的变量    'constructor-super': 2, //要求在构造函数中有 super() 的调用    'no-class-assign': 2, //禁止给类赋值    'no-dupe-class-members': 2, //禁止类成员中呈现反复的名称    'no-new-symbol': 2, //禁止 Symbol 和 new 操作符一起应用    'no-this-before-super': 2, //禁止在构造函数中,在调用 super() 之前应用 this 或 super    'require-yield': 2, //要求 generator 函数内有 yield    'no-mixed-spaces-and-tabs': 1, //要求不实用space,tab混用    'react/forbid-prop-types': [1, { forbid: ['any'] }], //禁止某些propTypes    'react/prop-types': 1, //没用对props类型进行校验    'react/jsx-closing-bracket-location': 1, //在JSX中验证右括号地位    'react/jsx-curly-spacing': [1, { when: 'never', children: true }], //在JSX属性和表达式中增强或禁止大括号内的空格。    'react/jsx-key': 2, //在数组或迭代器中验证JSX具备key属性    'react/jsx-max-props-per-line': [1, { maximum: 1 }], // 限度JSX中单行上的props的最大数量    'react/jsx-no-duplicate-props': 2, //避免在JSX中反复的props    'react/jsx-no-undef': 1, //在JSX中禁止未声明的变量    'react/no-string-refs': 1, //Using string literals in ref attributes is deprecated    'react/jsx-uses-react': 1, //避免反馈被谬误地标记为未应用    'react/jsx-uses-vars': 1, //避免在JSX中应用的变量被谬误地标记为未应用    'react/no-danger': 1, //避免应用危险的JSX属性    'react/no-did-update-set-state': 2, //避免在componentDidUpdate中应用setState    'react/no-did-mount-set-state': 0, //避免在componentDidUpdate中应用setState    'react/no-direct-mutation-state': 2, //避免this.state赋值    'react/no-unknown-property': 2, //避免应用未知的DOM属性    'react/prefer-es6-class': 1, //为React组件强制执行ES5或ES6类    'react/react-in-jsx-scope': 0, //应用JSX时,必须要引入React    'react/sort-comp': 0, //强制组件办法程序    'react/sort-prop-types': 0, //强制组件属性程序    'react/jsx-sort-props': 1,    'react/no-deprecated': 1, //不应用弃用的办法    'react/jsx-equals-spacing': 1, //在JSX属性中强制或禁止等号四周的空格    'react/wrap-multilines': 0,    'comma-dangle': 1, //对象字面量项尾不能有逗号    'react/no-multi-comp': 0, //避免每个文件有多个组件定义    'flowtype/generic-spacing': 0, //泛型对象的尖括号中类型前后的空格标准    'flowtype/space-after-type-colon': 0, //类型注解分号后的空格标准    // react-hooks    'react-hooks/rules-of-hooks': 'error',    'react-hooks/exhaustive-deps': 'warn'  }};复制代码

当初,再也不能得心应手往你的代码库提交文件啦,不过 eslintprettier 的规定要和团队的成员协商制订哈~