RenderContext is a core class in the Esmx framework, responsible for managing the complete lifecycle of Server-Side Rendering (SSR). It provides a comprehensive API to handle rendering contexts, resource management, state synchronization, and other key tasks:
Type definition for Server-Side Rendering handler function.
type ServerRenderHandle = (rc: RenderContext) => Promise<void>;The Server-Side Rendering handler function is an async or sync function that receives a RenderContext instance as a parameter, used to handle Server-Side Rendering logic.
export default async (rc: RenderContext) => {
const app = createApp();
const html = await renderToString(app);
rc.html = html;
};
export const simple = async (rc: RenderContext) => {
rc.html = '<h1>Hello World</h1>';
};Type definition for resource file list collected during rendering process.
interface RenderFiles {
js: string[];
css: string[];
modulepreload: string[];
resources: string[];
}rc.files = {
js: [
'/assets/entry-client.js',
'/assets/vendor.js'
],
css: [
'/assets/main.css',
'/assets/vendor.css'
],
modulepreload: [
'/assets/Home.js',
'/assets/About.js'
],
resources: [
'/assets/logo.png',
'/assets/font.woff2'
]
};Defines the generation mode for importmap.
type ImportmapMode = 'inline' | 'js';inline: Embeds importmap content directly into HTML, suitable for:
js: Generates importmap content as an independent JS file, suitable for:
Rendering context class, responsible for resource management and HTML generation in the Server-Side Rendering (SSR) process.
Defines configuration options for rendering context.
interface RenderContextOptions {
base?: string
entryName?: string
params?: Record<string, any>
importmapMode?: ImportmapMode
}string''Base path for static resources.
string'default'Server-Side Rendering entry function name. Used to specify the entry function for Server-Side Rendering, utilized when a module exports multiple rendering functions.
export const mobile = async (rc: RenderContext) => {
};
export const desktop = async (rc: RenderContext) => {
};Record<string, any>{}Rendering parameters. Can pass parameters of any type to the rendering function, commonly used to pass request information (URL, query parameters, etc.).
const rc = await esmx.render({
params: {
url: req.url,
lang: 'zh-CN',
theme: 'dark'
}
});'inline' | 'js''inline'Import map generation mode:
inline: Embeds importmap content directly into HTMLjs: Generates importmap content as independent JS fileEsmxtrueReference to the Esmx instance. Used to access framework core functionality and configuration information.
string | nullnullRedirect address. When set, the server can perform HTTP redirects based on this value, commonly used in login verification, permission control, and other scenarios.
export default async (rc: RenderContext) => {
if (!isLoggedIn()) {
rc.redirect = '/login';
rc.status = 302;
return;
}
};
export default async (rc: RenderContext) => {
if (!hasPermission()) {
rc.redirect = '/403';
rc.status = 403;
return;
}
};number | nullnullHTTP response status code. Can set any valid HTTP status code, commonly used in error handling, redirects, and other scenarios.
export default async (rc: RenderContext) => {
const page = await findPage(rc.params.url);
if (!page) {
rc.status = 404;
return;
}
};
export default async (rc: RenderContext) => {
if (needMaintenance()) {
rc.redirect = '/maintenance';
rc.status = 307;
return;
}
};string''HTML content. Used to set and get the final generated HTML content, automatically handling base path placeholders when setting.
export default async (rc: RenderContext) => {
rc.html = `
<!DOCTYPE html>
<html>
<head>
${rc.preload()}
${rc.css()}
</head>
<body>
<div id="app">Hello World</div>
${rc.importmap()}
${rc.moduleEntry()}
${rc.modulePreload()}
</body>
</html>
`;
};
const rc = await esmx.render({
base: '/app',
params: { url: req.url }
});
stringtrue''Base path for static resources. All static resources (JS, CSS, images, etc.) will be loaded based on this path, supporting runtime dynamic configuration.
const rc = await esmx.render({
base: '/esmx',
params: { url: req.url }
});
const rc = await esmx.render({
base: '/cn',
params: { lang: 'zh-CN' }
});
const rc = await esmx.render({
base: '/app1',
params: { appId: 1 }
});stringtrue'default'Server-Side Rendering entry function name. Used to select which rendering function to use from entry.server.ts.
export default async (rc: RenderContext) => {
};
export const mobile = async (rc: RenderContext) => {
};
export const desktop = async (rc: RenderContext) => {
};
const rc = await esmx.render({
entryName: isMobile ? 'mobile' : 'desktop',
params: { url: req.url }
});Record<string, any>true{}Rendering parameters. Can pass and access parameters during the Server-Side Rendering process, commonly used to pass request information, page configuration, etc.
const rc = await esmx.render({
params: {
url: req.url,
lang: 'zh-CN'
}
});
const rc = await esmx.render({
params: {
theme: 'dark',
layout: 'sidebar'
}
});
const rc = await esmx.render({
params: {
apiBaseUrl: process.env.API_BASE_URL,
version: '1.0.0'
}
});Set<ImportMeta>Module dependency collection set. Automatically tracks and records module dependencies during component rendering, only collecting resources actually used in the current page rendering.
const renderToString = (app: any, context: { importMetaSet: Set<ImportMeta> }) => {
return '<div id="app">Hello World</div>';
};
const app = createApp();
const html = await renderToString(app, {
importMetaSet: rc.importMetaSet
});RenderFilesResource file list:
await rc.commit();
rc.html = `
<!DOCTYPE html>
<html>
<head>
${rc.preload()}
${rc.css()}
</head>
<body>
${html}
${rc.importmap()}
${rc.moduleEntry()}
${rc.modulePreload()}
</body>
</html>
`;'inline' | 'js''inline'Import map generation mode:
inline: Embeds importmap content directly into HTMLjs: Generates importmap content as an independent JS fileinput: any - Data to serializeoptions?: serialize.SerializeJSOptions - Serialization optionsstringSerializes a JavaScript object to string. Used to serialize state data during Server-Side Rendering, ensuring data can be safely embedded into HTML.
const state = {
user: { id: 1, name: 'Alice' },
timestamp: new Date()
};
rc.html = `
<script>
window.__INITIAL_STATE__ = ${rc.serialize(state)};
</script>
`;varName: string - Variable namedata: Record<string, any> - State datastringSerializes state data and injects it into HTML. Uses a safe serialization method to handle data, supporting complex data structures.
const userInfo = {
id: 1,
name: 'John',
roles: ['admin']
};
rc.html = `
<head>
${rc.state('__USER__', userInfo)}
</head>
`;Promise<void>Commits dependency collection and updates the resource list. Collects all used modules from importMetaSet, resolving specific resources for each module based on manifest files.
const html = await renderToString(app, {
importMetaSet: rc.importMetaSet
});
await rc.commit();stringGenerates resource preload tags. Used to preload CSS and JavaScript resources, supports priority configuration, and automatically handles base paths.
rc.html = `
<!DOCTYPE html>
<html>
<head>
${rc.preload()}
${rc.css()}
</head>
<body>
${html}
${rc.importmap()}
${rc.moduleEntry()}
${rc.modulePreload()}
</body>
</html>
`;stringGenerates CSS stylesheet tags. Injects collected CSS files, ensuring stylesheets load in the correct order.
rc.html = `
<head>
${rc.css()}
</head>
`;stringGenerates import map tags. Generates inline or external import maps based on the importmapMode configuration.
rc.html = `
<head>
${rc.importmap()}
</head>
`;stringGenerates client entry module tags. Injects the client entry module, must be executed after importmap.
rc.html = `
<body>
${html}
${rc.importmap()}
${rc.moduleEntry()}
</body>
`;stringGenerates module preload tags. Preloads collected ESM modules, optimizing first-screen loading performance.
rc.html = `
<body>
${html}
${rc.importmap()}
${rc.moduleEntry()}
${rc.modulePreload()}
</body>
`;