最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    正文概述 掘金(阿里妈妈前端快爆)   2021-04-08   635

    本文来自 GoGoCode 用户抱雪投稿

    1 为什么要迁移 Vue3.x

    说点什么呢? 总之。。。 这不是我的错!

    首先先要写个案例,找到一个可执行方案。

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    2 方案选择

    参考Vue2转3官方文档

    v3.cn.vuejs.org/guide/migra…

    面对自己项目百八十个文件,人工爆肝肯定是不可能的,想都不能想! 唯一的方案是基于AST(抽象语法树)解构代码,根据Vue官网给出升级文档的修改建议,批量修改输出文件的方案。 只是。。。AST操作有点复杂。

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    调研了几个工具,GitHub上找到了几个去掉代码文件里 console.log 的示例学习学习:(这两处代码引用作对比方案,可以跳过) 一. 利用 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();
    };
    

    二. 利用 babel 操作 AST去掉console.log 的示例: (基于篇幅省略了部分代码,有兴趣的同学请访问github.com/mattphillip…)

    export default function({
      types,
    }: typeof BabelCore): PluginObj<ConsoleTransformState> {
      return {
        name: 'console-transform',
        visitor: {
          CallExpression(path, { opts, file }) {
            validateSchema(schema, opts);
            const { env, removeMethods, additionalStyleMethods } = opts;
            const callee = path.get('callee');       
            /*
            基于篇幅限制
            此处省略40+行代码
            */        
          },
        },
      };
    }
    

    基于本人实力,这两个方案实在是劝退案例。

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    正在我为这个项目重构发愁,发量迅速减少,混迹于社区寻找解救方案的时候,忽然发现了GoGoCode这个工具。

    贴一段官方介绍:

    GoGoCode的官方文档 gogocode.io/zh/docs/spe…

    这不正是我想要的么,遇到你就是古话说的,瞌睡来了有人递枕头! 而GoGoCode操作 AST 去掉 代码中console.log,仅仅只需要一行代码!!

    $(`要转换的代码段`).find(`console.log($_$)`).remove()
    

    熟悉的 $ 符号,熟悉的find、remove等API,扣一下题,说零成本操作AST不算标题党吧 爆赞!!!方案选定!!!

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    3 开工

    举个栗子:按键修饰符的迁移方案

    Vue2转3官方文档 - 按键修饰符的迁移 v3.cn.vuejs.org/guide/migra…

    按照文档写一个待转化的Demo

    <template>
     <div>
       <h1>迁移:按键修饰符</h1>
       <p>迁移策略:
             1.Vue3不再支持使用数字 (即键码) 作为 v-on 修饰符 
             2.不再支持 config.keyCodes</p>
       <div class="mt20 text-left">
         <div>space:<input type="text" @keyup.space="keys('space')" /></div>
         <div>space:<input type="text" @keyup.32="keys('keycode 32 space')" /> </div>
         <div>space:<input type="text" @keyup.customSpace="keys('keycode 32 space')" /> </div>
       </div>
     </div>
    </template>
    <script>
    import Vue from 'vue';
    Vue.config.keyCodes = {
        customSpace: 32,
        customDelete: 46
    };
    export default {
      name: '按键修饰符', 
      methods: {
        keys(key) {
          alert('您按下的是' + key);
        },
      },
    };
    </script>
    

    任务确定

    根据astexplorer.net分析下要转换的内容

    安利一下astexplorer.net这个工具,我们可以利用它很方便的查看某段代码的AST语法树结构

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    这里要做的有三件事:

    1)提取代码里自定义的keyCodes(上图蓝框Vue.config.keyCodes的内容部分),与系统keyCodes合并为一个map,后续要在template替换时使用;

    2)移除Vue.config.keyCodes 代码(Vue3不再支持);

    3)遍历所有标签以及它的属性,使用合并后的keyCodes替换标签(上图红框 xx.32与xx.customSpace部分)。

    转换逻辑编写

    1. 项目里运行安装GoGoCode
    npm install gogocode
    
    1. 初始化script的AST对象
    const $ = require('gogocode');
    //script代码,用$转为AST节点
    let scriptAst = $(`
    import Vue from 'vue';
    Vue.config.keyCodes = {
        customSpace: 32,
        customDelete: 46
    };
    export default {
      name: '按键修饰符',  
      methods: {
        keys(key) {
          alert('您按下的是' + key);
        },
      },
    };`)
    
    1. 我们要寻找script里自定义的keyCodes(Vue.config.keyCodes的内容部分)

    使用GoGoCode的find API,加上匹配通配符_,拿到所有的自定义keyCode数组

    // 匹配取出自定义的keyCode,结果:Node数组
    const customKeyCodeList = scriptAst.find(`Vue.config.keyCodes = {$_$}`).match[0]
    

    控制台打出customKeyCodeList,是一个Node数组

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    1. customKeyCodeList加上系统的keyCode,构造全量的keyCodeMap
    // 全量的keyCode对照表,基于篇幅这里只列出3个
    // https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/keyCode
    let keyCodeMap = {46: 'delete',32: 'space',112: 'f1'}
    //加上自定义keyCode构造汇总所有的keyCodeMap,待会替换template内容的时候需要使用
    //结果:{46: 'delete',32: 'space',112: 'f1', customSpace: 'space', customDelete: 'delete'}
    for(let i = 0;i< customKeyCodeList.length; i=i+2){
        Object.assign(keyCodeMap, {
            [customKeyCodeList[i].value] : keyCodeMap[customKeyCodeList[i+1].value]
        })
    }
    

    控制台打出keyCodeMap构造结果

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    1. Vue3要求: Vue.config.keyCodes不再支持,需要移除。find到这个节点,使用remove API移除
    scriptAst.find(`Vue.config.keyCodes = $_$`).remove()
    
    1. 初始化template节点,html模板需要带{ parseOptions: { html: true } }参数
    let templateAst = $(`<template>
     <div>
       <p>迁移:按键修饰符</p>
       <p>迁移策略:
             1.Vue3不再支持使用数字 (即键码) 作为 v-on 修饰符 
             2.不再支持 config.keyCodes</p>
       <div class="mt20 text-left">
         <div>space:<input type="text" @keyup.space="keys('space')" /></div>
         <div>space:<input type="text" @keyup.32="keys('keycode 32 space')" /> </div>
         <div>space:<input type="text" @keyup.customSpace="keys('keycode 32 space')" /> </div>
       </div>
     </div>
    </template>`, { parseOptions: { html: true } })
    
    1. 使用find、each、attr API遍历所有的标签以及它的属性,使用keyCodeMap,替换属性名称
    //find+each遍历所有的标签项
    templateAst.find(['<$_$></$_$>', '<$_$ />']).each((node) => {
        //如果节点含有属性,则遍历它的属性
        if (Array.isArray(node.attr('content.attributes'))) {
            node.attr('content.attributes').forEach((attr) => {
                //使用上文构造出来的汇总keyCodeMap,替换匹配到的属性名 如@keyup.32 -> @keyup.space
                for (let keyItem in keyCodeMap) {
                    if (attr.key.content.endsWith(`.${keyItem}`)) {
                        attr.key.content = attr.key.content.replace(`.${keyItem}`,`.${keyCodeMap[keyItem]}`)
                    }
                }
            })
        }
    })
    

    这里用到的node.attr('content.attributes'),就是刚才从astexplorer.net工具查到的

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    1. 最后输出,大功告成,对比一下转换的结果

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    4 总结

    这段代码里的AST相关操作只有10行左右,其余都是核心转换逻辑。GoGoCode可以像使用Jquery操作DOM的一样的体验来操作AST,入门简单使用也方便

    starter里还有批量处理文件的demo github.com/thx/gogocod…

    Github上提issues也很快就有回应! github.com/thx/gogocod…

    实在是代码转换利器

    如果文中有任何问题,欢迎您的反馈。

    谢谢,祝你有美好的一天!

    GoGoCode 相关链接

    GoGoCode的Github仓库(新项目求star ^_^) github.com/thx/gogocod…

    GoGoCode的官网 gogocode.io/

    可以来 playground 快速体验一下 play.gogocode.io/


    起源地下载网 » 0成本上手AST,用GoGoCode解决Vue2迁移Vue3难题

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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