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为主的技术栈不符
  • 尝试将ReactWeex融合,发现有很多无法解决的性能问题

Rax的愿景

  • DSL标准
  • 多端投放
  • 生态完善
  • 一次开发,多端运行

Rax跨端解决方案的设计及原理

跨端方案设计

notion image

VDOM的优势

特点

  1. 标准的数据结构
  1. 与具体的端解耦

价值

  1. UI = fn(state)
  1. 跨端

从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节点等等
notion image

DSL设计

为什么有了VDOM还需要语法编译

  • VDOM的跨端能力需要容器来提供一些能力,有的容器不具备这样的能力
notion image

语法编译带来的缺陷

  • 无法覆盖所有语法,一般都是一个子集,用起来效率不高
  • 架构的复杂度较高,需要持续的投入
  • 语法编译不是银弹,更推荐在特定的情况下使用
  • 如通过babel-plugin-import按需引入组件

目前社区编译时的方案

  1. Rax的driver-weex
  1. Taro2.0
  1. 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": {}
    ]]
  ]
}
在构建后会通过不同的目录将不同端的代码聚合
notion image

多端构建原理

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

Rax小程序整体架构

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

编译时方案

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

缺陷

语法限制
// 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适配documentwindow操作DOM的逻辑如createElement,appendChild等,将DOM树处理生成到render层
render层:利用自定义组件的自引用特性渲染构建DOM树,完成动态构建DOM的过程
notion image
notion image

© kaba 2019 - 2023