【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/

相关推荐
大家的林语冰15 分钟前
CSS 已死?DOM 性能黑洞!Pretext 排版革命让你在文本间跳舞,没有 DOM 也能纵享丝滑~
前端·javascript·css
vipbic25 分钟前
我也该升级了,陪伴了我7年的博客
前端
Lee川44 分钟前
RAG 实战:从一篇掘金文章出发,拆解检索增强生成的全链路
前端·人工智能·后端
Lee川1 小时前
MCP 高德地图实战:当 AI 学会使用工具,一个协议如何重塑大模型的行动边界
前端·人工智能·后端
ZC跨境爬虫1 小时前
跟着 MDN 学CSS day_14:(尺寸调整技能测试与实战解析)
前端·css·ui·html·tensorflow
kyriewen1 小时前
用魔法打败魔法:我让AI替我去面试前端岗,AI面试官给我打了92分,还发了offer
前端·javascript·面试
IT_陈寒1 小时前
Redis批量删除踩了坑,原来DEL命令不是万能的
前端·人工智能·后端
lichenyang4532 小时前
鸿蒙聊天 Demo 练习 06:AI 思考气泡与 MVVM + Controller 结构重构
前端
Lkstar2 小时前
Vue keep-alive 原理全解:LRU 缓存策略、源码级理解
前端·vue.js·面试
会联营的陆逊2 小时前
html2canvas 1.4.1 在 iOS Safari 中生成图片卡住的问题排查与修复
前端