基于 wujie.js 进行微前端融合

项目背景

目前项目中需要将A ,B 两个项目进行融合,A ,B 项目有各自的用户token与自己的交互方式,技术栈一致。之前是用跳链的方式,新开一个页面进行操作,给用户的感官是两个项目较为割裂,目前期望让两个项目看起来像一个整体,减少割裂感。

解决方案

  1. iframe内嵌 + 菜单融合
  2. 微前端融合

iframe内嵌 + 菜单融合

iframe内嵌有两种方式:

第一种是将整个B 项目作为一个页面融入A 项目,这样做的好处是切换页面不会重复请求,session,local等存储便于管理,不会出现样式覆盖。缺点是依旧有一些割裂感,且B 项目是整体作为一个页面,感官上很奇怪。

第二种是将B 项目的多个页面融入A 项目的菜单,整体感官上会是一个整体,但是切换页面的时候容易造成重复请求,白屏等情况,用户体验较差

微前端融合------qiankun

qiankun 是一个由阿里巴巴(蚂蚁金服)团队开源的微前端解决方案。它基于Single-SPA进行二次开发和增强,旨在帮助开发者将单体前端应用改造为由多个独立"微应用"聚合而成的架构。‌‌

如果你是使用umi框架进行开发,我建议使用qiankun,因为umi 提供开箱即用的微前端支持,通过简单的配置即可实现微前端融合

qiankun 使用 Proxy沙箱拦截全局变量,通过重写CSS选择器,添加前缀实现样式隔离,依赖 import-html-entry解析HTML。通过 props 传递和 globalState 进行全局状态管理。基于数据流传递内容

微前端融合------wujie

Wujie 是由‌京东物流技术团队自主研发的微前端框架,用于解决大型前端应用在模块解耦、独立部署、技术栈兼容等方面的挑战。

如果你是使用 vue 进行页面开发,同时期望用尽可能少的改动实现简单的微前端融合,我推荐使用 wujie。

无界使用iframe 作为JS运行沙箱,通过 WebComponent 将渲染内容映射到主应用上,既享受了iframe对JS的绝对隔离,又避免了iframe的UI通信和样式局限性。CSS通过样式作用域和 Shadow-DOM机制,隔离性优于qiankun的Proxy模式。原生支持子应用保活,预加载等功能,开发改动量小。

Wujie 接入

详细代码见:wujie/examples at master · Tencent/wujie · GitHub

主应用改造

main.js 改造

javascript 复制代码
// main.js
import WujieVue from "wujie-vue2";
const isProduction = process.env.NODE_ENV === "production";
const { setupApp, preloadApp, bus } = WujieVue;

bus.$on("click", (msg) => window.alert(msg));

// 在 xxx-sub 路由下子应用将激活路由同步给主应用,主应用跳转对应路由高亮菜单栏
bus.$on("sub-route-change", (name, path) => {
  const mainName = `${name}-sub`;
  const mainPath = `/${name}-sub${path}`;
  const currentName = router.currentRoute.name;
  const currentPath = router.currentRoute.path;
  if (mainName === currentName && mainPath !== currentPath) {
    router.push({ path: mainPath });
  }
});

const degrade = window.localStorage.getItem("degrade") === "true" || !window.Proxy || !window.CustomElementRegistry;
const props = {
  jump: (name) => {
    router.push({ name });
  },
};
/**
 * 大部分业务无需设置 attrs
 * 此处修正 iframe 的 src,是防止github pages csp报错
 * 因为默认是只有 host+port,没有携带路径
 */
const attrs = isProduction ? { src: hostMap("//localhost:8000/") } : {};
/**
 * 配置应用,主要是设置默认配置
 * preloadApp、startApp的配置会基于这个配置做覆盖
 */
setupApp({
  name: "react16",
  url: hostMap("//localhost:7600/"),
  attrs,
  exec: true,
  props,
  fetch: credentialsFetch,
  plugins,
  prefix: { "prefix-dialog": "/dialog", "prefix-location": "/location" },
  degrade,
  ...lifecycles,
});

子应用渲染组件实现

js 复制代码
//Vue2Sub
<template>
  <!--单例模式,name相同则复用一个无界实例,改变url则子应用重新渲染实例到对应路由 -->
  <WujieVue width="100%" height="100%" name="vue2" :url="vue2Url"></WujieVue>
</template>

<script>
import hostMap from "../hostMap";

export default {
  computed: {
    vue2Url() {
      return hostMap("//localhost:7200/") + `#/${this.$route.params.path}`;
    },
  },
  methods: {
    jump(name) {
      this.$router.push({ name });
    },
  },
};
</script>

<style lang="scss" scoped></style>

编写路由!!!

js 复制代码
//router.js
{
    path: "/vue2-sub/:path",
    name: "vue2-sub",
    component: Vue2Sub,
},

总结

wujie 的优势很明显,代码改动量小,无需配置子应用前缀,适合快速接入开发的项目,数据传递主要依赖于事件系统,例如我本来想传递一个全局用户信息给子应用,结果发现数据变化时,不会触发任何内容,并且子应用的 props 也没有更新,所以我自己基于事件传递实现了一套自动化获取token然后登陆的逻辑,实现相关功能。此外wujie的文档较为简单,有些功能函数的具体作用也不是很清晰,只能根据自己去猜(也可能是笔者能力较弱,叠个甲,哈哈哈)

相关推荐
燐妤21 分钟前
前端HTML编程2:深入学习表单与表格
前端·学习·html5
朝阳3925 分钟前
react【实战】首页 -- 响应式导航栏(含带联动动画的搜索框)
前端·react.js·前端框架
贾铭39 分钟前
如何实现一个网页版的剪映(五)如何跳转到视频某一帧
前端·后端
林恒smileZAZ43 分钟前
CSS 滚动驱动动画(scroll-timeline):无 JS 实现滚动特效
前端·javascript·css
俺不会敲代码啊啊啊43 分钟前
el-table实现行拖拽(包含展开项)
前端·vue.js·typescript
LIO43 分钟前
React Router 极简指南(v6+)
前端·react.js
明月_清风1 小时前
从 AST 视角看透前端工程化:一条编译管线如何串联起所有工具
前端
架构源启1 小时前
2026 进阶篇:Spring Boot响应式编程 + Spring AI 1.1.4 流式实战 + Vue前端完整实现(避坑指南)
java·前端·vue.js·人工智能·spring boot·spring·ai编程
白开水都有人用1 小时前
前端 AES 加密 + 后端解密 + MD5 校验登录
前端
OpenTiny社区1 小时前
还在手写 AI 聊天页?这款 Vue3 气泡组件,直接搞定流式对话!
前端·vue.js·ai编程