xinglie / xinglie.github.io

blog
https://xinglie.github.io
153 stars 22 forks source link

跨技术栈的混合渲染在magix中的实践 #98

Open xinglie opened 2 years ago

xinglie commented 2 years ago

文章在2019年写的,从内部转载公布于此

前言

经过几年的努力,阿里妈妈所有基于magix技术开发的管理系统、运营平台、营销页面等,均被统一成了[magix运行环境]+[各自的业务view],在整个推进过程中,magix-cli功不可没

magix运行环境

运行环境包括以下几个部分

  1. 模块加载器,如seajs
  2. 基础类库,如jQuery
  3. magix核心代码
  4. magix组件库
  5. web components组件

业务view

各业务线为了完成自己的业务需求而实现的自己的view

因为有了magix-cli,各系统、平台、营销页面之间,除了业务view不同外,magix的运行环境是一致的,这也给接下来的magix项目间加载打下了基础

magix项目间的互相加载与渲染

项目间的加载在技术上没有难点,更多的是在业务上,比如有些view是登录后才能访问的,有些view可能挂载一些特定的权限等,因此我们除了技术外,在项目中约定了一些规则。

  1. 各项目间的业务view需要继承自己的基类view,在基类view中完成如请求、挂载等事情
  2. 各项目需要有一个prepare预处理文件,用于处理自己的登录等前置事情
  3. 各项目中需要的组件要动态加载,这里主要是为了避免同样的组件反复加载。被渲染的view所需要的组件由宿主提供

更详细的约定可以参考这里:https://thx.github.io/magix-cli-book/#/crossProjectView

当我们完成了这些约定后,项目间的渲染即可以顺利进行,目前在阿里妈妈的后台项目中,如钻展、信息流、直通车等均使用了该技术进行加载其它项目中的view

magix与其它技术栈

如何把magix中的view渲染到React中?

根据前面的说明,基于magix项目,目前[magix运行环境]是统一的,即大家都是同样的magix版本,同样的模块加载,同样的基础通用库等,只是为了方便管理和减少互相影响,[magix运行环境]是在每个项目中安装了一份。

如果要把任意一个基于magix技术的业务view渲染到别的技术栈里,我们需要先加载这份[magix运行环境],加载完成后即可把任意业务view渲染出来。

这份[magix运行环境]我做了提取,仓库在这里:(内部地址,外部不展示) magix-ports中只包括运行业务view所需要的模块加载器、基础类库、magix核心代码、组件等

magix-ports-react

有了magix-ports这个运行环境还是不够的,前面我们提到为了方便处理业务view是否需要登录、权限等,我们做了一些约定,因此我们要加载完magix-ports环境后,还需要根据约定把这些业务上的事情也要处理一遍。同时为了方便各技术栈的引用,magix这边应该提供相应技术栈的组件供对方使用,比如我们实现的

magix-ports-react:(内部地址,外部不展示)

就是方便把magix的view渲染到react技术栈里

在magix-ports-react内部我们做了前述的业务约定处理,方便react使用

  1. 加载magix-ports这个所有magix view通用的运行环境
  2. 根据待加载的view确定该view所处的cdn地址
  3. 根据是否需要登录加载相应的prepare
  4. 渲染view

目前该实现已经在adc项目中实施

技术细节可参考这里:https://github.com/xinglie/xinglie.github.io/issues/97

未来

Q:目前基于magix项目均是[magix运行环境]+[各自的业务view],而magix-ports其实就是[magix运行环境],那以后会不会把各项目中的[magix运行环境]替换成magix-ports这一份而不是各自维护? A:这个目前有这样的倾向,统一后更方便项目间互相渲染及跨技术栈渲染,但也会带来调试、链路变长等问题。我们会先把跨技术栈渲染这个事情做稳定,组件切换到web components上,然后再根据情况切换[magix运行环境]到magix-ports上

Q:如何把其它技术栈的组件渲染到magix项目中? A:需要其它技术栈提供方案

Q:除react外,还有其它技术栈方便使用吗 A:我们提供了magix-ports-vanilla用于支持任何环境,当然,为了某些技术栈使用方便,我们可以快速提供相应技术栈的组件