vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
127 lines (124 loc) • 3.93 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { join } from 'node:path';
import { PassThrough } from 'node:stream';
import { parentPort } from 'node:worker_threads';
import React__default from 'react';
import { addCssFile, cssFiles } from './state.js';
import { InlineCssCollector } from '../../css-collector-inline.js';
import { createRscStream } from '../../helpers/createRscStream.js';
import { createLogger } from 'vite';
async function messageHandler(message) {
switch (message.type) {
case "RSC_RENDER":
const {
id,
pageImport,
propsImport,
pageExportName,
propsExportName,
url,
outDir,
projectRoot,
moduleRootPath,
moduleBaseURL,
moduleBasePath,
moduleBase,
pipableStreamOptions
} = message;
try {
const [Component, propsModule] = await Promise.all([
import(join(projectRoot, pageImport)),
import(join(projectRoot, propsImport))
]);
const propsAtExport = propsModule[propsExportName];
const props = await Promise.resolve(
typeof propsAtExport === "function" ? propsAtExport(url) : propsAtExport
);
const PageComponent = Component[pageExportName];
const stream = createRscStream({
Html: React__default.Fragment,
Page: PageComponent,
CssCollector: InlineCssCollector,
loader: (id2) => import(id2).then((m) => m.default),
props,
moduleBase,
moduleRootPath,
moduleBasePath,
moduleBaseURL,
logger: createLogger(),
inlineCss: true,
cssFiles: Array.from(cssFiles.values()).map((css) => ({
type: "text/css",
content: css,
path: css
})),
route: url,
url: typeof moduleBaseURL === "string" && moduleBaseURL !== "" ? new URL(url, moduleBaseURL).toString() : url,
root: projectRoot,
pipableStreamOptions: {
...pipableStreamOptions,
onError: (error) => {
if (typeof pipableStreamOptions.onError === "function") {
pipableStreamOptions.onError(error);
}
parentPort?.postMessage({
type: "ERROR",
id,
error: error instanceof Error ? error.message : String(error)
});
},
onPostpone: (reason) => {
if (typeof pipableStreamOptions.onPostpone === "function") {
pipableStreamOptions.onPostpone(reason);
}
parentPort?.postMessage({
type: "POSTPONE",
id,
reason
});
}
}
});
if (!stream) {
throw new Error("Failed to create stream");
}
const passThrough = new PassThrough();
stream.pipe(passThrough);
passThrough.on("data", (chunk) => {
parentPort?.postMessage({
type: "RSC_CHUNK",
id,
chunk: chunk.toString(),
moduleRootPath: moduleBasePath,
moduleBaseURL,
outDir,
rscOutputPath: `${outDir}/${id}.rsc`,
cssFiles: Array.from(cssFiles.entries())
});
});
passThrough.on("end", () => {
parentPort?.postMessage({
type: "RSC_END",
id
});
});
} catch (error) {
console.trace(error);
parentPort?.postMessage({
type: "ERROR",
id,
error: error instanceof Error ? error.message : String(error)
});
}
break;
case "CSS_FILE":
addCssFile(message.id, message.cssFile);
break;
}
}
export { messageHandler };
//# sourceMappingURL=messageHandler.js.map