什么是 Garfish 微前端框架,它的核心特点和应用场景是什么?
Garfish 是字节跳动开源的微前端框架,主要解决大型前端应用在跨团队协作、技术栈多样化和独立部署方面的痛点。与 qiankun 等方案相比,Garfish 在沙箱隔离和依赖共享上有独特设计,适合对隔离性和性能有更高要求的企业级场景。
Garfish 的核心架构
Garfish 的整体架构由以下核心模块组成:
- Loader(加载器):负责子应用资源的获取和解析,支持异步加载和预加载策略
- Sandbox(沙箱):隔离子应用的 JavaScript 执行环境,防止全局变量污染
- Router(路由):管理子应用的路由注册、匹配和切换
- Store(状态管理):提供跨应用的通信机制
下面通过一个最小接入示例说明 Garfish 的基本用法:
jsimport Garfish from 'garfish'; Garfish.run({ basename: '/', domGetter: '#sub-app', apps: [ { name: 'vue-app', entry: 'http://localhost:8080', activeWhen: '/vue', }, { name: 'react-app', entry: 'http://localhost:3000', activeWhen: '/react', }, ], });
主应用只需配置子应用的名称、入口地址和激活路由,Garfish 会自动处理加载、挂载和卸载。
六大核心特点详解
1. 沙箱隔离
Garfish 提供两种沙箱模式:
- 快照沙箱(Snapshot Sandbox):在子应用挂载前快照 window 对象,卸载后恢复。适用于不支持 Proxy 的浏览器,但无法处理动态添加的全局变量。
- VM 沙箱(Proxy Sandbox):基于 ES6 Proxy 实现,为每个子应用创建一个代理 window 对象,真正实现了全局变量的隔离。这是 Garfish 推荐的方式。
js// VM 沙箱原理示意 const proxyWindow = new Proxy(window, { get(target, key) { // 优先从子应用自己的状态中读取 return ownState[key] ?? target[key]; }, set(target, key, value) { ownState[key] = value; // 写入子应用独立状态 return true; }, });
VM 沙箱的优势在于多个子应用可以同时运行而互不干扰,这也是 Garfish 支持多实例的基础。
2. 依赖共享
Garfish 支持子应用之间共享公共依赖(如 React、Vue、Lodash 等),避免重复加载同一库的多个副本:
jsGarfish.run({ apps: [ { name: 'app1', entry: 'http://localhost:8081', props: { react: require('react'), // 共享 React 实例 }, }, ], });
依赖共享能显著降低整体包体积和加载时间,对于同时运行多个 React 子应用的场景尤为明显。
3. 预加载策略
Garfish 内置智能预加载机制,会在浏览器空闲时提前获取子应用资源:
- 自动记录用户访问习惯,为高频使用的子应用增加预加载权重
- 支持
prefetch配置项,可自定义预加载行为 - 预加载的资源包括 HTML、JS、CSS 等子应用入口依赖
jsGarfish.run({ prefetch: true, // 开启预加载 // 也可传入函数自定义预加载逻辑 // prefetch: (apps) => apps.filter(app => app.name === 'high-priority-app'), });
4. 框架无关
Garfish 对子应用的技术栈没有限制,React、Vue、Angular、Svelte 等均可接入。子应用只需导出固定的生命周期钩子:
js// 子应用需要导出的生命周期 export function provider({ dom, basename, props }) { return { mount() { /* 挂载逻辑 */ }, unmount() { /* 卸载逻辑 */ }, update() { /* 可选,接收父应用传参更新 */ }, }; }
5. 多实例支持
不同于部分微前端方案只允许单个子应用运行,Garfish 支持在同一页面中同时运行多个子应用实例:
js// 同一页面同时挂载两个子应用 Garfish.run({ domGetter: '#container', apps: [ { name: 'sidebar', activeWhen: '/', entry: '...' }, { name: 'main-content', activeWhen: '/', entry: '...' }, ], });
这在后台管理系统等需要布局嵌套的场景中非常实用。
6. 样式隔离
Garfish 提供多种样式隔离方案:
- CSS Scoped:为子应用的样式自动添加作用域前缀
- Shadow DOM:利用浏览器原生的 Shadow DOM 实现完全隔离
- CSS Modules:配合构建工具使用,从源头避免样式冲突
Garfish vs Qiankun:如何选择?
| 对比维度 | Garfish | Qiankun |
|---|---|---|
| 出品方 | 字节跳动 | 蚂蚁集团 |
| 沙箱方案 | 快照 + VM 双模式 | 快照 + Proxy 双模式 |
| 依赖共享 | 原生支持 | 需额外配置 |
| 多实例 | 原生支持 | 有限支持 |
| 预加载 | 内置智能预加载 | 需手动配置 |
| 社区规模 | ~2.9k Stars | ~16k Stars |
| 文档完善度 | 中等 | 较完善 |
| 适用场景 | 隔离性要求高、需多实例 | 通用场景、快速接入 |
选择建议:
- 选 Garfish:项目需要强隔离、多实例共存、依赖共享,或已在字节生态内
- 选 Qiankun:追求社区支持、开箱即用,或团队微前端经验较少
典型应用场景
企业级后台管理系统
多个业务团队各自维护独立子应用(权限管理、数据分析、运营工具等),通过 Garfish 统一接入主框架,实现独立开发、独立部署。
电商平台
活动页、商品详情、购物车等模块由不同团队负责,使用 Garfish 的预加载和依赖共享优化首屏性能。
大型 SaaS 产品
不同功能模块(CRM、BI、工单系统)采用不同技术栈,Garfish 的框架无关特性允许各模块选择最合适的技术方案。
接入注意事项
- 子应用改造:需要导出
provider生命周期函数,并在打包配置中设置libraryTarget: 'umd' - 跨域配置:子应用需配置 CORS 头,允许主应用跨域获取资源
- 环境变量:子应用中访问
window时需注意沙箱代理,避免直接操作导致泄漏 - 公共路径:子应用的静态资源路径需正确配置
publicPath,防止资源加载失败
总结
Garfish 作为字节跳动出品的微前端框架,在沙箱隔离、依赖共享和多实例方面有独到优势。如果你的项目对应用隔离有较高要求,或者需要在一个页面中同时运行多个子应用,Garfish 是值得考虑的方案。但在社区生态和文档完善度上,它目前仍落后于 qiankun,团队在选型时需要权衡技术优势与社区支持之间的取舍。