5月31日 17:12

Garfish 实际项目怎么落地才不容易失控?

Garfish 落地微前端,关键不是把子应用跑起来,而是先把主应用边界、子应用生命周期、发布规则和故障兜底定清楚。主应用只做平台能力:注册应用、路由分发、登录态、主题、全局错误处理和监控埋点;业务逻辑尽量留在子应用里。这样做的取舍是,前期规范会多一点,但后续团队扩张、独立发布、灰度回滚都会轻很多。

主应用应该管什么?

主应用最好保持“薄壳”角色,不要把订单、用户、报表这类业务判断塞进去。它可以统一提供 userInfo、权限、语言、主题、接口前缀和埋点方法,再通过 props 传给子应用。边界要写清:主应用负责“能不能进入”和“挂在哪里”,子应用负责“进去以后怎么展示”。一个常见坑是主应用为了方便到处暴露全局对象,最后每个子应用都依赖它,独立运行和本地调试会很痛苦。

ts
import Garfish from 'garfish'; Garfish.run({ basename: '/', apps: [{ name: 'user-center', entry: process.env.USER_CENTER_ENTRY!, activeWhen: '/user', props: { getUser: () => window.__portal_user__, track: (event: string, data?: unknown) => sendLog(event, data), }, }], sandbox: { snapshot: true, fixBaseUrl: true }, });

子应用生命周期怎么写才稳?

子应用要保证 mount 可重复执行,unmount 能把 DOM、事件、定时器、请求订阅清干净。React、Vue、Svelte 都可以接入,但不要假设自己永远运行在完整页面里。实际项目里最容易踩坑的是全局事件和轮询任务:页面切走后还在请求接口,用户再回来就出现重复订阅。建议把清理函数集中放到一个数组里,卸载时统一执行,避免遗漏。

ts
const disposers: Array<() => void> = []; export async function mount({ dom, props }) { const onResize = () => props.track('resize'); window.addEventListener('resize', onResize); disposers.push(() => window.removeEventListener('resize', onResize)); root = createRoot(dom.querySelector('#root')!); root.render(<App user={props.getUser()} />); } export async function unmount() { root?.unmount(); disposers.splice(0).forEach(fn => fn()); }

发布和回滚要提前约定

每个子应用独立发布,但入口地址必须可控,最好通过环境配置或版本化 manifest 管理。直接把生产 entry 写死在主应用里,看起来简单,回滚时却要重新发主应用。更稳的方式是主应用读取配置中心,子应用发布后只更新版本指针。边界是配置中心也要有缓存和降级,否则它挂了会导致所有子应用加载失败。发布前还要约定资产命名、CDN 缓存、灰度比例和回滚触发条件。比如新版本错误率超过阈值时,先切回旧 entry,再排查子应用代码,而不是让主应用临时加兼容逻辑。

追问

主应用为什么不能承载太多业务逻辑?

因为微前端的收益来自团队和发布边界,而不是页面拆分本身。主应用一旦包含大量业务判断,子应用每次变更都要等主应用配合,独立发布就失效了。取舍是主应用要多做一些平台抽象,但这比后期拆耦成本低得多。踩坑点是“临时加一个判断”很容易变成长期依赖,所以要把例外也纳入评审。

子应用是否必须能独立运行?

最好能独立运行,至少本地开发和基础页面渲染不应依赖主应用。独立运行会增加一层 mock props 或本地启动配置,但可以显著降低联调成本。边界是登录、权限、埋点这类平台能力可以用模拟实现,不必在本地完整复刻。常见坑是子应用直接读取主应用全局变量,离开主应用就白屏。

团队之间怎么约定通信方式?

优先用 props 传稳定能力,用事件总线传一次性通知,少用共享可变状态。共享状态看起来方便,但边界不清时会让数据来源变得混乱。取舍是事件会让调用链不如直接函数清晰,所以事件名、payload 类型和取消订阅规则要写进规范。踩坑最多的是忘记 off,导致重复弹窗、重复请求或内存泄漏。

样式隔离应该一开始就上 Shadow DOM 吗?

不一定。后台类系统用 CSS Modules、BEM 前缀或 scoped CSS 往往够用,Shadow DOM 更适合冲突严重、第三方样式复杂的场景。它的边界是弹窗、下拉、主题变量和全局字体可能需要额外适配。取舍是隔离越强,跨应用统一视觉和调试成本也越高。

接入 Garfish 后如何做质量验收?

验收不只看页面能否打开,还要测路由切换、重复进入、卸载清理、异常加载和灰度回滚。建议 E2E 覆盖跨应用主流程,单测覆盖生命周期函数。边界是不要把所有子应用组合都测一遍,那会拖慢流水线;更实际的是主链路必测、风险应用加测。常见坑是只测首次加载,忽略第二次进入才暴露的重复订阅问题。

标签:Garfish