RenderContext 负责服务端渲染(SSR)过程中的资源管理与 HTML 生成,提供模块依赖收集与资源注入顺序约束。
通过 esmx.render() 获取实例:
async server(esmx) {
const server = http.createServer((req, res) => {
esmx.middleware(req, res, async () => {
const rc = await esmx.render({
params: {
url: req.url
}
});
res.end(rc.html);
});
});
}RenderContext 在组件渲染过程中收集模块与资源依赖,避免预加载所有资源。
importMetaSet 精确记录每个组件的模块依赖关系commit() 方法统一处理所有收集到的资源RenderContext 提供了多个方法来注入不同类型的资源,每个方法都经过精心设计以优化资源加载性能:
preload():预加载 CSS 和 JS 资源,支持优先级配置css():注入首屏样式表,支持关键 CSS 提取importmap():注入模块导入映射(Import Maps),支持动态路径解析moduleEntry():注入客户端入口模块,支持多入口配置modulePreload():预加载模块依赖,支持按需加载策略RenderContext 严格控制资源注入顺序,这种顺序设计是基于浏览器的工作原理和性能优化考虑:
head 部分:
preload():预加载 CSS 和 JS 资源,让浏览器尽早发现并开始加载这些资源css():注入首屏样式表,确保页面样式在内容渲染时就位body 部分:
importmap():注入模块导入映射,定义 ESM 模块的路径解析规则moduleEntry():注入客户端入口模块,必须在 importmap 之后执行modulePreload():预加载模块依赖,必须在 importmap 之后执行一个典型流程如下:
export default async (rc: RenderContext) => {
const app = createApp();
const html = await renderToString(app, {
importMetaSet: rc.importMetaSet
});
await rc.commit();
rc.html = `
<!DOCTYPE html>
<html>
<head>
${rc.preload()}
${rc.css()}
</head>
<body>
${html}
${rc.importmap()}
${rc.moduleEntry()}
${rc.modulePreload()}
</body>
</html>
`;
};RenderContext 提供了一个灵活的动态基础路径配置机制,支持在运行时动态设置静态资源的基础路径:
const rc = await esmx.render({
base: '/esmx',
params: {
url: req.url
}
});这种机制特别适用于以下场景:
多语言站点部署
主域名.com → 默认语言
主域名.com/cn/ → 中文站点
主域名.com/en/ → 英文站点微前端应用
RenderContext 提供了两种导入映射(Import Maps)模式:
Inline 模式(默认)
JS 模式
可以通过配置选择合适的模式:
const rc = await esmx.render({
importmapMode: 'js',
params: {
url: req.url
}
});RenderContext 支持通过 entryName 配置来指定服务端渲染的入口函数:
const rc = await esmx.render({
entryName: 'mobile',
params: {
url: req.url
}
});这种机制特别适用于以下场景:
// 移动端入口函数
export const mobile = async (rc: RenderContext) => {};
export const desktop = async (rc: RenderContext) => {};A/B 测试
特殊渲染需求
获取 RenderContext 实例
esmx.render() 方法获取实例依赖收集
importMetaSet.add(import.meta)commit() 方法资源注入
性能优化