qiankun沙箱实现原理

前言

  Qiankun 设置沙箱(Sandbox)主要是为了实现子应用之间的隔离,防止子应用之间的全局变量污染和副作用。Qiankun 使用了多种技术手段来实现这一目标,包括但不限于 JavaScript 的 Proxy 对象、自定义的全局变量管理等。

Qiankun 沙箱实现原理

Qiankun 的沙箱实现主要通过以下几个步骤来完成:

1.全局变量隔离:

  • Qiankun 使用 Proxy 对象来拦截对全局变量的访问和修改。
  • 当子应用试图访问或修改全局变量时,Qiankun 会捕获这些操作,并在沙箱环境中进行处理。

2.DOM 操作隔离:

  • Qiankun 通过创建一个虚拟的 DOM 环境来隔离子应用的 DOM 操作。
  • 子应用的 DOM 操作会被映射到这个虚拟的 DOM 环境中,从而不影响主应用和其他子应用。

3.事件隔离:

  • Qiankun 会对子应用中发生的事件进行监听和管理,确保事件不会影响到全局范围。

具体实现细节

使用 Proxy 对象

  Qiankun 使用 Proxy 对象来拦截对全局变量的操作,从而实现全局变量的隔离。

const sandbox = {
  global: window,
};

const proxyHandler = {
  get(target, key) {
    // 拦截对全局变量的访问
    return Reflect.get(sandbox.global, key) || target[key];
  },
  set(target, key, value) {
    // 拦截对全局变量的修改
    sandbox.global[key] = value;
    return true;
  },
};

// 创建一个全局变量的代理对象
window = new Proxy(sandbox, proxyHandler);

2.DOM 操作隔离

  Qiankun 通过创建一个沙箱 DOM 环境来隔离子应用的 DOM 操作。

function createSandboxDOM() {
  const sandboxDiv = document.createElement('div');
  sandboxDiv.id = 'sandbox';
  document.body.appendChild(sandboxDiv);
  return sandboxDiv;
}

const sandboxDiv = createSandboxDOM();

// 将子应用的所有 DOM 操作映射到 sandboxDiv 中
document.body = sandboxDiv;

3.事件隔离

  Qiankun 会对子应用中的事件进行监听和管理,确保事件不会影响到全局范围。

function addEventListenerWrapper(type, listener) {
  const originalAddEventListener = window.addEventListener;
  window.addEventListener = function (eventType, cb) {
    originalAddEventListener(eventType, function (event) {
      // 检查事件是否来自子应用
      if (event.target && event.target.ownerDocument === sandboxDiv) {
        cb(event);
      }
    });
  };
}

addEventListenerWrapper('click', function (event) {
  console.log('子应用点击事件', event);
});

示例代码

  主应用配置

// main.js
import { init, MicroApp, router } from 'qiankun';

function createSandboxDOM() {
  const sandboxDiv = document.createElement('div');
  sandboxDiv.id = 'sandbox';
  document.body.appendChild(sandboxDiv);
  return sandboxDiv;
}

const sandboxDiv = createSandboxDOM();

init({
  apps: [
    new MicroApp({
      name: 'sub-app-1',
      entry: '//localhost:8001',
      container: sandboxDiv,
      activeRule: '/sub-app-1',
    }),
  ],
  router,
});

// 路由监听
router.onNavigate(({ location }) => {
  console.log('navigate to', location.pathname);
});

  子应用配置

// sub-app.js
if (window.__POWERED_BY_QIANKUN__) {
  // 当前环境是 Qiankun 环境
  window.__onGlobeEvent = function (event) {
    console.log('received event:', event);
  };

  // 创建沙箱环境
  const sandbox = {
    global: window,
  };

  const proxyHandler = {
    get(target, key) {
      return Reflect.get(sandbox.global, key) || target[key];
    },
    set(target, key, value) {
      sandbox.global[key] = value;
      return true;
    },
  };

  // 创建一个全局变量的代理对象
  window = new Proxy(sandbox, proxyHandler);
} else {
  // 非 Qiankun 环境下的普通应用
  // ...
}

总结

  Qiankun 通过使用 Proxy 对象来拦截全局变量的访问和修改,通过创建沙箱 DOM 环境来隔离子应用的 DOM 操作,并通过自定义的事件监听来管理子应用中的事件。这些措施共同实现了子应用之间的隔离,确保了主应用和子应用之间的互不干扰。通过这些技术手段,Qiankun 能够有效保障微前端架构的安全性和稳定性。

  




### qiankun 微前端框架工作原理 qiankun 是一种基于 single-spa 的微前端实现方案,其核心目标是通过模块化的方式将多个独立的前端应用集成到一个主应用中[^1]。以下是关于 qiankun 工作原理的关键点: #### 1. **主应用与子应用的关系** qianun 中存在两个主要概念:主应用(Master Application)和子应用(Sub Applications)。主应用负责管理子应用的加载、卸载以及生命周期调用。子应用则作为独立的应用程序运行于各自的上下文中。 主应用通过 `loadMicroApp` 方法动态加载子应用,并指定容器节点用于渲染子应用的内容[^2]。 ```javascript import { loadMicroApp } from 'qiankun'; const app = loadMicroApp({ name: 'app1', entry: '//localhost:7101', // 子应用入口地址 container: '#dynamicContainer', // 渲染容器的选择器 props: { someProp: 'someValue' } }); ``` #### 2. **沙箱机制** 为了防止不同子应用之间的全局变量冲突,qiankun 提供了一个隔离环境——沙箱(Sandbox)。沙箱的主要作用是对子应用中的全局对象(如 `window` 和 `document`)进行代理操作,从而避免污染其他子应用或主应用的全局状态[^3]。 当子应用被卸载时,沙箱会自动清理掉该子应用所引入的全局变量,确保不会影响后续加载的其他子应用。 #### 3. **生命周期钩子** 每个子应用都需要提供一组标准的生命周期函数来配合主应用完成初始化、挂载和卸载过程。这些生命周期包括但不限于以下三个阶段: - **bootstrap**: 初始化阶段,在此期间执行一些必要的准备工作。 - **mount**: 将子应用挂载至 DOM 容器内并启动业务逻辑。 - **unmount**: 卸载当前子应用实例及其关联资源。 下面是一个典型的 React 应用定义上述生命周期的例子[^3]: ```javascript // 导出生命周期方法 export async function bootstrap() { console.log('React application bootstrapped'); } export async function mount(props) { ReactDOM.render(<App />, document.getElementById('root')); } export async function unmount() { ReactDOM.unmountComponentAtNode(document.getElementById('root')); } ``` #### 4. **跨域支持** 由于实际项目中可能涉及多域名下的服务端部署情况,因此 qiankun 支持跨域场景下正常加载远程子应用的功能。这通常依赖 Webpack 插件或者类似的工具链配置来处理静态文件路径映射等问题[^2]。 --- ### 总结 综上所述,qiankun 利用了现代 JavaScript 技术栈实现了高效的微前端架构设计模式。它不仅简化了复杂系统的拆分维护难度,还提供了强大的功能扩展能力以满足企业级需求。 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值