样式
Esmx 把 CSS 当作联邦一等资源 —— 每个远程自己打包样式,在 manifest 里
声明,host 渲染时为每个触达的 chunk 注入 <link rel="stylesheet">。你写的
就是标准的 import './x.css',没有 Esmx 专有 API。
编写
在任意远程,从 TypeScript 或框架入口导入 CSS,语法和你 bundler 一直熟悉的 完全一致:
或在 Vue/React/Svelte 组件里:
没有 useStyles() hook,没有 injectGlobalStyles() 工具函数,没有特殊文件
命名约定。CSS 的 import 语句本身就是合约的触发点。
Esmx 替你做的事
每个远程的 bundler(Rspack / Rsbuild / Vite)把 CSS 导入提取为真实
.css 文件,远程的 manifest.json 按 chunk 列出来:
当 host SSR 渲染一个触达 my-remote chunk 的页面时,RenderContext
收集 chunk 的 CSS URL,rc.css() emit:
…前面还配一份 <link rel="preload" as="style">,让浏览器在 HTML 还没解析完
就开始下载样式表。零 FOUC。
在多个远程之间共享样式
每个远程拥有自己的 CSS,共享设计系统的规范做法是把它放进所有远程都 会加载的那个联邦依赖。常见模式:
每个消费端的远程都会从 shared-host import 些东西(layout、router 上下文、
…)。共享 chunk 的 CSS 随它一起走 federation manifest,host 自动 emit
<link> —— 消费端不需要自己 import 共享 CSS。
共享 CSS 只存一份。每个远程仍写自己的框架原生组件,但消费同一套 class
名称(.btn, .card, …)和同一套 CSS 变量。
内部机制
三个官方 bundler 集成(@esmx/rspack、@esmx/rsbuild、@esmx/vite)
对第 2 步的实现完全一致 —— chunks[*].css[] 是 manifest 合约的一部分,
不是某个 bundler 的方言。
常见问题
dev 模式工作吗?
工作。dev manifest 在重新构建时更新,host 走同一条 <link> 注入路径,
不需要你额外为 HMR 处理 CSS。
CSS Modules / Tailwind / PostCSS / Sass 怎么办?
预处理由各 bundler 自己负责。Esmx 只关心最终落在 manifest 中的 .css
URL。你的 app.module.css、@apply、scss 都按 bundler 文档使用即可。
能直接 import 另一个远程的 CSS 吗?
不该需要 —— 见"共享样式"那一节。如果你硬要这么做,library 模式下的
bundler 对 workspace-dep CSS 处理可能不一致。让产出 CSS 的远程负责
自己的样式。
Subresource Integrity (SRI)?
生产模式下每个 emit 的 CSS chunk 都有 sha384-… 完整性哈希,带到
<link rel="stylesheet" integrity="…" crossorigin> 属性里。浏览器拒绝
应用被篡改的样式表。
参考
- Render Context —
rc.css()/rc.preload() - 每个 bundler 的 manifest 都含上文的
chunks[*].css[]字段。