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

相关推荐
豐儀麟阁贵7 分钟前
8.5在方法中抛出异常
java·开发语言·前端·算法
zengyuhan50337 分钟前
Windows BLE 开发指南(Rust windows-rs)
前端·rust
醉方休40 分钟前
Webpack loader 的执行机制
前端·webpack·rust
前端老宋Running1 小时前
一次从“卡顿地狱”到“丝般顺滑”的 React 搜索优化实战
前端·react.js·掘金日报
隔壁的大叔1 小时前
如何自己构建一个Markdown增量渲染器
前端·javascript
用户4445543654261 小时前
Android的自定义View
前端
WILLF1 小时前
HTML iframe 标签
前端·javascript
枫,为落叶1 小时前
Axios使用教程(一)
前端
小章鱼学前端1 小时前
2025 年最新 Fabric.js 实战:一个完整可上线的图片选区标注组件(含全部源码).
前端·vue.js
ohyeah1 小时前
JavaScript 词法作用域、作用域链与闭包:从代码看机制
前端·javascript