当前位置: 首页 > 科技观察

Eslint插件与Babel插件异同深入对比

时间:2023-03-22 00:40:43 科技观察

babel和eslint都是基于AST的,一个是代码转换,一个是查错修复。babel插件和eslint插件都可以对代码进行分析和转换,那么它们有什么区别呢?在本文中,我们将探讨babel插件和eslint插件之间的区别。babel插件babel的编译过程分为解析、转换、生成三个步骤。可以指定插件,遍历AST时会调用visitor。比如我们写一个插件,在console.xx的参数中插入文件名+行列号:查看函数调用节点(CallExpression)的callee属性,如果是console.xx的API,在argumentsLiteral节点中插入一个StringLiteral字符串,值为文件名+行列号。consttargetCalleeName=['log','info','error','debug'].map(item=>`console.${item}`);constparametersInsertPlugin=({types},options)=>{return{visitor:{CallExpression(path,state){constcalleeName=path.get('callee').toString()if(targetCalleeName.includes(calleeName)){const{line,column}=path.node.loc.start;路径。node.arguments.unshift(types.stringLiteral(`${options.file.filename}:(${line},${column})`))}}}}}module.exports=parametersInsertPlugin;然后使用babelcore的api执行代码编写,并调用插件:const{transformFileSync}=require('@babel/core');constinsertParametersPlugin=require('./plugin/parameters-insert-plugin');constpath=require('path');constinputFilePath=path.join(__dirname,'./sourceCode.js');const{code}=transformFileSync(inputFilePath,{plugins:[insertParametersPlugin],parserOpts:{sourceType:'unambiguous',plugins:['jsx']}});console.log(code);当源码为下面的代码时:console.log(1);functionfunc(){console.info(2);}exportdefaultclassClazz{say(){console.debug(3);}render(){返回<div>{console.error(4)}

}}目标代码为:可以看到在console.xx的api调用处插入了文件名和行列号的参数这是一个用于代码转换示例的babel插件。由此,我们可以总结出babel插件的特点:插件的形式是一个函数返回一个对象,对象的visitor属性声明了对什么节点做什么。访问者函数可以通过路径API对ast进行增删改查。修改后的ast会打印为目标代码eslint插件eslint插件也会解析代码,找到要检查的AST,然后检查并报错,但不一定修复代码。只有指定了fix才会修复。我们编写了一个检查对象格式的eslint插件。需要时,检查并修复以下代码格式:constobj={a:1,b:2,c:3}成这样:constobj={a:1,b:2,c:3}eslint是可以找到的AST关联的token,也就是我们可以得到对象的开始和结束token以及每个属性的行列号。我们需要验证前一个属性末尾的token的行号是否等于下一个属性开始的token的行号。所以这样写:指定检查ObjectExpression的每个属性的开始和结束标记的行号,即{}表达式,如果下一个属性不是上一个属性的+1行,则报错会被举报。此外,您还可以指定如何修复它。我们这里修复错误的方式是将两个token之间的部分替换为换行符(os.EOL)+tab。constos=require('os');module.exports={meta:{fixable:true},create(context){constsourceCode=context.getSourceCode();return{ObjectExpression(node){for(leti=1;i