前端创新实践 - 自研编译器助力小程序架构升级

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. 前端创新实践 自研编译器助力小程序架构升级 万安文 | vivo互联网用户运营前端专家
2. 目录 01 02 03 04 背景介绍 技术选型 实践与挑战 总结规划
3.
4. 现有 Wepy 小程序需要迁移到 UniApp 架构 尽量降低迁移的人工成本 01 架构迁移 02 迁移后的产出物能更好的复用 原 因 预期效果 Wepy 小程序 03 提升规模化迁移效率 1. 导购等小程序基于Wepy构建,epy进入维护阶段 2. 公司内的前端生态主要围绕 Vue 技术栈体系 04 统一技术栈,实现更好的跨端开发
5.
6. 从迁移周期、方案实现难易,心智成本等综合因素考虑迁移方案的技术选型 最终选择通过编译的方式实现架构升级 01 迁移周期 人工迁移 02 渐进式迁移 03 编译器迁移 很长(25人/天) 中(15人/天) 秒级迁移 方案差异 配置、工程化、API等等 wepy-loader 降低了工程化 差异问题实现成本较高 编译器抹平架构差异, 对团队较高。规模化优势 知识迁移成本 高 中 低 方案复杂度 低 中等偏高 高 (以中型项目为单位)
7.
8. 01 编译原理在前端的应用 02 单文件组件编译转换核心设计 03 实践 编译器思路和实现 整体编译系统流水线设计 04 Parser 解析器架构设计与实现 05 Transform 转换器架构设计与实现 1.Transform-template 模板转换器设计思路 2.Transform-template 模板转换器实现 3.Transfrom-component 组件转换器设计思路 4.Transfrom-component 组件转换器实现
9. 编译原理在前端的应用 现代前端领域在编译方面有大量应用 前端已经进入工程化编译时代: 应用范围广泛 应用框架: Vue、React、JSX 语言:ES6+,Typescript 代码格式化:prettier 代码静态检查:eslint 基础架构完善 大量成熟基础编译工具,Babel、Webpack、Vite 等 社区活跃,生态丰富 es-build、SWC 等工具的兴起
10. 单文件组件分析 wepy和 vue 单组件文件对比 Script模块 相同点 代码结构一致 script/template/style 三部分组成 不同点 API 差异 模板语法完全不同 依赖注入差异 Template模块 Style模块 Wepy 文件结构 Vue 文件结构
11. 单文件组件编译转换设计 通过静态编译/运行期注入将 wepy组件 转为 uniapp组件 Sryles Transform (Less/sass/scss) Sryles (Less/sass/scss) AST转换 01 静态编译实现编译期确定性的语法转换 Chameleon Transpiler 模板,wepy组件,page,app等 Parser Template 解析代码内容 (Pug/wxml) (expression) Transform Template AST转换 静态编译模块 Script 02 request / wepy async api 等 Script Wepy特有结构 wpy 运行期polyfill注入,解决项目中对 wepy 的API依赖解耦 Transform AST转换 原始wpy文件 Chameleon adaptor 运行期polyfill适配模块 Wepy独有Runtime逻辑的解耦和适配 vue
12. 整体编译系统流水线设计 通过编译流水线设计实现了全流程项目转换自动化 1. 组件通过 parser -> transform -> generate 三个核心步骤生成 UniApp 代码 2. 自动识别不同的项目资源进行不同的流水线转换 Parser解析器 Transform转换器 Generate代码生成器 Source -> Wepy AST Wepy AST -> UniApp AST UniApp AST -> UniApp Vue Project analyze 项目资源文件分析 Wepy 项目 UniApp 项目 静态资源文件转换器 Wepy-Code -> UniApp Code
13. Parser 解析器架构设计与实现 通过 Parser 解析器将源码转为 AST Wepy Code cheerio 01 02 针对script使用 babel-core 进行语法解析 针对wxml模版借助 cheerio 等工具 高效提取并最终转换为 AST parser-template Template Script cheerio babel/core Style Wepy AST
14. Transform 转换器架构设计 通过 Transform 转换器将 Wepy AST 转换为 UniApp AST Transfom 01 style 模块代码平移 transform-style 02 03 template 模块代码处理模板 语法差异、wxml 适配 script 模块代码处理 API 、 公共方法及依赖注入 Wepy AST transform- template transform- script wxml template app wxs page component UniApp AST
15. Transform -Template 模板转换器设计 基于 Wepy 和 Vue 模板语法对比来梳理设计思路: 通过文件比对、源码阅读来分析模板语法异同 Wepy 模板 模 板 差 异 Uni-app 模板 01 wepy 模板语法差异 - xml 命名空间定义指令 02 wxml 引用差异 - 特定的标签用来导入,如 <import />、<include /> 等 wxml vue wx:if v-if wx:elif v-else-if wx:else v-else wx:for v-for bindtap @tap 指令的对应转换关系示例
16. Transform -Template 模板转换器实现 模板转换流水线实现: 将传入的 Wepy 模板 AST 进行模板语法及WXML转换。最终生成 UniApp 模板 AST。 1.Wepy AST 2.Template 差异转换 3.WXML 适配 a.处理 wepy 的特殊引入 a.确定引入组件时的传参格式 b.指令、特殊标签等语法的转换 b.确定组件中传入对象的属性范围 c.收集引入的组件信息传递给下游 4. UniApp AST
17. Transfrom-component 组件转换器设计 基于 Wepy 和 Vue 中的 Script 语法对比来梳理设计思路 01 02 03 04 wepy 独有包依赖差异 Props/data/methods 生命周期钩子不同 事件发布/订阅的注册和监听机制不同 Wepy-script Vue-script 生命周期差异 05 ...等等
18. Transfrom-component 组件转换器实现 组件转换流水线实现: 将传入的 Wepy Comp AST 通过预归集和 DSL 语法差异处理,最终输出 UniApp Comp AST。 通过深度遍历,按照预置好的 规则进行数据归集处理 1.Wepy AST Transform -Template 模板转换器实现 通过归集好的各类 AST 节点数据, 进行各类场景下 DSL 语法的转换 3. DSL 语法差异转换 a.归集 ClassProperty 语法 AST节点 a.Wepy -> Vue 生命周期映射 b.归集非生命周期白名单内的函数 AST 节点 b.生命周期堆叠的处理 c.归集生命周期白名单内的函数 AST 节点 c.函数的处理 d.归集发布/订阅事件注册的函数 AST 节点 d.事件的处理 4. UniApp AST
19. 挑战 典型问题场景回溯 01 Uni-App 中 Template String 语法的适配 02 Scope Style 在 UniApp 中的适配
20. 典型难题回溯-模板字符语法适配 问题一 根因 模板字符串语法(template string)在 UniApp 底层编译不兼容 Wepy 项目的模板语法中充斥着大量的属性表达式,我们需要用模板字符串语法来无缝接入,但是 UniApp 的 style 和 class 属性在编译为小程序时不支持这种写法。 修复方案 wepy 动态表达式 wepy-chameleon compile vue 动态表达式 uni-app compile patch-package 自动化补丁
21. 典型难题回溯 - Scope Style 的适配 问题二 Wepy 私有化样式(scope style)的声明在 UniApp 编译后丢失 Wepy 文件转换为 UniApp 项目后正常,UniApp 编译为小程序后就发生了样式覆写丢失。 wepy-chameleon compile 样式异常 uni-app compile
22. 典型难题回溯 - Scope Style 的适配 根因 Vue 和 UniApp 中关于私有化样式的实现机制不同 scopeId 这个用于区分样式作用域的唯一标识在 UniApp 中的处理逻辑不是完全一致的。 vue 的 scope 原理 uniapp 的 scope 原理 主要通过生成data-xx attrbuite 来对页面元素进行定位 主要通过在 class 中生成 data-id 来区分
23. 典型难题回溯 - Scope Style 的适配 解决思路 对 UniApp 的 scope Compile 新增对 template String 场景的处理 我们不需要单独拉分支对 uniApp 提 PR 来处理,同样通过 patch-package 来 fix 即可。 patch package- 添加对isTemplateString的判断 目的:让 uniapp 底层编译 template String 格式的 class/style 属性 转换为数组格式 patch此处 class属性处理支持String template scopeId 已经可以正确的被 push 到原有的 className 中
24.
25. 后续规划 总结 有力的支撑了业务架构升级, 实现了规模化的代码升级能力 01 覆盖更多的 wepy 项目及场景 02 深挖业务中可以通过编译提效的空间 验证了编译技术对前端 能效大幅度提升 提升了团队对编译的 认知和知识积累
26.

首页 - Wiki
Copyright © 2011-2023 iteam. Current version is 2.107.0. UTC+08:00, 2023-01-31 22:14
浙ICP备14020137号-1 $访客地图$