关于Eslint-plugin的研究,今天主要讲两点:实现一个简单的插件。eslint如何处理plugin插件。接上一篇《Eslint源码探索》,今天就来一探究竟吧。今天是研究课。实现一个简单的插件官方的Plugin文档比较详细,但是内容太多。这里有几个关键步骤:生成插件模板生成规则规则规则对象配置属性描述这里单元测试生成单行注释以允许的字段为例。扩展插件的探索。提供官方模板生成工具Yeoman。同样在这里://下载pnpminstall-gyogenerator-eslint//生成模板yoeslint:plugin//生成ruleyoeslint:规则模板的结构也比较简单,提供了三个函数,都可以通过yoeslint:规则是自动生成的。docs文件说明。每个规则都有自己的md。lib核心库,包括每条规则。测试测试用例。每个规则都是一个单独的用例。依赖第三方包如下:eslint相关和test相关。requireindex包会将lib下的所有规则打包成一个对象。比较实用,以后会用在其他项目中。//requireIndex将多个文件包装成对象constrequireIndex=require("requireindex");module.exports.rules=requireIndex(__dirname+"/rules");//打印,包装的规则{//...'notes-keys':{meta:{type:'suggestion',docs:[Object],fixable:'code',schema:[Array]},create:[Function:create]}}mocha主要用于测试。接下来进入rules,了解rules的详细配置:在meta中,type比较关键,说明这条rule的必要性;problem,说明这段代码会导致错误和异常行为,需要优先处理。suggestion,表示这段代码只是一个建议,可能有更好的方法来做。布局,表示代码的美观性,例如空格、逗号、标题等。meta:{type:'suggestion',//`problem`,`suggestion`,or`layout`指定关键字包含在评论中",category:"StylisticIssues",//rulesCategoryrecommended:true,//配置文件中的"extends":"eslint:recommended"属性是否启用该规则,会只有当创建的规则被推送到eslint核心规则时才会生效。url:null,//该规则文档页面的URL},fixable:'code',//或`code`或`whitespace`//如果fixable主要用于修复功能,如果不设置fixable,eslint将默认此规则无法修复rule有options},fixable主要用来固定规则,在eslint-plugin包中这个是必须的,官方建议一定要在这里配置。对应的,create中context.report中的fix函数对应修复函数的回调。模式中定义的字段主要用于传入配置。例如,在上面的例子中,如果你想在注解中指定禁用某些字段,则需要将这些自定义禁用的字段传递到上下文中。此处用于限定传入字段的属性。当我使用这条规则时,我可以这样处理:rules:{//foo表示在notes:[2,{keyWords:['foo']}]}中禁用的字段“foo/notes-keys”返回一个对象,其中包含eslint在遍历语法树时用于访问节点的方法。有许多方法可以访问这些节点。这也是生成插件比较难的地方,因为这里需要了解AST的节点类型的知识。上图是对AST节点类型的简单总结。eslint源码中定义的访问NodeType如下。除了源码中定义的,还有第三方定义的。比如在react中,有JSXAttribute、JSXElement等自定义AST节点。这里先把创建代码放在这里,图中的Program就是AST节点访问的方法。接下来,让我们谈谈上下文。顾名思义,上下文在这里几乎是无所不能的。它主要可以帮助我们做以下几点:获取配置中的信息,比如settings和parser相关的属性。获取遍历的节点数组,如声明的变量、参数的变量、函数的变量、说明符的变量等。获取与源文件关联的文件名。获取源代码。获取范围内的所有变量和引用。报告有问题的代码。create中的逻辑比较简单。获取单行注释,然后判断配置中是否有字段,有则上报。此插件已发布在npm上,供您参考。直接在npm上搜索eslint-plugin-foo,只有一条规则。也可以点击文章底部原文链接查看github上的源码。使用起来也很简单,//.eslintrc.jsplugins:['foo'],rules:{"foo/notes-keys":[2,{keyWords:['foo']}]}在发布之前,我们有来写单元测试吧,也简单。eslint提供了RuleTester方法,我们只需要写几个简单的例子。construle=require("../../../lib/rules/notes-keys"),RuleTester=require("eslint").RuleTester;construleTester=newRuleTester();consterrMsg=(msg)=>`Notescontaindisallowedcharacters${msg}`;ruleTester.run("notes-keys",rule,{valid:['//sssss','//attr'],//有效,无效invalid:[{code:`//xxx:testcontent`,errors:[{message:errMsg('xxx')}],options:[{//通过options配置自定义参数keyWords:['xxx']}],//添加修复必须添加输出,并且内容output输出必须与规则output:`//:testcontent`,},{code:`//str11:consts='Testcontent'`,errors:[{message:errMsg('str')}],options:[{//通过options配置自定义参数keyWords:['str']}],//addfix必须添加输出,输出输出的内容要与规则输出中修复返回的结果:`//11:consts='testcontent'`,}],});运行eslint如何加载plugin插件。插件的处理不在eslint库中,引用了另一个库@eslint/eslintrc。这里需要注意的是,node在v14版本之后支持了ES模块的编写。总之,我们可以在节点文件中使用import/export。然后通过命令行执行node命令。接上一篇,我们讲了ConfigArrayFactory中plugin、extends、parser的处理。这里的探索过程也很简单,下载@eslint/eslintrc的源码,npminstall准备好后,我们创建一个demo.js文件。顺便下载我们发布的插件eslint-plugin-foo,添加到配置文件中。demo中的代码如下。我们固定一个路径让它流下来,通过node命令执行,这样我们就可以查看它执行的步骤。插件的大致加载过程和在源码中的位置如下:在loadInDirectory中,我们可以查看到当前的配置文件对象,也就是我们配置foo的地方。这个时候插件还没有加载。在_loadPlugin中可以获取到foo配置的数据。最后,将生效的规则收集到configArray中。最后在demo.js中打印配置。foo插件已经变成了一个对象,规则也放在了rules里面。对plugin的理解,先到这里。
