GuideCodeLint是前端工程中的一个重要环节(什么是codelint?),可以帮助我们及时部署代码在部署到生产环境之前的方式发现错误并改正,也可以规范我们的编码习惯,让团队的编码风格保持一致。CodeLint的工作原理是利用一些lint工具对代码进行静态分析,适时触发校验,提示错误。注意:本文可能无法涵盖所有??知识点。如有知识盲点,请主动查看并补充,也可在文章底部留言交流。1.Lint有哪些种类?随着nodejs和前端工程化的发展,前端圈产生了很多成熟的Lint工具,主要包括:ECMAScript/JavaScript代码编写的eslint规范和验证TypeScript代码编写的tslint规范和验证stylelint的编写规范和验证css/scss/less代码编写commitlint负责验证commitmsg是否符合标准的prettier或beautifyjs统一代码排版格式另外,我们还需要一些辅助工具:husky可以监听githooksnodejs包更方便nodejs开发人员来处理githooks任务。lint-staged可以将git“staged”文件作为参数传递给您要执行的shell脚本。读到这里,你可能对这些工具的作用和用法还有疑惑,但没关系。暂时你只需要知道我们会在各个环节使用这些工具来严格验证我们的代码即可。接下来,让我们深入了解它们。2.集成commitlint相信大家对Git并不陌生。不知道大家有没有过这样的经历,自己提交的gitcommitmsg是看不懂的。在小团队中,可能我们更关注业务输出,并不关心这些细节。随着团队的成长,commitmsg的标准化至关重要。它意味着我们是否知道我们和我们的同事对代码做了什么,它对代码排查、回滚甚至甩锅起着关键作用。本着“工具比人靠谱”的原则,我们希望通过在项目中集成一些工具,让我们在执行gitcommit-m'msg'时自动校验msg的内容,而不需要额外执行其他命令.Husky和commitlint正好可以解决我们的痛点。2.1.理解githooks和husky在正式集成commitlint之前,首先要介绍一下githooks。顾名思义,hooks就是“钩子”的意思。它是“发布-订阅模型”的实现,DOM事件(点击、悬停等),Git也预定义了一些“事件钩子”,如“commit-msg”、“pre-commit”等.,当我们执行相应的Git操作时就会触发,从而通知订阅该事件的shell脚本文件来处理我们要执行的任务,这些shell脚本文件存放在项目下的.git/hooks目录下根目录,如图:我们可以通过编写这些shell脚本文件来自定义我们的验证任务,但是大多数前端工程师linux/windowsshell并不擅长,这跟我们平时的工作重点有关,所以我们很难通过编写githooks脚本来优化前端工作流程。Nodejs改变了这一切,它让JavaScript拥有了控制“操作系统”的能力,你只需要安装nodejs包husky,它会在.git/hooks目录下帮我们自动生成shell脚本,我们就可以轻松使用更熟悉的Nodejs处理githooks任务,无需关注shell脚本的实现细节。在开发环境执行以下命令安装husky,如下:npminstallhusky--save-dev在项目根目录下的package.json文件中添加如下配置,在hooks字段下添加githooks监控任务配置,如下://这是NPM原生支持的脚本执行定义。执行"npmrunscriptname"时,执行"scripts":{"test":"nodetest.js"},//这是执行husky扩展定义方法的脚本,对应git时执行"husky"hooksaretriggered:{"hooks":{//可以执行一个js文件,把控制权交给我们比较熟悉的nodejs"pre-commit":"nodeheihei.js",//也可以调用其他脚本或者执行一个nativeshell命令"commit-msg":"npmruntest&&echosucceed"}}以上配置仅作为测试示例,不需要集成到项目中。大家可以先写个小demo试用一下,加深对githooks和husky的理解。2.2.安装配置commitlint当然别忘了我们今天的主角commitlint。我们需要使用它的cli(命令行界面)能力来配置一套我们自己的gitcommitmsg验证规则。首先安装@commitlint/cli和@commitlint/config-conventional,如下:commitlint提供的line工具,安装后会安装cli脚本放在./node_modules/.bin/目录下@commitlint/config-conventional是社区共享的一些配置,我们可以展开这些配置,也可以不安装这个package自定义配置接下来是初始化@commitlint/cli文件的配置,在项目根目录下创建一个名为commitlint.config.js的文件,代码如下:/***feature:newfeature*update:更新功能*fixbug:修复功能的错误*refactor:重构功能*optimize:优化构建工具或运行时性能*style:仅样式更改*docs:仅文档添加/更改*chore:更改构建过程或辅助工具*/module.exports={ext结束:['@commitlint/config-conventional'],规则:{'type-enum':[2,'always',['feature','update','fixbug','refactor','optimize','style','docs','chore']],'type-case':[0],'type-empty':[0],'scope-empty':[0],'scope-case':[0],'subject-full-stop':[0,'never'],'subject-case':[0,'never'],'header-max-length':[0,'always',72]}};//这些配置是什么意思?请自行参考commitlint文档。最后,我们需要在package.json中配置我们的husky选项。代码片段如下:"scripts":{//ignore"build":"nodebuild/build.js"},"husky":{"hooks":{//Key"commit-msg":"commitlint-EHUSKY_GIT_PARAMS"}}这个配置告诉githooks,当我们在当前项目中执行gitcommit-m'testcommit'时会触发commit-msg事件hooks,通知husky执行commitlint-EHUSKY_GIT_PARAMS命令,其中就是我们刚刚安装的./node_modules/.bin/commitlint,它会读取commitlint.config.js的配置规则,应用我们刚刚提交的commitlint测试,提交这串文本进行验证。如果验证失败,则在终端输出错误,并终止commit。:看不懂上图没关系,但你至少要看懂下图:上面我们讲解了githooks、husky和commitlint的工作流程。了解husky的工作原理非常重要,后面会讲到使用,请务必了解。3.集成ESLint大家都知道JavaScript语法有一些设计缺陷,编码风格也各不相同。举个简单的例子,A??同学在定义字符串时喜欢用双引号,而B同学则习惯用单引号。不讨论谁的风格更合理,但我们至少应该统一一下,这样会降低我们代码的管理成本。在我们的项目中集成eslint已经成为解决这个问题的成熟方案。可以说任何一个中大型项目都应该使用ESlint来约束我们的JavaScript代码。接下来我们看看我们是如何在webpack构建的Vue项目中集成eslint的。3.1.安装配置eslint-cli首先在开发环境安装eslint,代码如下:npminstall--save-deveslint和commitlint一样,都会在./node_modules/.bin/下创建一个名为eslint的文件目录。cmd执行脚本(windows系统下生成cmd脚本,linux系统下生成sh脚本,由nodejs自动帮你处理),eslint.cmd是eslint包提供的cli工具。在项目的根目录中创建一个名为.eslintrc.js的文件。eslint.cmd执行时,默认会读取文件中的配置。初始配置如下:module.exports={root:true,env:{es6:true,node:true},plugin:[],extends:[],rules:[]}完成以上配置后,我们可以使用eslint的cli功能来验证我们的js代码。在根目录终端输入以下命令,验证检查当前目录下所有js文件,修复可以自动修复的错误。代码如下:./node_modules/.bin/eslint./**--fix如果你的npm版本在5.2以上,可以使用npx来执行./node_modules/.bin下面的脚本,比较方便,如下:npxeslint./**--fix从下图可以看出,eslint已经生效:3.2.扩展eslint的配置和规则当然只有这些还不够,我们需要个性化的集成一些其他的辅助包或者配置一套自己的eslint环境,让它更符合我们项目的需要。npm上有很多社区提供的共享配置。我们可以选择适合自己的配置,直接集成。比如我们在Github中搜索“eslint-config-”,就会发现有很多开源的共享配置可用,如图:大家可以根据项目的需要选择合适的配置。这里我们使用eslint-config-standard的共享配置,执行安装:npminstall--save-deveslint-config-standard修改配置文件如下:module.exports={root:true,env:{es6:true,node:true},extends:['standard']}下面我们深入eslint-config-standard这个包,看看它做了什么,如下对于它的一些内部代码段:从上图我们可以发现eslint-config-standard内部扩展了eslint-plugin-import、eslint-plugin-node和eslint-plugin-promise等插件,它们的功能分别是:eslint-plugin-importenableseslinttosupporttheidentificationandimport/export的验证eslint-plugin-node使eslin支持nodejs原生模块的识别和验证eslint-plugin-promise使promise最佳实践的验证注意:如果你不使用eslint-config-standard,但仍然想要要支持以上功能,请安装自己集成,自定义集成代码这里就不展示了。3.3.让eslint支持vue的识别验证。如果你是vue项目,还需要安装如下包:npminstall--save-deveslint-plugin-vue官网介绍eslint-plugin-vue》这个插件可以让我们检查和<使用ESLint的.vue文件的脚本>。”集成此插件将使eslint能够处理.vue文件。另外,我们还需要安装babel-eslint包,安装命令如下:npminstall--save-devbabel-eslintbabel-eslint是一个es语法解析器,用它来解析代码可以提供一些es实验阶段语法验证支持,最后我们完整的eslint配置如下:module.exports={root:true,env:{es6:true,node:true},parserOptions:{parser:'babel-eslint'},extends:['plugin:vue/essential',//识别vue语法,并提供vue默认验证规则'standard'],rules:[]//一些你想覆盖的规则}如果你还需要修改配置或者需要其他包的集成,请自己完成扩展,这个比较考验大家的动手能力。4、StyleLint的集成Stylelint和eslint的功能和原理相似,只是验证对象不同。主要用来校验你的样式代码,比如css,scss,less等,这里就不过多介绍了,相信聪明的你可以借鉴刚才的eslint文章,直接上传代码:npminstall--save-devstylelintnpminstall--save-devstylelint-config-standard在本地创建一个名为.stylelintrc.js的配置文件,配置如下:"usestrict";module.exports={ignoreFiles:["./**","!./client/views/**/*.vue","!./client/views/**/*.scss","!./client/styles/**/*.scss","!./client/plugin/**/*.vue","!./client/plugin/**/*.scss"],extends:["stylelint-config-standard"],rules:{//一些配置可以在这里重写}};测试校验能力,在项目根目录下输入代码:npxstylelint./--fix以上代码会默认读取.stylelintrc.js的配置,忽略不需要校验的目录。5.我们是否需要在格式化后的代码中加入hardLint?我们知道eslint可以限制JavaScript的使用,但是它限制代码布局格式的能力非常有限。同时,它不能限制css、scss、html等,如果我们想对我们的代码进行格式化,加入强约束,我们还需要像prettier或者beautify这样的工具,尤其是prettier,可以配合eslint使用。Prettier对react和jsx的支持很好,可惜prettier格式化Vue的能力没有那么强大,可配置项也少得可怜。阿三没用过,考虑到工具链的调整还需要逐步完善,阿三三,我也不太想马上做格式化强校验。感兴趣的同学可以自行研究。外部链接:Prettier对Vue的格式化功能有限。6.Lint的执行时间是什么时候?上面我们讲了,如何为我们的项目集成commitlint、eslint和stylelint,最后实现了。当我们执行gitcommit-m'testsubmission'时,会验证commit-msg的规范性,也可以在我们的项目根目录下执行npxeslint./--fix或npxstylelint./--fix来验证并修复我们的代码。但实际上,除了commit-msg的校验之外,已经满足了我们的真实场景,后面的cli手动校验已经不能满足我们项目的需求了。我们期望的是自动完成这一切。那么什么时候执行自动lint最好呢?这取决于你的需求,这里是我总结的一些常见的验证机会。6.1.在编辑器中执行softlintsoftlint是我给自己起的名字,意思是“软检查”。顾名思义,不是必须的,但却是非常必要的。它的使命是在开发环境中提醒开发者哪里出现了错误,请提前改正,是工具的加持,有助于提高你的排错效率。softlint一般是指在开发者的编辑器上做的验证,属于“本地验证”,也属于“增量验证”,因为大多数情况下编辑器只会验证你打开的文件,当然也可以配置为“全量”,但是这样会消耗大量的计算机性能。下面以vscode为例,看看如何使用vscdoe的插件对项目代码实现softlint。首先打开vscode的插件选项,搜索并安装ESLint插件和stylelint插件,安装完成后重启你的vscode,打开你项目中的.vue或者.js文件,发现验证就可以了,就这么简单,我们不需要额外的配置。为什么不需要配置?以vscode插件Eslint为例,打开插件官方介绍,可以看到这样一段话,“如果你本地安装了ESLint,那么Windows下运行.node_modules.bineslint--init和./node_modules/.bin/eslint--initunderLinuxandMac.",似曾相识,就是执行我们上面通过npm安装的eslint和stylelint包的cli脚本,你刚刚配置好了,就可以安装使用了,是不是很简单。6.2.对本地gitcommit执行hardlint虽然我们在本地编辑器中安装了vscode插件Eslint和vscode插件stylelint,但是这个还是没有到位。只是辅助加持,并不能实现真正的“hardlint”“限制”,我们希望在某种程度上,新人在下载项目代码后可以拥有自己的验证功能(开箱即用npminstall),以及无需手动配置任何东西。我们尝试在提交过程中与commitlint同时完成eslint和stylelint的校验。如果验证失败,则无法提交代码。阿三称之为“hardlint”。我们还是期望它是一种“增量验证”,因为如果每次执行gitcommit-m时都执行npxeslint./**--fix来验证项目中的所有文件,老大就等着破产吧,太慢了,我们只需要在Git中验证staged状态的文件(gitaddfiles)即可。前面我们说过,如果我们想在执行gitcommit的时候进行一些自定义的操作,我们可以利用husky监控githooks的能力。这个时候我们可以监听pre-commithook,也就是说它会比commit-msghook先被触发,先进行eslint和stylelint的校验,再进行commitlint的校验验证通过后。我们之前已经安装了husky,那么如何实现只对staged文件进行“增量验证”呢?这时候就需要使用另一个包lint-staged,执行如下命令:npminstall--save-devlint-staged然后在包中添加如下配置。涵盖配置):{"scripts":{"eslint:fix":"eslint--fix--ext\".js,.vue\"","eslint:lint":"eslint--ext\"".js,.vue\"","stylelint:fix":"stylelint\"./**\"--fix"},"husky":{"hooks":{"pre-commit":"lint-staged","commit-msg":"commitlint-EHUSKY_GIT_PARAMS"}},"lint-staged":{"lints":{"*.{scss,css}":["npmrunstylelint:fix","gitadd"],"*.vue":["npmrunstylelint:fix","npmruneslint:fix","gitadd"],"*.{js}":["npmruneslint:fix","gitadd"]},"ignore":["**/test/**"//其他要忽略的目录...]}}注意“lint-staged”配置,它会匹配Git文件中处于暂存状态的文件名,并为这些匹配到的文件执行对应的脚本,以vue文件为例,执行gitcommit时会依次执行npmrunstylelint:fix,npm-m'test'运行eslint:fix和gitadd,如果没有报错或者报错可以自动修复(--fix),会自动添加更改,修复的代码会添加到gitstaged,继续commitlint校验。如果全部通过,将生成一个新的提交。其流程如下图所示:6.3.其他lint机会除了上面提到的编辑器中的“softlint”和commit阶段的“hardlint”,我们还可以进行“webpackloaderphase”或者“CIcontinuouslint”“Integrateremote”进行验证,但是这不一定是必要的。这取决于您的公司是否需要这种验证。有兴趣的同学可以自行研究结论。如果在阅读过程中遇到难以理解的问题,一定要尽量主动寻找答案,培养独立解决问题的能力。欢迎留言评论。
