我们的代码库在多人维护的时候,经常会出现代码风格或者代码质量不一致,提交信息乱七八糟的情况。当然,即使是一个人的代码库,有时候自己写代码的时候,不太注意细节,也会出现风格不一致的情况。这篇文章就是为了解决这个问题而诞生的。阅读这篇文章不需要很长时间。如果您的代码库还没有配置这些配置,那么现在是您展示您的技能并武装您的代码库的好时机。1.规范commit信息首先来看angular代码库的commit记录,如图:我们可以使用commitizen和husky来规范代码库的commit。安装如下依赖:npminstall@commitlint/cli@commitlint/config-conventionalhusky-D如果没有安装commitizen,先全局安装:npminstallcommitizen-g在package.json中添加husky字段。{"husky":{"hooks":{"commit-msg":"commitlint-EHUSKY_GIT_PARAMS"}},}husky是一个githook工具,使用husky,我们可以很方便的在package.json中配置githook脚本,例如:pre-commit,pre-push,commit-msg等(1)创建commitlint.config.js文件module.exports={extends:["@commitlint/config-conventional"],};以后请用gitcz代替gitcommit提交信息,我们来看看,假设我们随便写一个gitcommit-m'fixbug'会提示什么?使用gitcz填写commit的内容。gitcz的类型说明:虽然我们现在可以标准化提交信息,但我们可能不喜欢默认的交互方式。例如,简化描述即可。如果不想提示我写详细的描述,那么可以使用cz-customizable进行定制。(2)自定义提交指令安装cz-customizable:npminstallcz-customizable-Dcz-customizable是一个可自定义的Commitizen插件,有助于实现一致的提交信息。cz-customizable适用于大型团队自定义范围和提交类型。新建一个.cz-config.js:在项目根目录下新建一个.cz-config.js文件:官方提供了一个配置信息,大家可以去这个地址查看:https://github.com/leoforfree/cz-customizable/blob/master/cz-config-EXAMPLE.js//.cz-config.jsmodule.exports={types:[{value:'feat',name:'feat:Anewfeature'},{value:'fix',name:'fix:Abugfix'},{value:'docs',name:'docs:Documentationonlychanges'},{value:'style',name:'style:Changestthatdonotaffectthemeaningofthecode\n(空白,格式化,missingsemi-colons,etc)',},{value:'refactor',name:'refactor:Acodechangethatneitherfixesabugnraddsafeature',},{value:'perf',name:'perf:Acodechangethatimprovesperformance',},{value:'test',name:'test:Addingmissingtests'},{value:'chore',name:'chore:Changestothebuildprocessorauxiliarytools\nandlibrariessuchasdocumentationgeneration',},{value:'revert',name:'revert:Reverttoacommit'},{value:'WIP',name:'WIP:Workinprogress'},],scopes:[{name:'accounts'},{name:'admin'},{name:'exampleScope'},{name:'changeMe'}],allowTicketNumber:false,isTicketNumberRequired:false,ticketNumberPrefix:'TICKET-',ticketNumberRegExp:'\\d{1,5}',//需要匹配字段类型的值。例如:'fix'/*scopeOverrides:{fix:[{name:'merge'},{name:'style'},{name:'e2eTest'},{name:'unitTest'}]},*///overridethemessages,defaultsareasfollowmessages:{type:"Selectthetypeofchangethatyou'recommitting:",scope:'\nDenotetheSCOPEofthischange(optional):',//usedifallowCustomScopeistruecustomScope:'DenotetheSCOPEofthischange:',subject:'WriteaSHORT,IMPERATIVEtensedescriptionofthechange:\n',body:'ProvideaLONGERdescriptionofthechange(可选).Use"|"tobreak换行:\n',breaking:'ListanyBREAKING'oppion)\(,footer:'ListanyISSUESCLOSEDbythischange(可选)。例如:#31,#34:\n',confirmCommit:'Areyousureyouwanttoproceedwiththecommitabove?',},allowCustomScopes:true,allowBreakingChanges:['feat','fix'],//skipanyquestionsyouwantskipQuestions:['body'],//limitsubjectlengthsubjectLimit:100,};types:描述修改的性质,是bugfix还是feat,在这里定义scopes:定义后,我们可以使用上下键来选择作用域类型,它会询问我们有关中断消息的信息。allowCustomScopes:设置为true,选择scope时,会有empty和custom可供选择,顾名思义,选择empty表示默认scope,如果选择custom,可以自己输入信息skipQuestions:指定哪些步骤toskip,比如跳过我们刚刚说的详细描述,设置为scope:['body'],假设我们的项目不会涉及到相关问题,我们可以设置为scope:['body','footer']subjectLimit:描述的长度限制。这里就不演示每个字段修改后的情况了。根据该字段的描述,建议如果要自定义提交规则,可以在本地修改验证。公司内部代码库不需要管理问题,另外,我不喜欢写很长的描述,所以我跳过了正文和页脚。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"}}现在,我们规范了提交信息,但是我们没有规范提交的代码。在一个代码库中,经常有2个空格/4个空格混用,有的地方写;,有的地方不写;,风格也不统一。比如我们希望提交到git库的代码能够通过eslint检查或者通过测试。我们可以在预提交钩子的帮助下做这些事情。2.代码提交前检查安装依赖:npminstalllint-staged-D使用pre-commithook"husky":{"hooks":{"pre-commit":"lint-staged"}},"lint-staged":{"**/*.js":["prettier--write","eslint"]}这样配置后,每次提交的文件(不是整个项目)都会prettier格式化和eslint检查,只有通过后,commit才能成功。(一)eslint和prettier配置我的项目是react项目,下面是我的配置。安装eslint和prettier相关依赖:npminstalleslinteslint-config-prettiereslint-plugin-promiseeslint-plugin-reacteslint-plugin-react-hooksprettierbabel-eslint-Dnew.prettierrc.js当然你也可以在package.prettier字段配置。json,这里我配置成一个单独的文件,方便后期维护。module.exports={printWidth:100,//长度超过100个换行符singleQuote:true,//使用单引号};如果你有一些文件不需要prettier格式化,可以新建一个.prettierignore文件,如下:distnode_modulespublicnew以下是我在.eslintrc.js文件中的配置:module.exports={settings:{反应:{pragma:'React',version:'detect'}},//babelparsertosupportES6/7featuresparser:'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,//禁用控制台'no-constant-condition':1,//禁止使用常量表达式'noinconditions-control-regex':1,//禁止在正则表达式中使用控制字符'no-debugger':2,//Disabledebugger'no-dupe-args':2,//禁止函数de重名finitionsParameter'no-dupe-keys':2,//禁止对象字面量中的重复键'no-duplicate-case':2,//禁止重复的case标签'no-const-assign':1,//是forbiddentomodifythevariabledeclaredbyconst'no-empty':1,//禁止出现空语句块'no-empty-character-class':2,//禁止使用空字符集'no-在正则表达式中ex-assign':2,//禁止对catch子句的异常参数重新赋值'no-extra-boolean-cast':1,//禁止不必要的布尔转换'no-extra-semi':1,//禁止不必要的semicolons'no-func-assign':2,//禁止函数声明的重新赋值'no-inner-declarations':0,//禁止嵌套块中的变量声明或函数声明,ES6不需要禁止'no-invalid-regexp':2,//禁止RegExp构造函数中的无效正则表达式String'no-irregular-whitespace':1,//禁止字符串和注释外的不规则行为Blank'no-obj-calls':2,//禁止将全局对象作为函数调用,例如Math()JSON()'no-regex-spaces':1,//禁止多个正则表达式字面量空格'no-sparse-arrays':1,//禁用稀疏数组'no-unexpected-multiline':1,//禁止混淆多行表达式'no-unreachable':1,//禁止Unreachable代码'no-unsafe-finally'出现在return,throw,continue,andbreakstatements:2,//禁止finally语句块中的控制流语句'no-unsafe-negation':1,//禁止对关系运算符的左操作数使用否定运算符'use-isnan':2,//需要使用isNaN()来检查NaN,比如isNaN(foo),notfoo==NaN'valid-typeof':2,//强制typeof表达式与有效字符串进行比较(eg:'undefined','object','boolean','number','string','function','symbol')'no-case-declarations':1,//词法声明'no-empty-pattern'不是allowedincaseclause:2,//空解构模式'no-fallthrough'isforbidden:2,//Casestatementisforbiddentofallthrough'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,//禁止赋值toclasses'no-dupe-class-members':2,//禁止类成员重名'no-new-symbol':2,//禁止Symbol和new操作使用'no-this-before-super':2,//禁止在构造函数中调用super()之前在生成器函数中使用this或super'require-yield':2,//requireyield'no-mixed-spaces-and-tabs':1,//要求不适用空格,tab混合使用'react/forbid-prop-types':[1,{forbid:['any']}],//ForbidcertainSomepropTypes'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在数组或迭代器中有一个键属性'react/jsx-max-props-per-line':[1,{maximum:1}],//限制JSX中单行的最大道具数'react/jsx-no-duplicate-props':2,//防止JSX中的重复道具'react/jsx-no-undef':1,//禁止在JSX中未声明variable'react/no-string-refs':1,//Usingstringliteralsinrefattributesisdeprecated'react/jsx-uses-react':1,//防止反应被错误标记为未使用'react/jsx-uses-vars':1,//防止JSX中使用的变量被错误地标记为未使用'react/no-danger':1,//防止使用危险的JSX属性'react/no-did-update-set-state':2,//PreventusingsetState'react/no-did-mount-set-state'incomponentDidUpdate':0,//PreventusingsetState'react/no-direct-mutation-state'incomponentDidUpdate':2,//Preventthis.stateassignment'react/no-unknown-property':2,//防止使用未知DOM属性'react/prefer-es6-class':1,//强制执行ES5或ES6classesforReactcomponents'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,//不要使用deprecatedmethods'react/jsx-equals-spacing':1,//在JSX属性中强制或禁止等号周围有空格'react/wrap-multilines':0,'comma-dangle':1,//对象文字项不能在末尾有逗号'react/n'o-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'}};现在,你不能再随心所欲地向你的代码库提交文件了,但是eslint和prettier的规则必须和团队成员协商好~
