cover-img
avatar

托码特人

分享科技与人文

一个关注互联网的技术博客

微前端框架实践

背景说明

此次实践对比相对知名的框架: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算是目前最好的微前端框架了。

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

资料

赞赏

声明: 本文内容由托码斯创作整理,由于知识水平和时效性问题,行文可能存在差错,欢迎留言交流。读者若需转载,请保留出处,谢谢!