最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 阿里妈妈出的新工具,给批量修改项目代码减轻了痛苦

    正文概述 掘金(阿里妈妈前端快爆)   2021-03-12   441

    作为一个程序员,当然总是期望自己的代码能「一次编写,四处运行」,但真实经验往往是「一处修改,百处填坑」,依赖落后了好几个版本了想要升级、老代码已经看着很不爽了打算重构,都需要下坚决的决心,毕竟哪里漏掉了或者改错了都可能酿成大祸,我们一般都怎么搞呢?

    放弃不搞


    顿时就减轻了痛苦有木有…但如果你坚持要搞,请往下看!

    土办法的真香和局限


    对于一些简单的需求,比如最近在掘金上看到了一个例子,去掉项目中 console.log(xxx) 代码,我相信大家平时遇到这种需求第一个想法都是直接选择编辑器批量文本替换成空字符串:

    阿里妈妈出的新工具,给批量修改项目代码减轻了痛苦
    利用正则表达式,我们还是可以搞定很多需求的,但这样真的能包含所有情况么?有的同事是真的喜欢回车。

    console
    	.log('aaa')
    

    这种情况下,如果面对更复杂的需求或者严谨的场景,要么我们编写更复杂的正则表达式,要么我们就不得不去硬肝 AST 操作了。

    AST有点复杂


    上网搜索了一下,还真找到了利用 jscodeshift 操作 AST 去掉 console.log 的示例:

    export default (fileInfo, api) => {
      const j = api.jscodeshift;
    
      const root = j(fileInfo.source)
    
      const callExpressions = root.find(j.CallExpression, {
          callee: {
            type: 'MemberExpression',
            object: { type: 'Identifier', name: 'console' },
          },
        }
      );
    
      callExpressions.remove();
    
      return root.toSource();
    };
    

    这需要大家对 AST 结构比较熟悉,在编写的时候需要对着解析好的节点结构才能缓缓写出,过一段时间再一看,也不会比弯弯绕绕的正则更好理解——大家平时太少接触 AST 了。

    试着结合一下


    有一次正当我为一个项目 API 大重构发愁,准备人肉爆肝的时候,我旁边的小姐姐实在看不下去了——她的项目比我更早地做了重构,人家不仅没爆肝,还顺手做了个工具 GoGoCode,这个工具借鉴了 jQuery 的两大思想:

    选择器链式调用

    用这工具去掉 console.log(xxx) ,其实就是一句话的事:

    const $ = require('gogocode')
    
    /** 刻意凌乱的代码 **/
    const input = `
    	console
    .log(`a, b,c`);
    `
    
    // 关键代码
    const output = $(input).replace('console.log()', '').generate()
    
    console.log(output)
    

    它的创新之处就在于,把你输入的 console.log() 解析成一段 AST 节点去源代码里做节点树的匹配,这样自然就没有代码格式的问题了。你输入的代码就相当于 jQuery 里面的选择器,只不过这一次选择的是代码节点。

    更多例子


    清理 console.log 这个操作还是太简单了,我再举一个栗子!

    我们经常使用这样的枚举列表:

    const list = [
      {
        text: "A策略",
        value: 1,
        tips: "Atip",
      },
      {
        text: "B策略",
        value: 2,
        tips: "Btip",
      },
      {
        text: "C策略",
        value: 3,
        tips: "Ctip",
      },
    ];
    

    突然有一天,为了统一代码里的各种枚举,我们需要把 text 属性更名为 name,把 value 属性更名为 id,这个用正则很难精确匹配容易误伤,操作AST树还有些麻烦,用 GoGoCode 只需要这么替换一下就行了:

    const $ = require('gogocode')
    
    const input = `
    
    const list = [
      {
        text: "A策略",
        value: 1,
        tips: "Atip",
      },
      {
        text: "B策略",
        value: 2,
        tips: "Btip",
      },
      {
        text: "C策略",
        value: 3,
        tips: "Ctip",
      },
    ];
    
    // ts的类型标记,这种正则替换会被错误替换的,在 gogocode 里就不会
    const text: string = ''
    // 这一段因为没有 value 就不会被选择器匹配到,也不会被错误替换
    const cfg = {
      text: ''
    }
    
    `
      
    const output = $(input2).replace(
      '{ text: $_$1, value: $_$2, $$$ }',
      '{ name: $_$1, id: $_$2, $$$ }'
    ).generate();
    

    其中 $_$1$_$2 相当于正则中的通配符,但是在这里只会匹配代码里有效的 AST 节点,$$$ 则可以匹配剩下的节点,有点像 es6 里的 ... ,这段代码匹配出了 textvalue 这对应的值填给了 nameid,剩下的原封不动放回去。

    而下半部分我刻意加了一些「干扰代码」,以往我通过字符串替换 text:name:的土办法遇到这样的就会误伤了,但 GoGoCode 不会。

    再看前一段社区里的一个例子


    正巧,前一段我在掘金看到了文章 像玩 jQuery 一样玩 AST,里面介绍了一个用 jscodeshift 进行 React jsx 代码转换的例子:

    打算对这样一份代码做修改:

    • 从 @alifd/next 导入改成 antd
    • 转译前 改成 转译后
    • Button 中 type 参数转换:normal -> default,medium -> middle
    • Button 中有 text 参数的改成 type="link"
    • Button 中warning 参数的改成 danger
    import * as React from 'react';
    import styles from './index.module.scss';
    import { Button } from "@alifd/next";
    
    const Btn = () => {
      return (
        <div>
          <h2>转译前</h2>
          <div>
            <Button type="normal">Normal</Button>
            <Button type="primary">Prirmary</Button>
            <Button type="secondary">Secondary</Button>
            
            <Button type="normal" text>Normal</Button>
            <Button type="primary" text>Primary</Button>
            <Button type="secondary" text>Secondary</Button>
            
            <Button type="normal" warning>Normal</Button>
          </div>
        </div>
      );
    };
    
    export default Btn;
    

    大概是这样:

    阿里妈妈出的新工具,给批量修改项目代码减轻了痛苦
    这种需求其实挺常见的,原文提供了一个 基于 jscodeshift 的实现,深入到了 AST 进行操作,但如果用 GoGoCode 就会直观很多:

    // 省略依赖和 input
    const output = $(input)
      .replace(`import { $$$ } from "@alifd/next"`, `import { $$$ } from "antd"`)
      .replace(`<h2>转译前</h2>`, `<h2>转译后</h2>`)
      .replace(
        `<Button type="normal" $$$></Button>`,
        `<Button type="default" $$$></Button>`
      )
      .replace(
        `<Button size="medium" $$$></Button>`,
        `<Button size="middle" $$$></Button>`
      )
      .replace(`<Button text $$$></Button>`, `<Button type="link" $$$></Button>`)
      .replace(`<Button warning $$$></Button>`, `<Button danger $$$></Button>`)
      .generate();
    

    相信你不要讲解也能知道这段代码是要做什么了~

    开源了,希望能得到大家的反馈


    我觉得这个项目挺有趣的,可以说是专门给代码做了一个 replace 程序,小姐姐说我看到得太浅显,其实这个项目不仅仅是 replace 这一招,这个项目支撑了我们几个几万行前端工程的架构升级计划,就算需求更复杂也是有办法搞定的,大家可以关注我们的账号或专栏,后面作者会发表更专业全面的介绍文章。

    小姐姐是我们阿里妈妈 MUX 团队的叶兮,我们团队以前有过 iconfont、Rap、MockJS 这样受到社区欢迎的项目,这一次我们把 GoGoCode 也开源到 Github:github.com/thx/gogocod…,希望能对同样有大量代码修改需求的朋友有所帮助。

    我们很希望了解到大家会经常遇到怎样的转换难题,如果你用现在 GoGoCode 不方便解决或者出了错,希望你能提给我们(issue:github.com/thx/gogocod… QQ群:735216094)。

    最后:新项目求 star 支持!

    Github:github.com/thx/gogocod…
    官网:gogocode.io


    起源地下载网 » 阿里妈妈出的新工具,给批量修改项目代码减轻了痛苦

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元