Esmx 模块链接实战:供给方、消费方、组合方三种角色如何协作?

📅 2026/8/16 14:59:44
Esmx 模块链接实战:供给方、消费方、组合方三种角色如何协作?
Esmx 模块链接实战供给方、消费方、组合方三种角色如何协作【免费下载链接】genesisNext-generation micro-frontend framework based on ESM, sandbox-free with zero runtime overhead, supporting multi-framework hybrid development项目地址: https://gitcode.com/gh_mirrors/genesis8/genesisEsmx 是一个基于 ESM 标准的下一代微前端框架以无沙箱、零运行时开销、支持多框架混合开发著称。而**模块链接Module Linking**正是它实现跨应用代码共享的核心能力多个独立构建的应用之间可以像使用本地模块一样安全地共享代码全程不引入任何额外的运行时库。本文用最小配置带你理解模块链接中的三种协作角色——供给方、消费方、组合方以及它们之间接线是如何被自动推导出来的。一图看懂多框架子应用如何组合成一个平台在动手之前先看 Esmx 官方示例 Hub 的最终效果一个页面里同时承载 Vue 2/3、React、Preact、Solid、Svelte、Lit 等 7 种框架、3 种打包工具构建的 15 个子应用全部通过一个 import map统一管理这正是模块链接三种角色协作的直观成果。单个子应用如 React 19 计数器则以独立微应用的形式运行在统一平台中互不干扰三种协作角色分别承担什么职责模块链接的协议事实全部写在package.json的一个esmx字段里恰好四个可选子字段字段含义entry框架入口client / server库模块可省略exports带逻辑名的子路径映射消费方永远看不到物理路径provides本模块为消费方再导出的第三方包列表uses你所消费的模块名列表数组顺序有意义三种角色覆盖所有工程场景而且每份声明都只是本地知识——你可以在对其他模块一无所知的情况下写出来。角色一供给方共享平台包供给方是提供共享能力的基座比如统一封装 UI、状态管理与公共依赖的shared包。它的exports暴露的是逻辑名而非物理路径provides则声明了它愿意为下游再导出的第三方包如vue、esmx/router{ name: shared, version: 3.2.1, esmx: { exports: { ./ui: ./src/ui/index.ts, ./store: { client: ./src/store.client.ts, server: ./src/store.server.ts } }, provides: [vue, esmx/router] } }消费方只需import shared/ui即使供给方重命名了源文件也不是破坏性变更。仓库中的 ssr-micro-shared/package.json 就是这样一个真实供给方示例。角色二消费方 供给方功能远程大多数业务模块身兼两职既消费共享平台的能力又向更上层的宿主提供自己的业务导出。比如购物车模块cart它uses了shared同时exports出自己的./widget{ name: cart, version: 1.8.0, dependencies: { shared: ^3.0.0 }, peerDependencies: { vue: ^3.4.0 }, esmx: { exports: { ./widget: ./src/cart-widget.ts }, uses: [shared] } }注意这里没有手写的 imports 映射也没有逐 specifier 的接线版本范围就放在 npm 本来就放的地方——dependencies并在构建时对照实际版本自动校验。角色三组合方宿主宿主是聚合一切的最终应用它只声明自己依赖了谁其余交给模块链接的传递规则{ name: host, version: 2.0.0, dependencies: { shared: ^3.0.0, cart: ^1.5.0 }, esmx: { uses: [shared, cart] } }uses是传递的如果cartusesshared那么 usescart的宿主会自动通过链条获得shared的供给。业务应用只声明一行对链条深度毫不知情。参考真实宿主 ssr-micro-hub/package.json它的uses列出了一长串子应用却没有任何手写接线。接线如何被推导两条规则取代所有手写映射模块链接的精髓在于零接线由两条规则完成合并规则supply(M) merge(supply(uses[0]), …, supply(uses[n]), M.provides)——后面的条目覆盖前面的模块自己的provides是隐含的最后一个元素。当两个模块供给同一个包时uses数组的顺序决定谁赢按从通用到具体排列具体层胜出。选举是逐 major 版本进行的共存的 major如 Vue 2 和 Vue 3是互相隔离的孤岛各有自己的赢家。查找规则打包器遍历你的代码时逐 specifier 判断——裸 specifier 出现在合并后的供给表里就外部化并接到赢家哪里都找不到则打包成自己的副本由逐模块的 import-map scope 自动隔离。因此单实例共享是固有的多版本共存也不需要额外词汇。这套逻辑在源码中有清晰实现module-link/config.ts 负责外部化与入口配置module-link/manifest-plugin.ts 构建包含exports与chunks的 manifest.json入口统一在 module-link/index.ts。用 esmx validate 免构建校验整张图改完声明后无需执行完整构建即可验证所有接线是否成立。esmx validate是整个解析过程的 dry run——覆盖挂载遍历、版本检查、供给合并、导出检查esmx validate # 人类可读报告 esmx validate --json # 机器可读信封适合 CI / Agent只有出现 error 级诊断才以非零码退出仅有警告则退出 0。完整诊断分类E_NOT_LINKED、E_VERSION、E_SCHEMA、W_MULTI_MAJOR等可查阅官方文档 module-linking.md 与核心实现 packages/core/src/module-config.ts。实战Vue 2 与 Vue 3 如何在同一平台共存多版本共存是模块链接最亮眼的场景。一个共享基座并排供给两个 major 的 Vue每个业务应用只声明自己的版本范围解析器自动把它们接到匹配的 major全程没有任何手写 imports共享基座sharedprovides: [vue, vue2, esmx/router]其中vue2通过 npm 别名npm:vue^2.7.0引入每个 major 是独立的选举分组Vue 3 应用声明peerDependencies: { vue: ^3.5.0 }uses: [shared]只导出自己的路由配置Vue 2 应用声明vue: npm:vue^2.7.0同样只写一行uses聚合宿主hostuses: [shared, vue2-app, vue3-app]每个子应用一行组合子应用的单一路口。构建好子应用后运行esmx validate --json即可确认整张依赖图能解析。模块链接 vs Module Federation有何不同对比项Esmx 模块链接Module Federation运行时原生 ESM Import MapsWebpack/Rspack 运行时容器开销零额外运行时Federation 运行时 共享作用域协商SSR一等公民SEO 友好需额外配置历史上较脆弱版本显式 provider单一所有者运行时共享作用域协商由于链接基于浏览器自身的模块系统没有沙箱、没有私有加载器同一份import在浏览器、SSR 与测试中都表现一致。想亲自体验克隆仓库后即可在本地跑起包含 15 个子应用的完整示例git clone https://gitcode.com/gh_mirrors/genesis8/genesis进入examples/micro-app目录观察ssr-micro-shared供给方、各框架子应用消费方 供给方与ssr-micro-hub组合方三者之间如何用最少的声明完成最复杂的协作。理解了这三种角色你就掌握了 Esmx 微前端架构的核心心智模型。【免费下载链接】genesisNext-generation micro-frontend framework based on ESM, sandbox-free with zero runtime overhead, supporting multi-framework hybrid development项目地址: https://gitcode.com/gh_mirrors/genesis8/genesis创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考