作为一名程序员,当然总是期望自己的代码能够“一次编写,到处运行”,但真正的体验往往是“修改一次,到处跑”。到处填坑”,依赖落后好几个版本想升级,老代码已经看着很不爽想重构,需要下定决心,毕竟任何疏漏或失误都可能酿成大祸,我们平时是怎么做的呢?如果放弃不做,痛苦立马就减轻了。。。但是如果你坚持做,请往下看!局部方法的真实性和局限性对于一些简单的需求,比如最近在掘金上看到的一个例子,去掉项目中的console.log(xxx)代码,相信大家遇到这种需求的第一个想法就是直接选择编辑器将批处理文本替换为anemptystring:使用正则表达式,我们还是可以处理很多需求的,但这真的能覆盖所有情况吗?有的同事很喜欢回车console.log('aaa')复制代码这样的话,如果我们面对更多复杂的需求或者严苛的场景,我们要么需要写更复杂的正则表达式,要么就要进行硬AST操作。AST有点复杂。在网上搜索了一下,找到了一个使用jscodeshift操作AST并去掉console.log的例子:exportdefault(fileInfo,api)=>{constj=api.jscodeshift;constroot=j(fileInfo.source)constcallExpressions=root.find(j.CallExpression,{callee:{type:'MemberExpression',object:{type:'Identifier',name:'console'},},})复制代码;调用表达式。消除();返回根。toSource();};复制代码需要大家熟悉AST结构。写的时候需要面对解析出来的节点结构慢慢写出来。过段时间再看,不会比回绕复杂更容易理解AST的规律——大家平时接触AST太少了。尝试结合它。有一次,我正在为一个项目的API大重构发愁,快要爆肝时,旁边的小姐姐看不下去了——她的项目重构比我早。不仅没爆,还做了个工具GoGoCode。这个工具借鉴了jQuery的两大思想:选择器和链式调用。使用这个工具去掉console.log(xxx),其实就是一句话的东西:const$=require('gogocode')/**故意乱码**/constinput=`console.log(`a,b,c`);`//关键代码constoutput=$(input).replace('console.log()','').generate()console.log(output)copycode它的创新在于解析console.log()你输入的是一个AST节点,和源码中创建的节点树相匹配,所以代码格式自然没有问题。你输入的代码相当于jQuery中的选择器,只不过这次选择的是代码节点。更多例子清理console.log这个操作还是太简单了,再举个例子吧!我们经常使用这样的枚举列表:constlist=[{text:"Astrategy",value:1,tips:"Atip",},{text:"Bstrategy",value:2,tips:"Btip",},{text:"Cstrategy",value:3,tips:"Ctip",},];复制代码突然有一天,为了统一代码中的各种枚举,我们需要将text属性重命名为name,将value属性重命名为id,很难用正则表达式准确匹配,容易误伤。操作AST树还是有点麻烦。你只需要用GoGoCode替换它:const$=require('gogocode')constinput=`constlist=[{text:"StrategyA",value:1,tips:"Atip",},{text:"StrategyB",value:2,tips:"Btip",},{text:"StrategyC",value:3,tips:"Ctip",},];//ts类型标记,这种正则替换会被错误替换,在gogocode中不会有consttext:string=''//这一段因为没有value不会被选择器匹配,也不会被错误替换constcfg={text:''}`constoutput=$(input2).replace('{text:$_$1,value:$_$2,$$$}','{name:$_$1,id:$_$2,$$$}')。产生();复制代码其中$_$1和$_$2相当于正则表达式中的通配符,但是这里只会匹配代码中有效的AST节点,$$$可以匹配剩下的节点,有点像es6中的...,这个code匹配text和value,对应的value填入name和id,其余原封不动放回去。后半部分,我特意加了一些“干扰码”。以前我都是用字符串替换text:为name:的本地方法,会误伤,而GoGoCode不会。让我们看一下上一段中社区中的一个例子。巧合的是,在上一段看到了掘金的一篇文章。像jQuery一样玩AST,里面介绍了一个使用jscodeshift进行Reactjsx代码转换的例子:我打算修改这样一段代码:将import从@alifd/next改成antdbeforetranslation,改成aftertranslation。Button中类型参数转换:normal->default,medium->middleButtonwithtextparameterchangedtotype="link"Buttoninwarningparameterchangedtodangerimport*asReactfrom'react';importstylesfrom'./index.module.scss';import{Button}from"@alifd/next";constBtn=()=>{return(
