Rax intro
date
May 1, 2021
slug
rax
status
Published
tags
跨端
summary
从架构看Rax的设计
type
Post
Rax体系设计背景及现状
为什需要跨端解决方案
- 容器在持续的变化
- webview
- RN/Weex
- 小程序
- Flutter
- 除了运行在特定容器里,大多数业务都有投放到浏览器中的需求
- 不想根据容器写多套代码,也不想写代码的方式一直在变,开发效率低
Rax的起点
- RN无法支持
Web
,但是业务投放到Web
又是必需的
- 与RN方案类似的
Weex
诞生,但是Weex
的DSL其实是仿的Vue
,与PC端React
为主的技术栈不符
- 尝试将
React
与Weex
融合,发现有很多无法解决的性能问题
Rax的愿景
- DSL标准
- 多端投放
- 生态完善
- 一次开发,多端运行
Rax跨端解决方案的设计及原理
跨端方案设计

VDOM的优势
特点
- 标准的数据结构
- 与具体的端解耦
价值
UI = fn(state)
- 跨端
从VDOM到跨平台
- React/Vue起初都不具备跨平台的能力,所以早起RN/Weex都是内置一份hack的React/Vue
- Rax本身就是针对与跨平台来设计的,因此诞生时通过driver层的模式切换来适配不同的平台
- React会将jsx转换成VDOM,Rax在转换成VDOM后,若是Web端,会采用driver-dom将VDOM转换成DOM,Weex端则会采用driver-weex转换成Weex下渲染的DOM节点等等

DSL设计
为什么有了VDOM还需要语法编译
- VDOM的跨端能力需要容器来提供一些能力,有的容器不具备这样的能力

语法编译带来的缺陷
- 无法覆盖所有语法,一般都是一个子集,用起来效率不高
- 架构的复杂度较高,需要持续的投入
- 语法编译不是银弹,更推荐在特定的情况下使用
- 如通过
babel-plugin-import
按需引入组件
目前社区编译时的方案
- Rax的driver-weex
- Taro2.0
- uniapp
框架设计
应用入口
app.json
// src/app.json
{
"routes": [
{
"path": "/",
"source": "pages/Home/index"
}
],
"tabBar": {
"textColor": "#999",
"selectedColor": "#666",
"backgroundColor": "#f8f8f8",
"items": [
{
"name": "home",
"path": "/",
"icon": "https://gw.alicdn.com/tfs/TB1ypSMTcfpK1RjSZFOXXa6nFXa-144-144.png",
"activeIcon": "https://gw.alicdn.com/tfs/TB1NBiCTgHqK1RjSZFPXXcwapXa-144-144.png"
}
]
}
}
app.ts
// src/app.ts
import { runApp, IAppConfig } from 'rax-app';
// 应用配置
const appConfig: IAppConfig = {
app: {
// ...
onLaunch(){},
onShow(){}
},
router: {
// ...
},
store: {
// ...
}
};
runApp(appConfig);
多端构建
build.json中配置端,也可以针对不同平台做不同配置
{
"targets": ["web", "miniapp"],
"web":{
"ssr": true
},
"miniapp": {
"buildType": "runtime"
},
"plugins": [
["build-plugin-rax-faas",[
"options": {}
]]
]
}
在构建后会通过不同的目录将不同端的代码聚合

多端构建原理
通过Webpack的多任务机制实现。
平时开发中,我们都是一个入口,打包成一个bundle。而在多端环境下,端的不同,可能需要的plugins也不同。

Rax小程序整体架构
Rax的定位:双引擎驱动的完整小程序开发体系
底层:通过集团的build scripts支撑工程,支持小程序项目、组件和插件的开发
运行时:通过模拟DOM,BOM底层的API实现适配
编译时:通过静态编译,将Rax的DSL编译成小程序DSL
生态:Fusion,Universal等
上层:支持阿里、微信、字节小程序及快应用

编译时方案
特点:高性能
底层:通过build scripts支撑
核心:jsx-compiler
编译后:通过轻量的runtime来抹平Rax与小程序的生命周期差异

缺陷
语法限制
// rax中
<View>
{props.children}
</View>
// 小程序中可以用slot实现
<View>
<slot />
</View>
// 如果rax中操作复杂一些,小程序就无法支持了
<View>
{
props.children.map(child=><Text>{child}</Text>)
}
</View>
运行时方案
特点: 弥补编译时方案的不足
- 不存在语法限制
- 运行真正的Rax,支持新特性
- 基于Webpack的工程
原理
架构:通过
webpack plugin
,输出固定的page模板代码和app模板代码编译的模版代码:通过
webpack
生成一个js bundle,通过模拟DOM和BOM的API,将document和window注入到bundle中底层:通过
miniapp-render
适配document
和window
操作DOM的逻辑如createElement,appendChild等,将DOM树处理生成到render层render层:利用自定义组件的自引用特性渲染构建DOM树,完成动态构建DOM的过程

