背景说明

此次实践对比相对知名的框架:single-spa,icestark,qiankun

其中在微前端这篇文章中我们可以看到,icestark,qiankun,Magix三个都是阿里旗下的产物,分别由baba和mama实现。下边将对各个框架逐一踩坑

开始之前,我先从stateofjs找了排前三的前端框架作为子项目

single-spa

  • 官网:https://single-spa.js.org/docs/getting-started-overview
  • 类型:
    • application / parcel:同属UI层,区别是前者为特定路由渲染微前端UI,后者不受路由限制(通用组件UI)
    • utility module (styleguide, api cache, etc):逻辑层,暴露(通用)共享逻辑(helpers…)
    • root config:微应用入口配置(至少得有一个)。包括一个被所有single-spa应用共享的html文件和一个注册子应用的js文件,当然二者是可以合并成一个文件的,即可以在一个html里完成所有配置。

新项目接入

整个新建过程使用create-single-spa命令生成脚手架代码,请npm install -g create-single-spa

1. 创建俩不同框架的application
mkdir single-spa-demo && cd single-spa-demo && mkdir apps && cd apps

create-single-spa react-app
create-single-spa vue-app

2. 创建root-config

注意Organization这里不要为空,否则会有问题

3. 启动微服务并尝试接入子应用
启动基座

如果直接启动,你会发现有这个问题:Unable to resolve bare specifier ‘single-spa’。然后你需要从**cdnjs手动添加一个库。后来从官方了解到>=1.8.0**之后就没有这个问题了,实测是这样。所以如果遇到这个问题,请更新cli版本

实际上在index.ejs中,我们可以看到还有一个systemjs-importmap是被注释起来的。我们打开注释并加入依赖的核心库

<script type="systemjs-importmap" src="/importmap.json"></script>
{
  "imports": {
    "single-spa": "https://cdnjs.cloudflare.com/ajax/libs/single-spa/5.5.1/umd/single-spa.min.js",
    "react": "https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js",
    "react-dom": "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js",
    "vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"
  }
}
接入子应用

reactvue按照上面的命令一顿操作下来基本没啥问题,但svelte命令里没有集成,所以我们需要人肉集成

npx degit sveltejs/template svelte-app

然后参考:https://single-spa.js.org/docs/ecosystem-svelte

这样一顿操作之后,你又会发现Svelte挂掉了

紧接着,你需要把代码稍加改造

const svelteLifecycles = singleSpaSvelte({
  component: function() {
    return SvelteApp;
  },
  domElementGetter: () => document.getElementById("svelte-app"),
  props: {}
});

此时,三大框架均已成功融合到single-spa微应用了

registerApplication({
  name: "svelte-app",
  app: () => System.import("@thomas/svelte-app"),
  activeWhen: "/",
});

registerApplication({
  name: "react-app",
  app: () => System.import("@thomas/react-app"),
  activeWhen: "/react",
});

registerApplication({
  name: "vue-app",
  app: () => System.import("@thomas/vue-app"),
  activeWhen: "/vue",
});
<script type="systemjs-importmap">
    {
      "imports": {
        "@thomas/root-config": "//localhost:9000/thomas-root-config.js",
        "@thomas/react-app": "//localhost:9001/thomas-react-app.js",
        "@thomas/vue-app": "//localhost:9002/js/app.js",
        "@thomas/svelte-app": "//localhost:9003/build/bundle.js"
      }
    }
  </script>

icestark

  • 官网:https://ice.work/docs/icestark/about
  • 核心:
    • 框架应用:一个系统只有一个框架应用,框架应用负责系统整体的 Layout 以及子应用的管理与注册(由于目前的API设计参考了React Router,同时为保证开发体验,框架应用跟React做了耦合,所以框架应用必须基于React)
    • 子应用:通常是一个单页面应用,可能包含一个或多个页面,子应用负责自身相关的几个页面代码。

新项目接入

相比single-spa,icestark的接入姿势简单许多,官方文档又是中文的,建议直接搬命令操作。

整体感觉封装的比较彻底,不需要过多配置。新项目入手还是很方便的,唯一会有的问题就是官方基座模板使用了icejs,无形之中又增加了一种学习成本。

改造旧项目

为了探究icestark的能力,这里我用改造旧项目的方式整合一个微前端应用。首先还是用官方的姿势创建一个框架应用

子项目改造

首先添加依赖yarn add @ice/stark-app,然后根据官方文档进行已有项目改造子应用。一切顺利的话,如下图就完成了icestark的整合!

qiankun

从官方介绍来看,乾坤是基于single-spa的微前端实现库。因此一些概念和实现可能需要往上再看一遍

新项目接入

qiankun不像single-spa官方那样提供一个cli命令去生成主应用和子应用,也不像icestark那样主应用必须是React。因此对于qiankun大法,主应用可以自由选择,比如用create-react-appvue-cli。此处用@vue/cli 4.3.1创建主应用

另外官方例子中,有二者的实现,有需要可以参考一下:examples。主应用创建完成后,基本上按照官方的文档一顿操作即可集成

qiankun官方文档相当简介,以至于稍不注意就看完了,我竟然还会有一种意犹未尽的感觉…以为上了个假官网!

总结

几乎遵循这两年流行的思想,即:「去中心化」。分治而又在某个统一规则下玩,除了single-spa,后边的icestarkqiankun都分别支持html entry,即某种成都上用一样的方式解决了样式隔离等微前端核心难题

从接入的友好性和研发成本来看,阿里的库无疑是比较好的选择,而icestark和React绑的比较重,从官方文档可以看到他们还有很多事情要处理,所以综合下来qiankun算是目前最好的微前端框架了。

之后有时间再剖一篇原理实现,敬请期待!

资料