Skip to content
目录

02 · Monorepo 包职责与数据流

包拓扑(依赖方向)

来自仓库根目录 AGENTS.md 的归纳:

qiankun(门面)
├── @qiankunjs/loader
│   ├── @qiankunjs/sandbox
│   └── @qiankunjs/shared
├── @qiankunjs/sandbox
│   └── @qiankunjs/shared
└── @qiankunjs/shared

设计原因:把「会频繁迭代、边界清晰」的能力拆包,便于单独测试、按需引用(例如仅研究 loader 时不必拉满 qiankun 的 single-spa 胶水层)。

各包职责速查

主要职责
@qiankunjs/sharedtranspileScript / transpileLink、三层 fetch 装饰(缓存/重试/非 2xx 抛错)、moduleResolver(依赖图 + semver)、Deferred 与 defer 脚本队列工具
@qiankunjs/sandboxStandardSandbox(Membrane + Compartment)、createSandboxContainer(mount/unmount 时 patch document 等)、各类 patcher 的 free() 清理
@qiankunjs/loaderloadEntry:fetch 流 → TagTransformStreamWritableDOMStream(fork writable-dom)
qiankunregisterMicroApps / start / loadMicroApploadApp 编排、addons(如 runtimePublicPath)、与 single-spa 对齐的 parcel 配置

loadApp 中的横向切面

loadApp 在创建沙箱后,将 同一套 enhancedFetchnodeTransformer 注入 loader:

53:55:packages/qiankun/src/core/loadApp.ts
const enhancedFetch = makeFetchCacheable(makeFetchRetryable(makeFetchThrowable(fetch)));
89:95:packages/qiankun/src/core/loadApp.ts
const containerOpts: LoaderOpts = {
    fetch: enhancedFetch,
    sandbox: sandboxInstance,
    nodeTransformer,
    ...restConfiguration,
  };
  const lifecyclesPromise = loadEntry<MicroAppLifeCycles>(entry, microAppDOMContainer, containerOpts);

原因:子应用所有「按 URL 拉脚本/样式」的路径尽量走同一 fetch 栈,从而共享 LRU 缓存、重试策略与错误语义,避免沙箱内 fetch 与 loader 入口 fetch 行为不一致。

默认 nodeTransformer 与模块解析

默认实现把 moduleResolver 绑到当前子应用容器 + document.head(主应用通常把依赖图 script 放在 head):

41:44:packages/qiankun/src/core/loadApp.ts
const defaultNodeTransformer: AppConfiguration['nodeTransformer'] = (node, opts) => {
    const moduleResolver = (url: string) => defaultModuleResolver(url, microAppDOMContainer, document.head);
    return transpileAssets(node, entry, { ...opts, moduleResolver });
  };

依据:依赖共享需要同时读取子应用主应用script[type=dependencymap] JSON,再在 semver 约束下把子应用的 URL 映射到主应用已加载的同名依赖 URL(见 packages/shared/src/module-resolver/index.ts)。

下一节

03-流式Loader与Head虚拟化.md

MIT License.