鹅厂最新开源 WebComponent + iframe 的微前端框架

《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐是一个基于 Web Components + iframe 的微前端框架——wujie。

鹅厂最新开源 WebComponent + iframe 的微前端框架

微前端已经是一个非常成熟的领域了,但开发者不管采用哪个现有方案,在适配成本、样式隔离、运行性能、页面白屏、子应用通信、子应用保活、多应用激活、vite 框架支持、应用共享等用户核心诉求都或存在问题、或无法提供支持。

Web Components 是一个浏览器原生支持的组件封装技术,可以有效隔离元素之间的样式,iframe 可以给子应用提供一个原生隔离的运行环境,相比自行构造的沙箱 iframe 提供了独立的 window、document、history、location,可以更好地和外部解耦。无界微前端采用 webcomponent + iframe 的沙箱模式,在实现原生隔离的前提下比较完善地解决了上述问题。

特性

  • 极速:极致预加载、预执行,页面秒开无白屏、丝滑般切换

  • 强大:支持子应用保活、内嵌、去中心化通信、多应用激活

  • 简单:框架封装, 保持普通组件使用体验一致

  • 原生隔离:基于 WebComponent 和 iframe,原生物理隔离

  • 原生性能:避免 with 语句运行代码,整体的运行性能接近原生

  • 开箱即用:主、子应用无需做任何适配,开箱即用

鹅厂最新开源 WebComponent + iframe 的微前端框架

无界优势

  • 多应用同时激活在线:框架具备同时激活多应用,并保持这些应用路由同步的能力

  • 组件式的使用方式:无需注册,更无需路由适配,在组件内使用,跟随组件装载、卸载

  • 应用级别的 keep-alive:子应用开启保活模式后,应用发生切换时整个子应用的状态可以保存下来不丢失,结合预执行模式可以获得类似ssr的打开体验

  • 纯净无污染:

    • 无界利用iframe和webcomponent来搭建天然的js隔离沙箱和css隔离沙箱

    • 利用iframe的history和主应用的history在同一个top-level browsing context来搭建天然的路由同步机制

    • 副作用局限在沙箱内部,子应用切换无需任何清理工作,没有额外的切换成本

  • 性能和体积兼具:

    • 子应用执行性能和原生一致,子应用实例instance运行在iframe地window上下文中,避免with(proxyWindow){code}这样指定代码执行上下文导致的性能下降,但是多了实例化iframe的一次性的开销,可以通过 proload 提前实例化

    • 体积比较轻量,借助iframe和webcomponent来实现沙箱,有效地减小了代码量

  • 开箱即用:不管是样式的兼容、路由的处理、弹窗的处理、热更新的加载,子应用完成接入即可开箱即用无需额外处理,应用接入成本也极低

快速上手

1、安装

1npm install wujie -S

2、主应用

引入:

1import { bus, setupApp, preloadApp, startApp, destroyApp } from "wujie";

提示:如果主应用是vue框架可直接使用 wujie-vue,react框架可直接使用 wujie-react

创建主引用:

1setupApp({{ name: "唯一id", url: "子应用地址", exec: true, el: "容器", sync: true }})

预加载:

1preloadApp({ name"唯一id"});

启动子应用:

1startApp({ name"唯一id" });

3、子应用改造

无界对子应用的侵入非常小,在满足跨域条件下子应用可以不用改造。

前提:

子应用的资源和接口的请求都在主域名发起,所以会有跨域问题,子应用必须做 cors 设置

 1app.use((req, res, next) => {
2  // 路径判断等等
3  res.set({
4    "Access-Control-Allow-Credentials"true,
5    "Access-Control-Allow-Origin": req.headers.origin || "*",
6    "Access-Control-Allow-Headers""X-Requested-With,Content-Type",
7    "Access-Control-Allow-Methods""PUT,POST,GET,DELETE,OPTIONS",
8    "Content-Type""application/json; charset=utf-8",
9  });
10  // 其他操作
11});

运行模式:

无界有三种运行模式:单例模式、保活模式、重建模式。
其中保活模式、重建模式子应用无需做任何改造工作,单例模式需要做生命周期改造。

生命周期改造:

改造入口函数:

  • 将子应用路由的创建、实例的创建渲染挂载到window.__WUJIE_MOUNT函数上

  • 将实例的销毁挂载到window.__WUJIE_UNMOUNT上

  • 如果子应用的实例化是在异步函数中进行的,在定义完生命周期函数后,请务必主动调用无界的渲染函数 window.__WUJIE.mount()

示例:

  • vue3

 1if (window.__POWERED_BY_WUJIE__) {
2  let instance;
3  window.__WUJIE_MOUNT = () => {
4    const router = createRouter({ history: createWebHistory(), routes });
5    instance = createApp(App);
6    instance.use(router);
7    instance.mount("#app");
8  };
9  window.__WUJIE_UNMOUNT = () => {
10    instance.unmount();
11  };
12else {
13  createApp(App).use(createRouter({ history: createWebHistory(), routes })).mount("#app");
14}
  • vite

 1declare global {
2  interface Window {
3    // 是否存在无界
4    __POWERED_BY_WUJIE__?: boolean;
5    // 子应用mount函数
6    __WUJIE_MOUNT: () => void;
7    // 子应用unmount函数
8    __WUJIE_UNMOUNT: () => void;
9    // 子应用无界实例
10    __WUJIE: { mount() => void };
11  }
12}
13
14if (window.__POWERED_BY_WUJIE__) {
15  let instance: any;
16  window.__WUJIE_MOUNT = () => {
17    const router = createRouter({ history: createWebHistory(), routes });
18    instance = createApp(App)
19    instance.use(router);
20    instance.mount("#app");
21  };
22  window.__WUJIE_UNMOUNT = () => {
23    instance.unmount();
24  };
25  /*
26    由于vite是异步加载,而无界可能采用fiber执行机制
27    所以mount的调用时机无法确认,框架调用时可能vite
28    还没有加载回来,这里采用主动调用防止用没有mount
29    无界mount函数内置标记,不用担心重复mount
30  */

31  window.__WUJIE.mount()
32else {
33  createApp(App).use(createRouter({ history: createWebHistory(), routes })).mount("#app");
34}
  • react

 1if (window.__POWERED_BY_WUJIE__) {
2  window.__WUJIE_MOUNT = () => {
3    ReactDOM.render(
4      <React.StrictMode>
5        <App />
6      </React.StrictMode>,
7      document.getElementById("root")
8    );
9  };
10  window.__WUJIE_UNMOUNT = () => {
11    ReactDOM.unmountComponentAtNode(document.getElementById("root"));
12  };
13else {
14  ReactDOM.render(
15    <React.StrictMode>
16      <App />
17    </React.StrictMode>,
18    document.getElementById("root")
19  );
20}


-END-

开源协议:MIT
项目地址:https://github.com/Tencent/wujie


原文始发于微信公众号(开源技术专栏):鹅厂最新开源 WebComponent + iframe 的微前端框架

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/54077.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!