Template-system 之 加入状态管理:远程组件本地可测、宿主可控
Overview
实现了什么: CDN 远程 ESM + 宿主可插拔状态
-
远程组件:本地开发时能自己跑,不依赖宿主。用 mock context 或本地的轻量状态,
local模式就能自测功能。 -
宿主加载:生产环境下 external 掉
@ss/useCart等端口,由宿主通过 import map 注入真实 Redux 实现。这样远程组件在宿主环境下“自然”调用宿主的状态管理,像本地写的 hook 一样。
技术关键点
-
按领域拆分端口:
@ss/useCart、@ss/react-redux… 不搞一个大网关。这样远程只会下载自己用到的 proxy 文件,按需加载,缓存粒度也细。 -
proxy 转发:无论 React、React Redux、还是自定义 useCart,都通过 proxy 把“宿主全局注册实例”惰性转发出去,保证上下文一致。
-
import map 注入:让浏览器解析
@ss/useCart→/externals/useCart.mjs,在远程组件看来就是正常import { useCart } from '@ss/useCart',实现“解耦 + 替换”。 -
自测与宿主兼容:dev 阶段 alias 到 mock,prod 阶段 external 到 import map。保证“远程组件能单独测试,也能在宿主无缝使用”。
为什么很值得
-
独立性:远程组件不依赖宿主就能开发调试。
-
可复用性:宿主换状态管理实现(比如从 Redux → Zustand → Server Action),远程组件无需改动。
-
架构优雅: Port/Adapter 模式(领域端口 + 宿主适配),是大规模前端模块化里最常见的“best practice”。
-
未来扩展:不仅限于 useCart,你可以逐渐把 useAuth、useTheme 也抽成端口,形成一套“状态 DI(依赖注入)”机制。
核心思路
目标
远程组件在本地(template-system)能自测;在宿主环境里自动接入宿主的 Redux(或任意状态实现),而不改远程代码。
方法论:在“模块边界”做依赖注入(DI)。把状态能力抽象成端口(Port),例如 @ss/cart,远程只依赖端口;宿主在运行时通过 import map 把端口映射到自己的实现产物(ESM)。
1)Template-system(远程库)配置
开发(dev):用 Vite alias 指向本地 mock,远程组件可独立自测。
const getRR = () => { const rr = self.__REACT_REDUX__; if (!rr) throw new Error('[react-redux-proxy] Host react-redux not ready.'); return rr; }; export const useDispatch = (...a) => getRR().useDispatch(...a); export const useSelector = (...a) => getRR().useSelector(...a); export default new Proxy({}, { get(_t, p, r){ return Reflect.get(getRR(), p, r); }});
在 useCart.proxy.ts 里改为从端口取 hooks:
2.3 import map 映射端口 → 产物
<script type="importmap"> { "imports": { "react": "/vendor/react-19.1.0.js", "react-dom": "/vendor/react-dom-19.1.0.js", "react/jsx-runtime": "/vendor/react-jsx-runtime-19.1.0.js", "react-redux": "/vendor/react-redux.proxy.mjs", // 先window注入实例,然后mjs就能找到 "@ss/cart": "/externals/useCart.mjs" } } </script>
浏览器只在远程真正
import '@ss/cart'时下载/externals/useCart.mjs,按需加载。

浙公网安备 33010602011771号