uniapp的 App.vue 可以定义小程序生命周期方法,globalData全局数据对象 , 以及一些自定义方法,核心代码实现如下:
<script>export default {globalData: {text: 'text'}onLaunch: function() {console.log('App Launch,app启动')},onShow: function() {console.log('App Show,app展现在前台')},onHide: function() {console.log('App Hide,app不再展现在前台')},methods: {// .....}}<script>5.2.2 核心转换设计
文章插图
如图,核心转换设计流程:
- 对 app.py 进行 parse,拆分出script和style部分,对script部分使用babel进行parse生成AST 。
- 通过对 AST 分析出,小程序的生命周期方法,globalData全局数据,自定义方法等 。
- 对于AST进行uniapp转换,生命周期方法和全局数据转成对象的方法和属性,对自定义方法转换到method内 。
- 其中对 globalData 的访问,要进行替换通过 getApp()进行访问 。
- 抽取 ast 中的 config 字段,输出到 app.json 配置文件 。
- 抽取 wepy.config.js 中的 config 字段 , 传入 wepy 的 app 实例 。
let APP_EVENT = ['onLaunch', 'onShow', 'onHide', 'onError', 'onPageNotFound']//....// 实现wepy app到uniapp App.vue的转换t.program([...body.filter((node: t.Node) => !t.isExportDeclaration(node)),// 插入appClass...appClass,...body.filter((node: t.Node) => t.isExportDeclaration(node)).map((node: object) => {// 对导出的app进行处理if (t.isExportDeclaration(node)) {// 提前config属性const { appEvents, methods, props } = this.clzProperty// 重新导出vue style的对象return t.exportDefaultDeclaration(t.objectExpression([// mixins...mixins,// props...Object.keys(props).filter((elem) => elem !== 'config').map((elem) =>this.transformClassPropertyToObjectProperty(props[elem])),// app events...appEvents.map((elem) =>this.transformClassMethodToObjectMethod(elem)),// methodst.objectProperty(t.identifier('methods'),t.objectExpression([...methods.map((elem) =>this.transformClassMethodToObjectMethod(elem)),])),]))}return node}), ])// ..... 5.2.3 痛点难点在运行期,app.wpy 会继承 wepy.App 类 , 这样就会在运行期和 wepy.App 产生依赖关系,怎么最小化弱化这种关系 。抽取wepy的最小化以来的polyfill,随着业务中代码剔除对wepy的api调用,最终去除对polyfill的依赖 。
5.3 wepy component 转换对于wepy component 的转换主要可以细化到对 component 中 template、script、style 三部分代码块的转换 。
其中,style 部分由于已经兼容 Vue 的规范 , 所以我们无需做额外处理 。而 template 模块主要是需要对 wepy template 中特殊的标签、属性、事件等内容进行处理 , 转化为适配 uni的template,上文做了详细的说明 。
我们只需要专注于处理 script 模块的代码转换即可 。从架构设计的思路来看,component script 的转换主要是是做以下两件事:
- 编译期可确定代码块的转换 。
- 运行期动态注入代码的兼容 。
5.3.1 差异性梳理首先先解释一下什么是“编译期可确定代码块”,我们来看一个 wepy 和 Vue 语法对比示例:
文章插图
从直观上来说,这个 script 的模板的语法大致和 Vue 语法类似,这意味着我们解析出来的 AST 结构和 Vue 文件对应的 AST 结构上类似 , 基于这一点来看编译转换的工作量大致有底了 。
从细节来看,wpy 文件script 模块中的 API 语法和 Vue 中有声明及使用上的不同,其中包含:
- wepy 自身的包依赖注入及运行时依赖
- props/data/methods 声明方式不同
- 生命周期钩子不同
- 事件发布/订阅的注册和监听机制不同 。
- ....等等
5.3.2 核心转换设计我们简单梳理一下 wepy-component-transform 这个模块的结构,可以分为以下三个部分:
- 预处理 wepy component script 代码 AST 节点部分
- 构建 Vue AST
- 通过 generate 吐出代码
基于前文转换设计这一节我们知道, wepy 变色龙的转换器中对代码的 AST 解析主要依赖 babel AST 三板斧(traverse、types、generate)来实现 , 通过分析各个差异点代码语句转换后的 AST 节点,就可以通过 traverse 中的钩子来进行节点的前置处理,这里安利一下 https://astexplorer.net/,我们可以通过它快速分析代码块 AST 节点、模拟场景及验证转换逻辑:
推荐阅读
- 之六 2流高手速成记:从SpringBoot到SpringCloudAlibaba
- Windows下自动云备份思源笔记到Gitee
- 原神和兰那库拉一起找到枝任务怎么完成
- DNF浓缩的纯洁之骸到底怎么获得(dnf浓缩的纯洁之骸在哪搬砖)
- 浓缩的异界精髓,浓缩的纯洁之骸在哪里可以得到
- dnf浓缩的纯洁之骸有什么用怎么得到(dnf怎么获得纯洁之骸)
- 地下城与勇士浓缩的纯洁之骸怎么可以弄到(地下城与勇士怎么获得极品装备)
- DNF浓缩的纯洁之骸要怎么才能得到(dnf浓缩的纯洁之骸在哪搬砖)
- 嘉峪关到张掖-嘉峪关到张掖多少公里
- DNF传说勋章怎样获得,哪里获得勋章(dnf如何快速得到勋章)