当前位置: 首页 > news >正文

无界 Wujie 微前端实战:三步接入、三种模式与高频坑的完整指南

无界 Wujie 微前端实战:三步接入、三种模式与高频坑的完整指南

【免费下载链接】wujie极致的微前端框架项目地址: https://gitcode.com/gh_mirrors/wu/wujie

无界(Wujie)是一款基于 Web Components + iframe 的微前端框架,核心思路是把子应用"原生隔离"地装进主应用页面:样式靠 Web Components(浏览器原生的组件封装技术)隔离,JS 在 iframe(浏览器原生的隔离小窗口)里运行,两边互不污染。它对子应用几乎零侵入,存量老项目也能直接用。

如果你有下面两种情况,这份实战就是为你写的:

  • 多团队各维护一套应用,想并入同一套系统,但技术栈没法统一
  • 有一批不想(也没法)动的老应用,需要嵌进新门户里

💼 为什么不用 iframe 直接套?

纯 iframe 嵌入看似省事,实际有三个绕不开的问题:

  1. 隔离太彻底:JS、路由、DOM 全关在 iframe 里,主应用够不着,跨窗口通信很别扭
  2. 体验割裂:弹窗盖不住整页,路由跟浏览器地址栏不同步,刷新丢状态
  3. 切换慢:每次切页面都重新请求资源,白屏时间不受控

无界的解法可以一句话讲清:Web Components 管 DOM,iframe 管 JS。DOM 留在主应用这一层,所以弹窗能覆盖整页、样式原生隔离;JS 仍跑在 iframe 里,执行环境同样天然隔离。两个都是浏览器原生能力,比自造沙箱的微前端方案省掉大量边界问题。

🔌 三步完成主应用接入

Vue / React 主应用可以直接用 wujie-vue、wujie-react 封装组件,这里给原生函数写法,逻辑完全一样:

import { setupApp, preloadApp, startApp } from "wujie"; setupApp({ name: "sub-app", // 子应用唯一标识 url: "http://sub.example.com", // 子应用地址 el: "#container", // 挂载容器 sync: true, // 路由同步,刷新不丢路由 alive: true // 保活模式 }); preloadApp({ name: "sub-app" }); // 预加载资源,可加 exec: true 直接预执行 startApp({ name: "sub-app" }); // 启动并渲染子应用

三步各司其职:setupAppname存一份默认参数,后面调用不用重复填;preloadApp把资源提前拉下来,exec: true时连代码都先执行完,用户点进来基本秒开;startApp才真正渲染。如果主应用彻底不用某子应用了,用destroyApp销毁——这是破坏性操作,后面坑点里细说。

🚦 子应用要改多少代码?先解决跨域

先给结论:跨域配好之后,保活和重建模式下一个字都不用改子应用;只有单例模式要做生命周期改造(下面单独讲)。

子应用的静态资源和接口请求都是从主应用域名发起的,所以子应用服务器必须开放 CORS。用 Node.js 部署的话,服务端加一段响应头就够了:

app.use((req, res, next) => { res.set({ "Access-Control-Allow-Credentials": true, "Access-Control-Allow-Origin": req.headers.origin || "*", "Access-Control-Allow-Headers": "X-Requested-With,Content-Type", "Access-Control-Allow-Methods": "PUT,POST,GET,DELETE,OPTIONS", }); next(); });

这段中间件会把主应用来源回显给浏览器,加载时的"资源请求报错"就消失了;具体放行范围按你的业务收紧。另外,遇到代码根本碰不到的子应用,还可以用replace钩子在运行时改写它的 HTML / JS / CSS,源工程一行不动。

🧭 三种运行模式怎么选

无界把子应用分成三种运行模式,区别在"切换页面时子应用被怎么对待":

模式开启方式改造成本适用场景
保活模式alive: true零改造不想白屏、要保留状态;老项目首选
重建模式不保活、不改造(默认)零改造低频子应用、内存敏感场景
单例模式不保活 + 生命周期改造需改造多个菜单要跳到同一子应用的不同页面

白话翻译:保活 ≈ 实例常驻内存,切换只显隐不重建;重建 = 每次进来都推倒重来;单例 ≈ 常驻一个"插槽",切换时销毁旧实例、创建新实例,而且可以靠改url精准定位到新实例的子路由。

一句话选型:子应用碰不了代码,选保活;要省内存且接受重新加载,选重建;多个菜单指向同一子应用的不同页面,选单例(这时把name设成同一个,各菜单还能共享一个实例和承载 JS 的 iframe)。更多细节可看仓库文档 docs/guide/mode.md。

✍️ 单例模式生命周期怎么写

选了单例模式,就要把子应用的"创建、挂载、销毁"包进两个函数:挂在window.__WUJIE_MOUNT,销毁挂在window.__WUJIE_UNMOUNT。以 Vue 3 为例:

if (window.__POWERED_BY_WUJIE__) { let instance; window.__WUJIE_MOUNT = () => { const router = createRouter({ history: createWebHistory(), routes }); instance = createApp(App); instance.use(router); instance.mount("#app"); }; window.__WUJIE_UNMOUNT = () => { instance.unmount(); }; } else { createApp(App).use(createRouter({ history: createWebHistory(), routes })).mount("#app"); }

window.__POWERED_BY_WUJIE__是无界注入的标记位,等于"我正被无界接管"。特别注意:Vite 项目因为脚本是异步加载的,实例化时机不确定,定义完上面两个函数后要主动调一次window.__WUJIE.mount(),无界的 mount 函数内置了去重标记,不会重复挂载。

⚠️ 高频坑点,踩过的都在这

  1. 预加载与启动参数不一致namereplacefetchalivedegrade这五个参数在preloadAppstartApp里必须严格一致,最常见的事故就是改了预加载配置忘了同步启动配置,渲染直接异常。
  2. 保活模式下改 url 不跳路由:实例是常驻的,startApp改变url对路由无效。想让保活子应用换页面,得用bus(无界自带的事件总线,主应用和子应用各持一端)通信跳转。
  3. 别随手 destroyApp:它会把 iframe、shadowRoot 和无界实例一起销毁,缓存全清。只要子应用后面还会打开,下次进来就会有一段白屏;"重建"用refreshApp就够了,destroyApp留给真正"再也不用"的场景。
  4. Vite 子应用里 location 不对:module 脚本无法被代理劫持,window.location.host拿到的是主应用的 host。要读子应用自己的 host,统一改用$wujie.location.host(无界注入在window.$wujie上)。
  5. 降级有代价degrade: true时子应用跑进真 iframe,理论上能兼容老浏览器,但弹窗困在 iframe 里盖不住整页。只给确认不兼容的浏览器打开,别全局开。

🚀 上线前再看三条进阶建议

  1. 核心子应用预执行preloadApp配合exec: true再加保活,请求和渲染全部提前完成,接近 SSR 的秒开体验。代价是预加载占用网络线程、预执行占用渲染线程,别无脑全开。
  2. 路由同步 + 短路径sync: true会把子应用路由写进主应用 URL 的查询参数,刷新、分享链接都不丢状态;链接太长时用prefix做短路径替换。
  3. 接口带 cookie:子应用请求需要携带 cookie 时,传一个自定义 fetch 即可:fetch: (url, options) => window.fetch(url, { ...options, credentials: "include" })

你的第一步:挑一个最核心的子应用,用"保活模式 + 预加载"在本地跑通(子应用不改代码,只把服务端跨域打开),链路稳定之后再评估要不要升级到单例模式。

【免费下载链接】wujie极致的微前端框架项目地址: https://gitcode.com/gh_mirrors/wu/wujie

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.cnnetsun.cn/news/4157710.html

相关文章:

  • IP地址与子网掩码深度解析:从原理到实战的网络配置指南
  • Numa Balancing 入门
  • kaml快速开始:data class与YAML双向转换,4个实战例子讲清核心用法
  • OBS RTSP 服务器搭建:5分钟装好 obs-rtspserver 插件并出流
  • MobaXterm Keygen 快速上手:3 步生成专业版许可证文件
  • 拆解Orbit区块链交易调查工具核心代码:ranker排行算法、getNew去重与pageLimit分页机制详解
  • 现货电价API接入最佳实践:日前电价、实时电价、节点电价和96点数据
  • 安全先行:office-docs-powershell管理员必须知道的8个PowerShell认证与权限最佳实践清单
  • Triton前置——Python基础语法
  • HumanInput源码剖析:8KB事件库如何解析复杂的组合事件字符串,EventHandler设计全解读
  • NAND闪存工作原理——SSD数据是如何存储的?
  • SDRangel SDR信号接收与频谱分析快速上手
  • 一台电脑两台手柄?任意 PC 游戏双人分屏的完整指南
  • 跑通多模态情感分析:Multimodal-Sentiment-Analysis 图文融合实战指南
  • MonitorControl|macOS外接显示器亮度音量一键调:多屏办公党的屏幕控制方案
  • 论文AI率0%黑科技!降AIGC网站留学生亲测::Turnitin查重秒变“教授最爱”原创风
  • 题解:洛谷 P3184 [USACO16DEC] Counting Haybales S
  • 文档加载工程:从多格式数据到标准化Document对象的实战指南
  • 5 步装好 Windows 微信防撤回补丁:RevokeMsgPatcher 新手完整教程
  • Unlock-Music 音乐解密完整指南:在浏览器里批量解密 qmc、ncm 等加密音乐文件
  • AnythingLLM 本地部署完全指南:私有知识库文档问答
  • Linux入门攻坚——86、ELK Stack-1-基本概念
  • SpringBoot+微信小程序旅游平台:从零到部署的毕设实战指南
  • U盘重装Windows系统全攻略:从启动盘制作到安装设置详解
  • DatalinkX 快速上手指南:从零到跑通第一个数据同步任务
  • 3分钟把整本网页小说存成EPUB:WebToEpub离线阅读工具上手笔记
  • LinkSwift 网盘直链解析工具:实用新手指南
  • 万店连锁智能运维实践:从告警驱动到一键根因定位的STAROps体系
  • slack-irc 消息格式转换艺术:Slack到IRC文本解析与表情映射完整剖析
  • MobilityDB查询完全手册:时空重叠、距离计算与轨迹插值SQL函数大全