RSCs Pipeline (generate-static-rscs.js)
Examine how Dinou serializes all application routes into React Server Component payloads in bulk during the production build.
Key File Location: ./dinou/core/generate-static-rscs.js💡 Overview
During the production server startup phase, we need to serialize the Server Components element trees of all crawled routes. The generate-static-rscs.js module manages this batch process, rendering routes to rsc.rsc payloads inside dist2/.
📊 Pipeline Flow
The flowchart below shows how routes are processed through the bulk serialization pipeline:
🔄 Differences: Bulk vs. Single Route Compilation
Dinou has two modules for generating RSC payloads: generate-static-rscs.js (for batch generation at startup) and generate-static-rsc.js (for single routes during active traffic). They operate differently to optimize speed and prevent downtime:
| Feature | Bulk Pipeline (generate-static-rscs.js) | Single Route Compiler (generate-static-rsc.js) |
|---|---|---|
| When does it run? | Runs once in the background when the production server starts up. | Runs on-demand when a user visits a page (ISR / ISG). |
| How does it write files? | Direct Writes: Writes directly to the final rsc.rsc file path. Safe because no public traffic is hitting the server yet during startup. | Double-Buffered: Writes to a temporary .tmp file first, then renames it atomically to prevent serving a half-written file to an active user. |
| Manifest File Reads | Reads the react-client-manifest.json once at the start and reuses it for all routes. Highly efficient for batching. | Reads the manifest from disk on every single execution to get the latest client component mappings. |
⚙️ Complete Code Walkthrough
Below is the full code of generate-static-rscs.js:
const fs = require("fs");
const path = require("path");
const { PassThrough } = require("stream");
const url = require("url");
const getJSX = require("./get-jsx.js");
const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
const { renderToPipeableStream } = isWebpack
? require("react-server-dom-webpack/server")
: require("@roggc/react-server-dom-esm/server");
const { requestStorage } = require("./request-context.js");
const OUT_DIR = path.resolve("dist2");
async function generateStaticRSCs(routes) {
// 1. Read Client Manifest to map dynamic Client components correctly
const manifest = JSON.parse(
fs.readFileSync(
path.resolve(
isWebpack
? "dist3/react-client-manifest.json"
: "react_client_manifest/react-client-manifest.json"
),
"utf8"
)
);
// 2. Loop through all crawled paths
for (const route of routes) {
const reqPath = route.endsWith("/") ? route : route + "/";
const payloadPath = path.join(OUT_DIR, reqPath, "rsc.rsc");
// 3. Inject Mock Request and Response Objects
const mockRes = {
_statusCode: 200,
_headers: {},
_cookies: [],
cookie(name, value, options) {
this._cookies.push({ name, value, options });
},
clearCookie(name, options) {},
setHeader(name, value) {
this._headers[name.toLowerCase()] = value;
},
status(code) {
this._statusCode = code;
},
redirect(arg1, arg2) {
let status = 302;
let url = "";
if (typeof arg1 === "number") {
status = arg1;
url = arg2;
} else {
url = arg1;
}
this._statusCode = status;
this._redirectUrl = url;
console.warn(`⚠️ [SSG] Redirect detected in ${reqPath} -> ${url} (${status})`);
},
};
const mockReq = {
query: {},
cookies: {},
headers: {
"user-agent": "Dinou-SSG-Builder",
host: "localhost",
},
path: reqPath,
method: "GET",
};
const mockContext = { req: mockReq, res: mockRes };
try {
fs.mkdirSync(path.dirname(payloadPath), { recursive: true });
const fileStream = fs.createWriteStream(payloadPath);
const passThrough = new PassThrough();
// 4. Render JSX inside Request Storage
await requestStorage.run(mockContext, async () => {
const jsx = await getJSX(reqPath, {}, null, false);
const { pipe } = isWebpack
? renderToPipeableStream(jsx, manifest)
: renderToPipeableStream(jsx, url.pathToFileURL(process.cwd()).href + "/");
pipe(passThrough);
passThrough.pipe(fileStream);
// Await stream finish
await new Promise((resolve, reject) => {
fileStream.on("finish", resolve);
fileStream.on("error", reject);
passThrough.on("error", reject);
});
});
console.log("✅ Generated RSC payload:", reqPath);
} catch (error) {
console.error("❌ Error generating RSC payload for:", reqPath, error);
}
}
console.log("🟢 Static RSC payload generation complete.");
}
module.exports = generateStaticRSCs;