使用后台代码规范是软件开发领域经久不衰的话题。几乎所有的工程师在开发过程中都会遇到,或多或少都想过。随着前端应用的规模和复杂度的增加,越来越多的前端工程师和团队开始关注JavaScript代码规范。主要解决的问题:对于独立开发者,或者执行能力强、技术场景相对单一的小团队,直接使用ESLint及其生态提供的一些标准解决方案,能够以相对较低的成本实现JavaScript代码规范的实现。如果再结合一些辅助工具(比如husky、lint-staged),整个过程会更加顺畅。ESLint对工程代码进行静态检查,发现并修复不符合规范的代码。如果想降低配置成本,也可以直接使用开源的配置方案,比如eslint-config-airbnb或者eslint-config-standard。1.了解代码检查代码检查,顾名思义就是检查代码,发生在开发阶段,可以有效帮助开发者减少JavaScript粗心的代码,比如语法错误、未定义的变量、未使用的变量等。此外,代码检查还可以约束和统一开发人员的代码风格,有利于团队协作。让我们从三个方面来分析,加深对代码检查的实际理解。这三个方面就是以下三点:1)代码检查的功能2)代码检查的类型3)代码检查的工具1、代码检查的功能代码检查这方面大概可以帮助我们做以下三件事:语言语法检查:例如检查字符串引号或函数调用括号不匹配等问题。代码错误检查:例如,检查开发人员是否使用了不存在的变量,或者变量已定义但未使用。代码风格检查:比如检查开发者没有使用分号(与选择的风格有关)等问题。2.代码检查的方式根据代码检查发生的时间和场景的不同来划分。我把代码检查的方式分为以下四种:Checkwhilecoding:在写代码的时候检查,通常是IDE自动实时检查和代码提示的形式。Checkaftercoding:写完代码后进行检查,一般是手动调用check脚本/工具检查代码或者代码保存后IDE自动检查当前文件。Pre-buildinspection:构建前检查,通常以代码检查的形式作为构建任务的前置环节,代码检查在构建过程中自动触发。Pre-commitcheck:gitcommitpre-check,通常以代码检查的形式作为gitcommit的一个hooks任务,在代码提交前自动触发代码检查。了解代码检查的方式非常重要,这直接体现了对代码检查本身概念的掌握程度。3、代码检查工具代码检查的实现通常不仅仅是字符串的分析处理,会涉及到大量的语法分析。由于涉及语法,因此需要针对不同的代码使用不同的代码检查工具。一般来说,我们会使用Eslint工具来检查JavaScript和Typescript代码,使用stylelint工具来检查样式代码。2.ESLint特性介绍目前比较常见的解决方案——ESLint,它是一个插件式的JavaScript代码静态检查工具,其核心是对解析得到的AST(AbstractSyntaxTree,抽象语法树)进行模式匹配代码,定位不符合约定规范的代码。1.插件下图简要描述了ESLint的工作流程:ESLint的能力更像是一个引擎,通过提供基本的检测能力和模式约束来推动代码检测流程的运行。原始代码经过解析器解析,在流水线中对所有规则进行逐条检查,最后将所有不符合规范的代码检测出来,并作为报告输出。采用插件化设计,不仅可以独立控制所有规则,还可以自定义引入新规则。ESLint本身并没有强绑定到解析器。我们可以使用不同的解析器对原始代码进行解析。比如我们可以使用babel-eslint支持更新的版本,不同阶段的ES语法,支持JSX等特殊语法,甚至可以使用@typescript-eslint/parser支持TypeScript语言检查。2、全面、可级联、可共享的配置能力ESLint提供全面灵活的配置能力,可以配置解析器、规则、环境、全局变量等;可以快速引入另一个配置,并与当前配置级联组合为新配置;您也可以将配置的规则集发布为npm包,以便在项目中快速应用。3、社区生态相对成熟。开源社区中有很多基于ESLint的项目。有各种场景和框架的插件,还有各种ESLint规则配置方案,基本可以覆盖前端开发的所有场景。4.标准化配置方案的设计基于ESLint的插件化和可堆叠的配置特性,以及针对各种场景和框架的开源方案。ESLint配置架构如下图所示:,分类结构,其中:基础层:制定统一的基础语法和格式规范,提供通用的代码风格和语法规则配置,如缩进、尾随逗号等。框架支持layer(可选):提供对一些常见技术场景和框架的支持,包括Node.js、React、Vue、ReactNative等;这一层配置了来自开源社区的各种插件,并对各种框架的规则进行了一定程度的调整。TypeScript层(可选):该层在typescript-eslint的帮助下提供对TypeScript的支持。适配层(可选):针对特殊场景提供定制支持,比如MRN(美团内部ReactNative定制方案),配合prettier使用,或者一些团队的特殊规则需求。*具体规则如何配置可以查看:https://eslint.org/docs/rules3.将Eslint接入项目,实现代码检查Eslint是一款插件式(检查规则)JavaScript代码检查工具。概念简明扼要。需要注意的是,eslint在概念上是一个插件式的检查工具,也就是说eslint是为了检查工具和检查规则的解耦而设计的。也就是说,安装完eslint的开发依赖后,我们可以也需要选择安装一个自己喜欢的校验规则。1.安装检查工具eslintnpminstalleslint--save-dev2.安装并配置检查规则在讨论配置和安装检查规则之前,我们有必要明确一下我们的检查目标是什么。在我看来,检查对象自然是构建前的代码,是自己/自己团队写的代码(不是第三方模块)。毕竟检测的最终目的是为维修服务。我们只负责修复我们自己/我们自己团队编写的代码。即使构建后的代码和第三方代码没有通过检查,我们也不会也不应该由我们修复。检查规则在项目中通常有两种表现形式,即:配置文件中配置的规则:主窗体,通过继承和扩展声明了大量的规则;项目代码中的魔法注释:二级形式,通常用于作为配置文件中规则的特例;生成eslint配置文件:对于配置文件,我们通常使用npxeslint--init生成一个ESLint配置文件.eslintc.js,如下示例:module.exports={root:true,env:{browser:true,es2021:true},extends:['eslint:recommended','plugin:vue/essential','standard'],解析器:require.resolve('vue-eslint-parser'),parserOptions:{ecmaVersion:12,sourceType:'module'},plugins:['vue'],rules:{indent:['off',2]}}代码中的魔术注释写法:除了配置文件中的配置规则,eslint还有的方法通过代码中的魔术注释打补丁规则如下://屏蔽整行代码检查conststr1="${name}isacoder"//eslint-disable-line//屏蔽某条规则:sono-template-curly-in-stringruleforlineconststr1="${name}isacoder"//eslint-disable-lineno-template-curly-in-string*Extension:ESLintdisableinspection1.disablecoderBlock/*eslint禁用*/consle.log("foo");consle.log("bar");/*eslint-disable*/2.禁用单行(代码行后面)consle.log("foo");//eslint-disable-line3.禁用下一行//eslint-disable-next-lineconsole.log("foo")4.Disablefiles(放在代码最前面)/*eslint-disable*/consle.log("foo");consle.log("bar");4.查看Eslint编码后的JS代码对于一个工作流程的讲解,我还是更喜欢直接演示一个简单的demo,根据代码检查的逻辑,我在演示和讲解demo时会遵循以下思路,即:目标问题代码检查规则配置代码检查操作及结果修复代码操作1,目标问题代码/*eslint-disable*/constnoUsedVar=1;functionfn(){console.log('hello')cnsole.log('eslint');}fn(fn2();以上只是几行代码可以表示eslit代码检查的三个部分,分别是:syntaxerrorcodingerror:undefined,unusedcodingstyle:nosemicolon2,通过eslint--init配置代码检查规则,根据项目特点回答问题后得到的eslint配置文件如下:/*eslint-disable*/module.exports={env:{browser:true,es6:true,},extends:['airbnb-base',],globals:{Atomics:'readonly',SharedArrayBuffer:'readonly',},parserOptions:{ecmaVersion}:2018,},规则:{},};3.代码检查操作及结果第一轮检查结果先报语法错误,然后修复语法错误后,第二轮检查报了很多编码和文体错误。将两次检查的结果与问题代码相关联可以得出以下分析:constnoUsedVar=1;//查找程序:'noUsedVar'被分配了一个值但从未使用过//findprogram:'cnsole'isnotdefined}fn(//syntaxerrorfn2();//findprogram:'fn2'isnotdefined4、修复代码根据以上检查结果修复。对于不一致导致的错误在代码风格上,大部分问题都可以通过参数--fix自动修复,对于语法和编码错误,大部分只能由开发者自己手动修复,手动修复和自动修复后,问题代码可能看起来像这样:*执行代码:npxeslint--fix相关地址import{fn2}from'./test2';functionfn(){console.log('hello');console.log('eslint');}fn();fn2();五、Eslint规则实现git预提交检查讨论Eslint如何实现git预提交检查:实现hook任务流程:通过lint-staged配合husky实现git预提交检查:先执行eslinttask,然后执行gitaddtask,进入第一点,gitpre-submitcheck的原理:GitH讨论好吧。1、实现hook任务流程:使用lint-staged配合husky实现,实现步骤如下:安装husky和lint-staged模块,配置husky的hook任务流程:下面的package.json任务触发任务流程:gitadd->gitcommit1)安装husky和lint-staged模块yarnaddhusky--devyarnaddlint-staged--dev2)配置husky的hook任务流程:如下package.jsontask"scripts":{"precommit":"lint-staged"},"husky":{"hooks":{"pre-commit":"yarnprecommit"}},"lint-staged":{"*.js":["eslint--fix","gitadd"]}3)触发任务流程:gitadd->gitcommit实践发现,相比于单个husky模块实现单个任务,使用lint-staged后,gitcommit命令只会执行成功(withaddresourcesandcommitinformation)在lint阶段触发操作,这些操作只对js文件有效。2、实现gitpre-commitcheck:先执行eslint任务,再执行gitadd任务。实现步骤如下:安装husky和lint-staged模块并配置huskyhook任务流:以下package.json任务触发任务流:gitadd->gitcommit1):安装husky和lint-staged模块yarnaddhusky--devyarnaddlint-staged--dev2):配置husky的hook任务流程:如下package.json任务"scripts":{"precommit":"lint-staged"},"husky":{"hooks":{"pre-commit":"yarnprecommit"}},"lint-staged":{"*.js":["eslint--fix","gitadd"]}3)触发任务流程:gitadd->gitcommit下载并配置好这些开发包后,我们执行gitcommit后,会触发husky配置的pre-commit钩子任务,这个钩子任务把任务交给lint-staged处理,然后通过lint-staged实现js文件的代码检查和自动样式修复(错误会中断提交)重新添加,然后执行commit任务,保证代码必须在s之前通过提交代码检查。
