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 配置示例
javascriptGarfish.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. 性能问题
- 减少样式文件大小
- 优化样式加载策略
- 使用样式缓存
通过合理配置样式隔离机制,可以确保微前端应用的样式独立性和可维护性。