如何将vue2代码一键升级到vue3(下)

书接上文(如何将vue2源码一键升级到vue3(上)),我们知道了如何通过ast去改造源码,本篇文章将介绍如何通过vue自定义loader的方式实现vue2的代码运行在基于vue3的项目当中。源码地址 vue2-to-vue3

关于loader

可以将其理解为在文件打包构建完成之前,对文件进行预处理,譬如我们熟知less-loader、sass-loader的作用就是将其转换为css输出,编写自定义loader的目的也是将文件按照我们的预期输出,更多关于loader的内容大家可以在Loaders上查阅。

目标

  1. 入口文件main.js改造
  2. vue文件改造
  3. 项目vue版本升级为3.x 以及相关依赖版本替换
  4. 跑起来

准备工作

新建一个vue2项目,在src目录下新建loader文件夹,其中包含index.js入口文件以及custom-loader文件,项目结构如下:

image.png

在vue.config.js对我们的自定义loader进行配置

// vue.config.js
const {
    defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
   
  chainWebpack: config => {
   
    // 配置自定义loader
    config.module
      .rule('custom-loader')
       // 匹配.vue和js文件
      .test(/\.(vue|js)$/)
      .include.add(/src/) // 只转化src目录下的js
      .end()
      .use('custom-loader')
      .loader(require.resolve('./src/loader'))
      .end()
  }
})

编写loader/index.js文件,source为源文件内容,在loader导出的函数中, this 作为上下文会被 webpack 填充,所以此处不能使用箭头函数,最后函数通过webpack注入到this上的callback()返回最终结果。

// src/loader/index.js
const loader = require('./custom-loader');
const compiler = function(source) {
   
    // 实例化loader,传入源代码,调用transform方法获取转换后的代码
    let result = new loader(source).transform();
    // console.log('result :>> ', result);
    return result;
};
module.exports = function (source) {
   
    this.callback(null,compiler(source),null);
};

编写loader/custom-loader.js,改造相关的逻辑都会在该文件下进行。

// src/loader/custom-loader.js
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const t = require("@babel/types");
const generator = require("@babel/generator").default;

/**
 * 转换类 
 * @param {string} source 源代码
 * @returns {string} 转换后的代码
 */
class Transformer {
   
    constructor(source) {
   
        this.source = source;
    }
    // 转换
    transform() {
   
        return compileCode(this.source);
    }
}
module.exports = Transformer;

function compileCode(source) {
   
    // 1. 生成AST
    const ast = parser.parse(source, {
   
        sourceType: 'module'
    });
    // 2. 遍历AST,找到对应的节点
    traverse(ast, {
   
        // 遍历 函数调用表达式 类型的节点
        CallExpression(path) {
   
            // 判断是否是console.log节点
            if (t.isMemberExpression
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值