Skip to content

微前端中的应用隔离是什么,一般是怎么实现的?

参考答案:

应用隔离问题主要分为主应用和微应用,微应用和微应用之间的JavaScript执行环境隔离,CSS样式隔离。

CSS隔离

当主应用和微应用同屏渲染时,就可能会有一些样式会相互污染,如果要彻底隔离CSS污染,可以采用CSS Module 或者命名空间的方式,给每个微应用模块以特定前缀,即可保证不会互相干扰,可以采用webpack的postcss插件,在打包时添加特定的前缀。

而对于微应用与微应用之间的CSS隔离就非常简单,在每次应用加载时,将该应用所有的link和style 内容进行标记。在应用卸载后,同步卸载页面上对应的link和style即可。

JavaScript隔离

每当微应用的JavaScript被加载并运行时,它的核心实际上是对全局对象Window的修改以及一些全局事件的改变,例如jQuery这个js运行后,会在Window上挂载一个window.$对象,对于其他库React,Vue也不例外。

为此,需要在加载和卸载每个微应用的同时,尽可能消除这种冲突和影响,最普遍的做法是采用沙箱机制(SandBox)。

沙箱机制的核心是让局部的JavaScript运行时,对外部对象的访问和修改处在可控的范围内,即无论内部怎么运行,都不会影响外部的对象。通常在Node.js端可以采用vm模块,而对于浏览器,则需要结合with关键字和window.Proxy对象来实现浏览器端的沙箱。

题目要点:

在微前端架构中,应用隔离是指在同一个页面中运行多个微前端应用时,确保这些应用之间不会互相干扰。应用隔离的目标是使得各个微前端应用可以独立开发、部署和运行,同时避免它们之间的冲突,例如样式冲突、JavaScript 变量污染等。

实现应用隔离的常见方法

  1. JavaScript 命名空间隔离

    • 作用:通过将应用的 JavaScript 代码封装在特定的命名空间中,避免全局变量污染。
    • 实现:使用立即执行函数表达式(IIFE)、模块化(如 ES6 模块、CommonJS)来限制作用域。
    javascript
    (function() {
      // 微前端应用代码
      const app = {};
      window.appNamespace = app;
    })();
  2. CSS 样式隔离

    • 作用:防止不同应用的 CSS 样式互相干扰。
    • 实现
      • CSS 模块化:使用 CSS 模块化工具(如 CSS Modules、Styled Components)来隔离样式。
      • CSS-in-JS:使用 JavaScript 中的 CSS(如 styled-components)来封装组件样式。
      • Scoped CSS:在 Vue 等框架中使用 scoped 属性,确保样式只影响当前组件。
      • CSS 前缀:使用工具(如 PostCSS)自动添加唯一前缀。
    css
    .app1-button {
      background-color: blue;
    }
  3. iframe 隔离

    • 作用:将应用嵌套在 iframe 中,完全隔离应用之间的 JavaScript 和 CSS。
    • 实现:每个微前端应用在不同的 iframe 中运行,从而确保它们的环境是完全独立的。
    html
    <iframe src="app1.html"></iframe>
  4. Web Components

    • 作用:通过 Web Components 封装应用,使其具有独立的 DOM 和样式。
    • 实现:使用自定义元素、Shadow DOM 和 HTML 模板来封装组件。
    javascript
    class MyComponent extends HTMLElement {
      constructor() {
        super();
        const shadow = this.attachShadow({ mode: 'open' });
        shadow.innerHTML = `<p>Hello, Shadow DOM!</p>`;
      }
    }
    customElements.define('my-component', MyComponent);
  5. 动态脚本加载

    • 作用:通过动态加载 JavaScript 代码和样式,避免在全局环境中存在不必要的冲突。
    • 实现:使用 JavaScript 的 import()、动态加载 CSS 文件等方式来加载应用。
    javascript
    import('app1').then(module => {
      module.init();
    });
  6. 应用容器与挂载点

    • 作用:在主应用中创建挂载点(DOM 节点),微前端应用在这些挂载点上运行,确保彼此隔离。
    • 实现:主应用在不同的挂载点上渲染微前端应用。
    html
    <div id="app1-container"></div>
    <div id="app2-container"></div>

总结

  • 应用隔离 确保微前端应用之间不会互相干扰,使得各个应用可以独立开发和运行。
  • 常见实现方法 包括 JavaScript 命名空间、CSS 样式隔离、iframe、Web Components、动态脚本加载和应用容器与挂载点。