【openInula茶话会】第三期:Vue转换到openInula技术揭秘

本期作者:陈圆 openInula社区架构SIG成员

《openInula茶话会》专栏每周不定期分享业务知识、实战经验与开发技巧,帮助社区成员快速提升技能,开启技术探索之旅! 本期介绍《Vue转换到openInula技术揭秘》,欢迎查阅。

项目背景

openInula问世以来吸引众多产品从React框架平滑切换到openInula框架,截止目前openInula已经支撑千万级代码规模商用。同时,不少产品提出帮助产品从Vue框架切换到openInula框架的诉求。因此openInula社区提供了一个转换工具,帮助产品从Vue框架切换到openInula框架。

整体方案设计

整体方案分3个部分:

  • Vue代码转换工具:转换工具负责将Vue文件转换成jsx文件,涉及到模版转换、JS转换和css转换。
  • Vue API适配层:适配层提供Vue API到openInula及生态的API 适配层,以便转换工具进行API转换。
  • UI组件库:提供组件库适配层,将Vue框架的ElementUI组件库转换到openInula框架组件库。

Vue To openInula转换工具

转换工具主要分成3部分: 模版转换、JS转换和CSS转换。下面分别介绍这3部分转换原理。

模版转换

  1. 读取Vue文件,利用@vue/compiler-sfc提供的parse对模版进行解析,解析后的数据通过自定义lintTemplate进行简单格式预处理
javascript 复制代码
  const sourceStr = fs.readFileSync(srcPath, 'utf8');

  // 解析 .vue 文件,获取解析结果
  const parsed = parse(sourceStr);
  const template = await lintTemplate(parsed.descriptor.template?.content);
  1. 使用@babel/parser将模版文件字符串编译成ast语法树
javascript 复制代码
import parser from '@babel/parser';
const templateAst = parser.parse(targetTemplate, {
      sourceType: 'module',
      allowTemplateLiterals: true,
      plugins: ['jsx'],
});
  1. 遍历ast语法树,根据需要处理每一个节点元素、属性绑定、事件等,这里就可以将v-if、v-for、v-show、v-modal等Vue模版语法转换成openInula的jsx语法。
javascript 复制代码
traverse(templateAst, {
      JSXElement(path) {
          // 处理元素节点
      },
      JSXAttribute(path) {
          // 处理属性
      }
      JSXExpressionContainer(path) {
          // 表达式处理
      }
      // 其他
    });
    

JS转换

  1. 读取Vue文件,将TS语法编译成js语法
  2. 和模版转换类似,利用@bable/parser将js文件的字符串转成ast语法树
  3. 区分vue options api和composition api分别进行语法树解析转换,主要完成以下工作
    • 处理import,将原本import vue生态组件转成openInula生态组件
    • 将Vue生命周期方法转入到openInula生命周期执行
    • 将底层变量用useMemo包裹,放在openInula组件中
  4. 处理国际化等生态组件
  5. 将Vue中变量赋值进行转换,以适配openInula语法
  6. 处理Vue中this指针问题下

CSS转换

Vue中存在局部CSS作用域的scoped语法,但是openInula中没有改功能。因此,引入scoped-css-loader在Webpack编译期完成局部CSS的编译。 Vue中的CSS只需转成对应的CSS文件,并将文件名以scoped.css结尾即可完成局部CSS功能。Webpack配置如下

javascript 复制代码
{
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: ['postcss-import', 'postcss-nested'],
              },
            },
          },
          {
            loader: 'less-loader',
          },
          {
            loader: 'scoped-css-loader',
          },
        ],
      },
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: ['postcss-import', 'postcss-nested'],
              },
            },
          },
          {
            loader: 'sass-loader',
            options: {
              // 每个项目地址不同
              additionalData: '@import "/convert/assets/common/style/common/varible.scss";'
            }
          },
          {
            loader: 'scoped-css-loader',
          }
        ],
      },

总结

Vue语法灵活性较高,将Vue文件转成openInula涉及细节众多,这里没有详细展开描述,仅介绍了转换流程关键动作。。如果各位开发者感兴趣,欢迎评论或留言,后续文章将展开描述更多细节。

🌈代码仓地址:gitee.com/openinula/i... 💻官网:www.openinula.net/

相关推荐
孟健2 分钟前
用 WorkBuddy 做个人名片网页,挂上开源设计技能后效果完全不同了
前端·人工智能·ai编程
IT_陈寒6 分钟前
SpringBoot自动配置的坑,这次终于爬出来了
前端·人工智能·后端
OpsEye38 分钟前
企业大模型压测,需要重点关注哪些指标?
javascript·ai编程
LuHang1 小时前
从天地图切换到高德地图:一次真实的底图迁移实战
前端·vue.js·cesium
用户360055579001 小时前
Kestrel_VLLM - 27 · 寄存器常驻与融合发射:两次「少发一次」
前端
前端小万1 小时前
用"道法术器"重构你和 AI 的协作方式
前端·人工智能·程序员
鶴哥只手遮天1 小时前
Angular 22 源码级深度解析-第 06 章 模板指令全解:`ɵɵelementStart`、`ɵɵproperty`、`ɵɵadvance` 与绑定指令
前端·开源·angular.js
像我这样帅的人丶你还2 小时前
我html生成的doc文档为何在手机文档显示不了图片?
前端·javascript
前端双越老师3 小时前
程序员 1v1 访谈系列第十期:纯前端坚持不了多久了
前端·ai编程·全栈
门思科技5 小时前
LoRaWAN 网络排障的五层漏斗:从"上不到云"到"数值不对",每一层该用什么工具证明
前端