Garfish
Garfish 是一个轻量级的微前端框架,旨在帮助开发者实现多应用的集成与协作,提升大型复杂前端项目的开发效率和维护性。它通过沙箱技术隔离不同子应用的运行环境,保证各个微应用之间的独立性和安全性,同时支持多种加载方式,包括异步加载和预加载,优化整体性能。Garfish 兼容主流前端框架如 React、Vue 和 Angular,方便开发者在不同技术栈之间灵活切换和组合。它提供了丰富的生命周期钩子,方便开发者管理微应用的加载、挂载和卸载过程,支持路由同步和状态共享,增强子应用之间的协同能力。Garfish 还注重开发体验,具备良好的调试工具和友好的错误提示,帮助快速定位问题。通过使用 Garfish,企业能够实现前端架构的模块化和解耦,促进团队并行开发,降低项目复杂度,提高系统的可扩展性和可维护性,适用于大型互联网应用和多团队协作的场景。

查看更多相关内容
Garfish 如何实现主应用与子应用之间的通信和状态共享?Garfish 提供了多种通信机制,支持主应用与子应用之间、以及子应用之间的数据共享和交互。
## 通信方式
### 1. Props 传递
- **适用场景**:主应用向子应用传递配置、用户信息等静态数据
- **特点**:单向数据流,简单直接
- **示例**:
```javascript
// 主应用配置
{
name: 'sub-app',
entry: '//localhost:3001',
props: {
userInfo: { name: 'John', role: 'admin' },
theme: 'dark',
apiConfig: { baseUrl: '/api' }
}
}
// 子应用接收
export function mount(props) {
const { userInfo, theme, apiConfig } = props;
// 使用传递的数据
}
```
### 2. 事件总线
- **适用场景**:跨应用的事件通知和响应
- **特点**:解耦应用间依赖,支持一对多通信
- **示例**:
```javascript
// 发布事件
Garfish.channel.emit('user-login', { userId: 123 });
// 订阅事件
Garfish.channel.on('user-login', (data) => {
console.log('用户登录:', data.userId);
});
// 取消订阅
Garfish.channel.off('user-login', handler);
```
### 3. 共享状态
- **适用场景**:需要跨应用共享的业务状态
- **特点**:集中管理,响应式更新
- **示例**:
```javascript
// 定义共享状态
Garfish.registerShared({
name: 'userStore',
store: {
state: { user: null },
mutations: {
setUser(state, user) {
state.user = user;
}
}
}
});
// 子应用使用
export function mount(props) {
const userStore = props.shared.userStore;
userStore.mutations.setUser({ name: 'John' });
}
```
### 4. 自定义通信协议
- **适用场景**:复杂的业务交互逻辑
- **特点**:灵活定制,满足特定需求
- **示例**:
```javascript
// 定义通信接口
Garfish.defineInterface('auth', {
login(credentials) {
return fetch('/api/login', {
method: 'POST',
body: JSON.stringify(credentials)
});
},
logout() {
return fetch('/api/logout');
}
});
// 子应用调用
export function mount(props) {
props.auth.login({ username, password });
}
```
## 状态管理最佳实践
### 1. 状态分层
- **全局状态**:用户信息、主题、权限等
- **应用级状态**:子应用内部状态
- **组件级状态**:组件内部状态
### 2. 状态隔离
- 避免直接访问其他应用的状态
- 通过通信机制传递数据
- 保持应用的独立性
### 3. 状态同步
- 使用事件机制同步状态变化
- 实现状态变更通知
- 避免状态不一致问题
### 4. 状态持久化
- 使用 localStorage 或 sessionStorage
- 实现跨会话的状态保持
- 考虑状态恢复机制
## 通信安全考虑
### 1. 数据验证
- 验证接收到的数据格式和内容
- 防止恶意数据注入
- 实现数据校验机制
### 2. 权限控制
- 限制敏感数据的访问
- 实现基于角色的权限控制
- 审计通信日志
### 3. 错误处理
- 完善的错误捕获和处理
- 提供友好的错误提示
- 实现降级方案
## 性能优化
### 1. 减少通信频率
- 合并多个通信请求
- 使用批量更新
- 实现防抖和节流
### 2. 数据缓存
- 缓存常用数据
- 减少重复请求
- 实现缓存失效策略
### 3. 异步通信
- 使用异步方式处理通信
- 避免阻塞主线程
- 优化用户体验
通过合理使用通信机制,可以实现微前端应用间的高效协作和数据共享。
前端 · 2月21日 16:02
Garfish 的性能优化策略有哪些,如何提升微前端应用的加载速度和运行效率?Garfish 提供了多种性能优化策略,帮助开发者构建高性能的微前端应用。
## 性能优化策略
### 1. 代码分割与懒加载
- **策略**:将子应用代码分割成多个 chunk,按需加载
- **实现方式**:
- 使用 Webpack 的动态 import
- 配置路由级别的代码分割
- 实现组件级别的懒加载
- **优势**:减少初始加载时间,提升首屏性能
- **示例**:
```javascript
// 动态导入子应用
const SubApp = React.lazy(() => import('./SubApp'));
// 路由级别代码分割
const routes = [
{
path: '/dashboard',
component: React.lazy(() => import('./Dashboard'))
}
];
```
### 2. 资源预加载
- **策略**:提前加载可能需要的资源
- **实现方式**:
- 使用 `<link rel="preload">` 预加载关键资源
- 配置子应用预加载策略
- 利用空闲时间预加载
- **优势**:减少用户等待时间,提升体验
- **示例**:
```javascript
// 预加载子应用
Garfish.preloadApp('app1');
// 预加载资源
<link rel="preload" href="/app1.js" as="script">
```
### 3. 缓存优化
- **策略**:利用浏览器缓存和 Service Worker 缓存资源
- **实现方式**:
- 配置 HTTP 缓存头
- 使用 Service Worker 缓存静态资源
- 实现子应用缓存机制
- **优势**:减少网络请求,提升加载速度
- **示例**:
```javascript
// Service Worker 缓存
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('garfish-cache').then((cache) => {
return cache.addAll([
'/app1.js',
'/app1.css'
]);
})
);
});
```
### 4. 并行加载
- **策略**:同时加载多个子应用或资源
- **实现方式**:
- 使用 Promise.all 并行加载
- 配置并行加载策略
- 优化资源加载顺序
- **优势**:缩短总加载时间
- **示例**:
```javascript
// 并行加载多个子应用
await Promise.all([
Garfish.loadApp('app1'),
Garfish.loadApp('app2'),
Garfish.loadApp('app3')
]);
```
### 5. 资源压缩
- **策略**:压缩 JavaScript、CSS、图片等资源
- **实现方式**:
- 使用 Webpack 压缩插件
- 启用 Gzip 或 Brotli 压缩
- 优化图片格式和大小
- **优势**:减少传输数据量,加快加载速度
- **示例**:
```javascript
// Webpack 压缩配置
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin(),
new CssMinimizerPlugin()
]
}
};
```
## 性能监控
### 1. 加载性能监控
- 监控子应用加载时间
- 统计资源加载成功率
- 分析加载瓶颈
### 2. 运行时性能监控
- 监控内存使用情况
- 统计 CPU 占用
- 检测性能问题
### 3. 用户体验监控
- 统计首屏渲染时间
- 监控交互响应时间
- 收集用户反馈
## 最佳实践
### 1. 性能预算
- 设定资源大小限制
- 控制加载时间预算
- 定期检查性能指标
### 2. 性能测试
- 使用 Lighthouse 进行性能测试
- 进行压力测试
- 模拟不同网络环境
### 3. 持续优化
- 定期分析性能数据
- 优化热点代码
- 更新依赖版本
### 4. 性能优化工具
- 使用 Chrome DevTools 分析性能
- 利用 webpack-bundle-analyzer 分析包大小
- 使用性能监控工具
## 常见性能问题及解决方案
### 1. 首屏加载慢
- **原因**:资源过多、未优化
- **解决方案**:代码分割、懒加载、预加载
### 2. 内存泄漏
- **原因**:未正确清理资源
- **解决方案**:完善生命周期管理、及时清理
### 3. 重复加载
- **原因**:缓存策略不当
- **解决方案**:优化缓存配置、避免重复请求
### 4. 渲染卡顿
- **原因**:计算量大、DOM 操作多
- **解决方案**:虚拟列表、防抖节流、优化渲染逻辑
通过综合运用这些性能优化策略,可以显著提升微前端应用的性能和用户体验。
前端 · 2月21日 16:02
Garfish 与其他微前端框架(如 qiankun、single-spa)相比有哪些优势和劣势?Garfish 与其他微前端框架(如 qiankun、single-spa、Module Federation)各有特点,选择时需要根据项目需求进行评估。
## 框架对比
### 1. Garfish vs qiankun
#### 相似点
- 都基于 single-spa 扩展
- 都提供沙箱隔离机制
- 都支持主流前端框架
- 都有完善的生命周期管理
#### 差异点
| 特性 | Garfish | qiankun |
|------|---------|---------|
| **沙箱机制** | 支持快照、代理、严格沙箱 | 主要使用快照沙箱 |
| **样式隔离** | 支持 Shadow DOM、CSS 作用域 | 主要使用 CSS 作用域 |
| **路由管理** | 内置路由系统 | 依赖 single-spa 路由 |
| **性能** | 轻量级,性能开销小 | 相对较重 |
| **学习曲线** | 较平缓 | 相对陡峭 |
| **社区活跃度** | 较新,社区较小 | 成熟,社区活跃 |
### 2. Garfish vs single-spa
#### 相似点
- 都提供微前端基础能力
- 都支持生命周期管理
- 都支持框架无关
#### 差异点
| 特性 | Garfish | single-spa |
|------|---------|------------|
| **易用性** | 开箱即用,配置简单 | 需要手动配置,复杂度高 |
| **沙箱隔离** | 内置多种沙箱机制 | 需要自行实现 |
| **样式隔离** | 内置样式隔离方案 | 需要自行实现 |
| **路由管理** | 内置路由管理 | 需要自行实现 |
| **文档完善度** | 文档相对简洁 | 文档详细但复杂 |
### 3. Garfish vs Module Federation
#### 相似点
- 都支持模块共享
- 都支持独立部署
- 都支持技术栈无关
#### 差异点
| 特性 | Garfish | Module Federation |
|------|---------|-------------------|
| **实现方式** | 运行时加载 | 构建时模块共享 |
| **依赖共享** | 需要手动管理 | 自动共享依赖 |
| **版本管理** | 需要手动处理 | 自动处理版本冲突 |
| **构建复杂度** | 相对简单 | 需要配置 Webpack |
| **适用场景** | 完全独立的应用 | 模块级别的共享 |
## 选择建议
### 选择 Garfish 的场景
- 需要轻量级的微前端解决方案
- 需要多种沙箱隔离机制
- 需要内置的路由和样式隔离
- 团队对微前端有一定了解
- 项目规模中等,不需要过度复杂的方案
### 选择 qiankun 的场景
- 需要成熟的微前端解决方案
- 需要丰富的社区支持和文档
- 团队对 qiankun 有经验
- 项目规模较大,需要稳定可靠的方案
### 选择 single-spa 的场景
- 需要高度定制的微前端方案
- 团队对微前端原理有深入了解
- 需要最大的灵活性
- 愿意投入时间进行配置和优化
### 选择 Module Federation 的场景
- 需要模块级别的共享
- 使用 Webpack 5
- 需要自动依赖管理
- 团队熟悉 Webpack 配置
- 需要细粒度的代码复用
## 迁移策略
### 从其他框架迁移到 Garfish
1. **评估现有架构**:分析当前微前端实现
2. **逐步迁移**:先迁移部分子应用
3. **保持兼容**:确保新旧方案共存
4. **测试验证**:全面测试迁移效果
5. **优化调整**:根据实际情况优化配置
## 最佳实践
### 1. 技术选型原则
- 根据团队技术栈选择
- 考虑项目规模和复杂度
- 评估维护成本
- 考虑社区支持和生态
### 2. 混合使用
- 可以结合多个框架的优势
- 根据不同场景选择不同方案
- 保持架构的一致性
### 3. 持续评估
- 定期评估框架的适用性
- 关注框架的更新和发展
- 准备备选方案
通过合理选择微前端框架,可以更好地满足项目需求并提升开发效率。
前端 · 2月21日 16:02
Garfish 的路由管理系统如何工作,如何实现主子应用的路由协同?Garfish 的路由管理系统是微前端架构的核心组件之一,负责协调主应用和子应用之间的路由关系。
## 路由管理核心功能
### 1. 路由注册
- **子应用路由配置**:每个子应用需要声明自己的路由规则
- **路由前缀**:为子应用设置独立的路由前缀,避免冲突
- **路由映射**:建立 URL 与子应用的映射关系
- **示例配置**:
```javascript
Garfish.run({
apps: [
{
name: 'app1',
entry: '//localhost:3001',
activeWhen: '/app1',
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
}
]
});
```
### 2. 路由监听与分发
- **监听 URL 变化**:自动监听浏览器路由变化
- **路由匹配**:根据 URL 匹配对应的子应用
- **路由分发**:将路由信息传递给对应的子应用
- **支持多种路由模式**:History API、Hash 模式
### 3. 路由同步
- **主子应用同步**:保持主应用和子应用的路由状态一致
- **跨应用导航**:支持从子应用导航到其他子应用
- **路由参数传递**:在应用切换时传递路由参数
- **面包屑导航**:支持跨应用的面包屑导航
### 4. 路由守卫
- **全局前置守卫**:在路由切换前执行逻辑
- **应用级守卫**:针对特定子应用的路由守卫
- **权限控制**:基于路由的权限验证
- **示例**:
```javascript
Garfish.router.beforeEach((to, from) => {
if (to.path === '/admin' && !hasPermission()) {
return '/login';
}
});
```
## 路由隔离策略
### 1. 路由前缀隔离
- 每个子应用拥有独立的路由前缀
- 避免路由冲突
- 便于路由管理和维护
### 2. 路由作用域
- 子应用只能访问自己的路由空间
- 防止子应用间的路由干扰
- 确保路由的独立性和安全性
### 3. 路由降级
- 在子应用加载失败时提供降级路由
- 显示错误页面或重定向到安全页面
- 提升用户体验
## 最佳实践
- **统一路由规范**:制定统一的路由命名和结构规范
- **路由懒加载**:结合路由懒加载优化性能
- **路由缓存**:合理使用路由缓存减少重复加载
- **错误处理**:完善路由错误处理机制
- **SEO 优化**:确保路由配置支持 SEO
通过有效的路由管理,可以实现子应用间的无缝切换和协同工作。
前端 · 2月21日 16:01
Garfish 的错误处理和降级机制是如何工作的,如何保证应用的稳定性?Garfish 的错误处理和降级机制确保微前端应用在出现异常时能够优雅降级,提供良好的用户体验。
## 错误处理机制
### 1. 子应用加载错误
- **错误类型**:网络错误、资源加载失败、脚本执行错误
- **处理策略**:
- 自动重试机制
- 提供错误提示
- 加载备用版本
- **配置示例**:
```javascript
{
name: 'app1',
entry: '//localhost:3001',
errorBoundary: {
onError: (error) => {
console.error('子应用加载失败:', error);
// 上报错误日志
reportError(error);
},
fallback: () => {
// 显示降级页面
return <ErrorPage message="应用加载失败,请稍后重试" />;
}
}
}
```
### 2. 运行时错误
- **错误类型**:JavaScript 运行时错误、组件渲染错误
- **处理策略**:
- 使用错误边界捕获
- 隔离错误影响范围
- 提供错误恢复机制
- **示例**:
```javascript
// React 错误边界
class ErrorBoundary extends React.Component {
componentDidCatch(error, errorInfo) {
// 捕获子应用错误
Garfish.emit('app-error', { error, errorInfo });
}
render() {
if (this.state.hasError) {
return <ErrorFallback />;
}
return this.props.children;
}
}
```
### 3. 生命周期错误
- **错误类型**:bootstrap、mount、unmount 执行失败
- **处理策略**:
- 捕获生命周期函数错误
- 确保资源正确清理
- 提供错误回调
- **示例**:
```javascript
export async function mount(container) {
try {
ReactDOM.render(<App />, container);
} catch (error) {
// 清理已渲染的内容
container.innerHTML = '';
throw error;
}
}
```
## 降级策略
### 1. 应用级降级
- **策略**:当子应用加载失败时,显示降级页面
- **实现方式**:
- 配置 fallback 组件
- 显示静态内容
- 提供重试按钮
- **示例**:
```javascript
{
name: 'app1',
entry: '//localhost:3001',
fallback: {
component: () => (
<div className="fallback">
<h3>应用暂时不可用</h3>
<button onClick={() => window.location.reload()}>
重新加载
</button>
</div>
)
}
}
```
### 2. 功能级降级
- **策略**:当部分功能失败时,降级到简化版本
- **实现方式**:
- 检测功能可用性
- 提供替代方案
- 逐步恢复功能
- **示例**:
```javascript
// 检测 API 可用性
async function checkApiAvailability() {
try {
await fetch('/api/health');
return true;
} catch {
return false;
}
}
// 根据可用性选择实现
const Component = apiAvailable ? FullFeature : SimplifiedFeature;
```
### 3. 性能降级
- **策略**:在性能不足时降低功能复杂度
- **实现方式**:
- 禁用动画效果
- 减少数据加载量
- 使用简化版组件
- **示例**:
```javascript
// 检测设备性能
const isLowPerformance = /low-performance/.test(navigator.userAgent);
// 根据性能选择组件
const AnimationComponent = isLowPerformance ? SimpleAnimation : FullAnimation;
```
## 错误监控与日志
### 1. 错误收集
- 收集所有子应用的错误信息
- 记录错误上下文
- 统一错误格式
### 2. 错误上报
- 实时上报错误到监控系统
- 批量上报减少网络请求
- 支持离线缓存
### 3. 错误分析
- 统计错误频率和类型
- 分析错误影响范围
- 生成错误报告
## 最佳实践
### 1. 错误预防
- 完善的单元测试和集成测试
- 代码审查和质量检查
- 预发布环境验证
### 2. 错误恢复
- 提供自动重试机制
- 实现手动恢复选项
- 保存用户状态避免数据丢失
### 3. 用户体验
- 友好的错误提示
- 清晰的错误说明
- 提供解决方案建议
### 4. 监控告警
- 设置错误阈值告警
- 实时监控错误率
- 快速响应严重错误
通过完善的错误处理和降级机制,可以确保微前端应用的稳定性和可靠性。
前端 · 2月21日 16:01
什么是 Garfish 微前端框架,它的核心特点和应用场景是什么?Garfish 是一个轻量级的微前端框架,主要用于解决大型前端项目的复杂性和维护性问题。它通过沙箱技术隔离不同子应用的运行环境,确保各个微应用之间的独立性和安全性。
核心特点包括:
1. **沙箱隔离**:使用 JavaScript 沙箱隔离不同子应用的全局变量和副作用,防止应用间相互干扰
2. **多种加载方式**:支持异步加载和预加载,优化整体性能和用户体验
3. **框架无关**:兼容 React、Vue、Angular 等主流前端框架,允许不同技术栈的应用共存
4. **生命周期管理**:提供完整的生命周期钩子,包括 bootstrap、mount、unmount 等
5. **路由管理**:内置路由系统,支持子应用的路由注册和切换
6. **样式隔离**:通过 CSS 作用域或其他机制确保子应用样式不冲突
Garfish 的优势在于:
- 轻量级设计,性能开销小
- 灵活的架构,易于集成到现有项目
- 完善的开发工具和调试支持
- 活跃的社区和持续的更新维护
使用场景包括企业级后台管理系统、电商平台、多团队协作的大型项目等。
前端 · 2月21日 16:01
Garfish 支持哪些子应用加载方式,如何根据场景选择合适的加载策略?Garfish 支持多种子应用加载方式,以适应不同的场景和性能需求。
## 加载方式
### 1. 同步加载
- **特点**:在主应用启动时立即加载子应用
- **适用场景**:核心子应用、必须立即使用的功能
- **优势**:首次访问速度快,无需等待
- **劣势**:主应用启动时间长,资源占用大
- **配置示例**:
```javascript
{
name: 'core-app',
entry: '//localhost:3001',
activeWhen: '/core',
loadMode: 'sync'
}
```
### 2. 异步加载
- **特点**:在需要时才加载子应用
- **适用场景**:非核心功能、按需加载的模块
- **优势**:减少初始加载时间,节省资源
- **劣势**:首次访问子应用时需要等待加载
- **配置示例**:
```javascript
{
name: 'feature-app',
entry: '//localhost:3002',
activeWhen: '/feature',
loadMode: 'async'
}
```
### 3. 预加载
- **特点**:在主应用空闲时提前加载子应用
- **适用场景**:可能被访问的子应用、提升用户体验
- **优势**:访问时无需等待,用户体验好
- **劣势**:占用网络和内存资源
- **配置示例**:
```javascript
{
name: 'dashboard',
entry: '//localhost:3003',
activeWhen: '/dashboard',
loadMode: 'preload',
preloadDelay: 2000 // 延迟2秒后预加载
}
```
### 4. 懒加载
- **特点**:首次访问时才开始加载
- **适用场景**:低频使用的功能、大型模块
- **优势**:最大化节省资源
- **劣势**:首次访问有延迟
- **配置示例**:
```javascript
{
name: 'settings',
entry: '//localhost:3004',
activeWhen: '/settings',
loadMode: 'lazy'
}
```
## 加载策略选择
### 基于业务重要性
- **核心业务**:同步加载或预加载
- **次要业务**:异步加载
- **辅助功能**:懒加载
### 基于访问频率
- **高频访问**:预加载或同步加载
- **中频访问**:异步加载
- **低频访问**:懒加载
### 基于资源大小
- **小型应用**:同步加载
- **中型应用**:异步加载
- **大型应用**:懒加载
## 性能优化技巧
### 1. 资源压缩
- 压缩 JavaScript 和 CSS 文件
- 使用 Webpack 的代码分割功能
- 启用 Gzip 或 Brotli 压缩
### 2. 缓存策略
- 合理设置 HTTP 缓存头
- 使用 Service Worker 缓存资源
- 实现子应用缓存机制
### 3. 并行加载
- 支持多个子应用并行加载
- 使用 CDN 加速资源加载
- 优化网络请求
### 4. 加载优先级
- 设置子应用的加载优先级
- 优先加载关键资源
- 延迟加载非关键资源
## 监控与调试
### 加载状态监控
- 监听子应用加载事件
- 记录加载时间和成功率
- 统计加载失败原因
### 错误处理
- 实现加载失败的降级方案
- 提供友好的错误提示
- 自动重试机制
合理选择加载策略可以显著提升微前端应用的性能和用户体验。
前端 · 2月21日 16:01
Garfish 的生命周期管理包括哪些钩子函数,它们的作用和执行顺序是什么?Garfish 提供了完整的生命周期管理机制,确保子应用的加载、挂载、更新和卸载过程可控且可预测。
## 生命周期钩子
### 1. bootstrap(初始化)
- **触发时机**:子应用首次加载时
- **作用**:执行子应用的初始化逻辑,如配置加载、依赖注入
- **只执行一次**:在子应用生命周期中只调用一次
- **示例**:
```javascript
export function bootstrap() {
console.log('子应用初始化');
return Promise.resolve();
}
```
### 2. mount(挂载)
- **触发时机**:子应用需要渲染到页面时
- **作用**:将子应用渲染到指定的容器中
- **可多次调用**:每次路由切换到该子应用时都会触发
- **示例**:
```javascript
export function mount(container) {
ReactDOM.render(<App />, container);
return Promise.resolve();
}
```
### 3. unmount(卸载)
- **触发时机**:子应用需要从页面移除时
- **作用**:清理子应用的 DOM、事件监听、定时器等资源
- **必须执行**:确保完全清理,避免内存泄漏
- **示例**:
```javascript
export function unmount(container) {
ReactDOM.unmountComponentAtNode(container);
return Promise.resolve();
}
```
### 4. update(更新)
- **触发时机**:子应用需要更新时(可选)
- **作用**:处理子应用的更新逻辑
- **非必需**:不是所有子应用都需要实现
- **示例**:
```javascript
export function update(props) {
// 处理属性更新
return Promise.resolve();
}
```
## 生命周期流程
1. **首次加载**:bootstrap → mount
2. **路由切换**:unmount(旧应用)→ mount(新应用)
3. **重新激活**:直接调用 mount(不重复 bootstrap)
4. **完全卸载**:unmount + 清理所有资源
## 最佳实践
- **异步处理**:所有生命周期函数都应返回 Promise
- **错误处理**:在生命周期中添加错误捕获逻辑
- **资源清理**:在 unmount 中彻底清理所有副作用
- **性能优化**:避免在 mount 中执行耗时操作
- **状态管理**:合理管理子应用的状态,避免重复初始化
通过合理使用生命周期钩子,可以确保子应用的稳定运行和资源的有效管理。
前端 · 2月21日 16:01
Garfish 的沙箱隔离机制是如何实现的,有哪些隔离策略?Garfish 的沙箱隔离机制主要通过以下方式实现:
## 1. 快照沙箱(Snapshot Sandbox)
- 在子应用加载前,对当前全局环境(window 对象)进行快照
- 记录所有全局变量和属性
- 子应用运行期间,允许修改全局变量
- 子应用卸载时,恢复到加载前的快照状态
## 2. 代理沙箱(Proxy Sandbox)
- 使用 ES6 Proxy 对 window 对象进行代理
- 拦截对全局变量的读取和写入操作
- 维护一个独立的沙箱环境,每个子应用有自己的全局变量副本
- 通过代理层隔离不同子应用的全局状态
## 3. 严格沙箱(Strict Sandbox)
- 结合快照和代理的优势
- 提供更严格的隔离机制
- 防止子应用间的全局变量污染
- 确保子应用卸载后完全清理副作用
## 隔离范围
- **全局变量隔离**:防止子应用间的变量冲突
- **事件监听器隔离**:自动清理子应用添加的事件监听
- **定时器隔离**:管理 setTimeout、setInterval 等定时器
- **样式隔离**:通过 CSS 作用域或 Shadow DOM 隔离样式
## 实现优势
- 性能开销小,不影响应用运行效率
- 支持动态加载和卸载子应用
- 兼容主流浏览器,无需 polyfill
- 提供降级方案,确保在不支持 Proxy 的环境中也能运行
沙箱机制确保了微前端架构下各个子应用的独立性和安全性,是实现微前端的关键技术之一。
前端 · 2月19日 17:45
Garfish 的样式隔离机制是如何实现的,有哪些常见的样式隔离方案?Garfish 的样式隔离机制确保不同子应用的样式不会相互干扰,是微前端架构中的重要组成部分。
## 样式隔离方案
### 1. CSS 作用域
- **原理**:为每个子应用的样式添加唯一前缀或后缀
- **实现方式**:
- 使用 PostCSS 插件自动添加作用域
- 通过 CSS Modules 实现局部作用域
- 使用 CSS-in-JS 方案(如 styled-components)
- **优势**:简单易用,兼容性好
- **劣势**:需要额外的构建配置
- **示例**:
```javascript
// PostCSS 配置
module.exports = {
plugins: [
require('postcss-selector-prefix')({
prefix: '[data-garfish-app="app1"]'
})
]
};
```
### 2. Shadow DOM
- **原理**:使用浏览器原生的 Shadow DOM 技术隔离样式
- **实现方式**:
- 将子应用挂载到 Shadow DOM 容器中
- 样式只在 Shadow DOM 内部生效
- 自动隔离全局样式
- **优势**:完全隔离,浏览器原生支持
- **劣势**:部分浏览器兼容性问题,事件冒泡处理复杂
- **示例**:
```javascript
// 创建 Shadow DOM 容器
const shadowRoot = container.attachShadow({ mode: 'open' });
// 将子应用挂载到 Shadow DOM
shadowRoot.appendChild(appElement);
```
### 3. 动态样式表管理
- **原理**:在子应用挂载时加载样式,卸载时移除样式
- **实现方式**:
- 动态创建和删除 `<style>` 标签
- 管理样式表的加载和卸载
- 避免样式残留
- **优势**:灵活控制,性能较好
- **劣势**:需要手动管理样式生命周期
- **示例**:
```javascript
// 动态加载样式
function loadStylesheet(url) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
return link;
}
// 卸载时移除样式
function unloadStylesheet(link) {
document.head.removeChild(link);
}
```
### 4. CSS 命名约定
- **原理**:通过命名规范避免样式冲突
- **实现方式**:
- 使用 BEM 命名规范
- 为每个子应用设置唯一的类名前缀
- 遵循统一的命名约定
- **优势**:无需额外工具,易于理解
- **劣势**:依赖开发者自觉,容易出错
- **示例**:
```css
/* 子应用 app1 的样式 */
.app1__header { }
.app1__button { }
.app1__button--primary { }
```
## 样式隔离配置
### Garfish 配置示例
```javascript
Garfish.run({
apps: [
{
name: 'app1',
entry: '//localhost:3001',
sandbox: {
strictIsolation: true,
styleIsolation: 'shadow-dom' // 或 'scoped-css'
}
}
]
});
```
## 最佳实践
### 1. 选择合适的隔离方案
- **简单项目**:CSS 作用域或命名约定
- **复杂项目**:Shadow DOM
- **混合场景**:结合多种方案
### 2. 全局样式处理
- 主应用提供全局基础样式
- 子应用避免使用全局选择器
- 使用 CSS 变量管理主题
### 3. 第三方库样式
- 使用作用域化版本
- 手动修改第三方库样式
- 考虑使用样式隔离方案
### 4. 性能优化
- 避免重复加载样式
- 使用样式压缩
- 合理使用 CSS 缓存
### 5. 开发体验
- 提供样式隔离的调试工具
- 支持热更新
- 提供样式冲突检测
## 常见问题解决
### 1. 样式不生效
- 检查样式隔离配置
- 确认样式加载顺序
- 检查选择器优先级
### 2. 样式冲突
- 使用更具体的选择器
- 调整样式隔离方案
- 检查全局样式影响
### 3. 性能问题
- 减少样式文件大小
- 优化样式加载策略
- 使用样式缓存
通过合理配置样式隔离机制,可以确保微前端应用的样式独立性和可维护性。
前端 · 2月19日 17:45