首先,本人是《babel 插件通关秘籍》掘金小册子的作者,对Babel有源码级的掌握,才有资格讨论这个话题。我想讨论以下话题:babel如何转换代码jscodeshiftbabel如何转换代码babel和jscodeshift的区别为什么gogocode不推荐AST,babelparser(babylon)支持esnext语法,可以支持typescript,jsx,flow和othersyntaxthroughpluginsTransform:转换AST,通过visitor处理不同的ASTrequire('@babel/helper-plugin-utils');constnoFuncAssignLint=declare((api,options,dirname)=>{api.assertVersion(7);返回{pre(file){file.set('errors',[]);},visitor:{AssignmentExpression(path,state){consterrors=state.file.get('errors');constassignTarget=path.get('left').toString()constbinding=path.scope.getBinding(assignTarget);if(binding){if(binding.path.isFunctionDeclaration()||binding.path.isFunctionExpression()){consttmp=Error.stackTraceLimit;Error.stackTraceLimit=0;errors.push(path.buildCodeFrameError('cannotreassigntofunction',Error));Error.stackTraceLimit=tmp;}}}},发布(文件e){console.log(file.get('errors'));}}});module.exports=noFuncAssignLint;声明访问者函数,在遍历过程中会调用该函数,在这里可以获取路径和状态api:路径是节点之间的关系。每条路径都与父节点和当前节点相关联。路径对象形成从当前节点到根节点的路径。状态是遍历过程中共享数据的机制。通过路径的ASTAPI的一系列增删改查,完成转换。例如,以下API:(replacement)remove)jscodeshift如何转换代码?jscodeshift也是一个代码转换的工具,只是api风格不同。它主动搜索AST,然后修改成新的AST,最后生成代码形式为:module.exports=function(fileInfo,api){returnapi.jscodeshift(fileInfo.source).findVariableDeclarators('foo').renameTo('bar').toSource();}jscodeshift的好处是更简洁。但是jscodeshift能不能代替babel呢?可以看看大牛给出的答案:babel和jscodeshift的区别。jscodeshift/issues/168使用recast进行解析,然后基于babel解析器进行转换。下面有个精彩的回复,把babel和jscodeshift的区别说清楚了:整理一下:babel的transformapi是visitor风格的,也就是声明了用什么ast做什么,然后在调用的时候调用遍历过程。这种写法加上具体的遍历方式就是设计模式(访问者模式),即使是复杂的场景也能处理。只是处理简单的场景会稍微啰嗦一点。jscodeshift是一种集合风格,类似于jquery,主动搜索AST,放入集合中进行操作。适合处理简单的场景。您需要知道如何找到每个AST,然后进行转换。你必须处理很多很多情况。万一搜索路径错误,那可能漏掉了一些情况。相比babel,复杂场景下很难没有bug。就像jquery和mvvm的区别一样,mvvm的方式(babel)对于复杂的场景还是靠谱的,一些dom也不会遗漏。(只是打个比方)所以,简单场景可以用jscodeshift,所有场景都可以用babel。babel的visitor的优势在于设计模式中visitor模式的优势。不与具体的遍历方式耦合,易于复用。为什么不推荐gogocodegogocode是阿里妈妈这两天开发的ast修改工具。在babel的基础上做了一层封装,据说可以简化ast操作。api类似于:$(code).find('vara=1').attr('declarations.0.id.name','c').root().generate();是的,基于babel的visitorstyleAPI封装了jscodeshift的collectionstyleAPI。本来babel的visitor虽然写起来有点麻烦,但是所有路径都可以搞定。改成收藏风格后,一旦某个路径掉线,就会出现bug。它处理的情况很多,不适合复杂的场景。Babel独创的访问者模式是一个优势,因此在上层封装了集合API。.如果要这样封装,为什么不直接基于jscodeshift。..不懂这个操作我不看好这个巴别套娃。我不相信在复杂的场景下所有的路径都可以处理而不会丢失情况。复杂场景我选择直接使用babel的api。总结一下,babel就是访问者设计模式的实现,将遍历方法和对AST的操作分离,使得操作可以复用。jscodeshift是一种集合风格,类似于jquery,复杂场景下容易掉例。gogocode基于babel实现collection样式,不容乐观,容易陷入case。一句话总结:简单场景可以用jscodeshift,所有场景都可以用babel,gogocode不推荐。
