vite-plugin-react-server 1.1.4 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/plugin/config/autoDiscover/resolveBuildPages.d.ts +1 -1
- package/dist/plugin/config/autoDiscover/resolveBuildPages.d.ts.map +1 -1
- package/dist/plugin/config/autoDiscover/resolveBuildPages.js.map +1 -1
- package/dist/plugin/config/defaults.d.ts +1 -1
- package/dist/plugin/config/defaults.d.ts.map +1 -1
- package/dist/plugin/config/resolveUrlOption.d.ts +2 -2
- package/dist/plugin/config/resolveUrlOption.d.ts.map +1 -1
- package/dist/plugin/config/resolveUrlOption.js +4 -1
- package/dist/plugin/config/resolveUrlOption.js.map +1 -1
- package/dist/plugin/config/resolveUserConfig.d.ts.map +1 -1
- package/dist/plugin/config/resolveUserConfig.js +11 -1
- package/dist/plugin/config/resolveUserConfig.js.map +1 -1
- package/dist/plugin/helpers/createRscStream.js +2 -1
- package/dist/plugin/helpers/createRscStream.js.map +1 -1
- package/dist/plugin/helpers/requestToRoute.d.ts +5 -0
- package/dist/plugin/helpers/requestToRoute.d.ts.map +1 -0
- package/dist/plugin/helpers/requestToRoute.js +24 -0
- package/dist/plugin/helpers/requestToRoute.js.map +1 -0
- package/dist/plugin/html.d.ts +1 -1
- package/dist/plugin/html.d.ts.map +1 -1
- package/dist/plugin/html.js +3 -2
- package/dist/plugin/html.js.map +1 -1
- package/dist/plugin/react-client/plugin.d.ts.map +1 -1
- package/dist/plugin/react-client/plugin.js.map +1 -1
- package/dist/plugin/react-client/server.d.ts +1 -1
- package/dist/plugin/react-client/server.d.ts.map +1 -1
- package/dist/plugin/react-client/server.js +51 -39
- package/dist/plugin/react-client/server.js.map +1 -1
- package/dist/plugin/react-server/server.d.ts +1 -1
- package/dist/plugin/react-server/server.d.ts.map +1 -1
- package/dist/plugin/react-server/server.js +36 -22
- package/dist/plugin/react-server/server.js.map +1 -1
- package/dist/plugin/react-static/plugin.d.ts.map +1 -1
- package/dist/plugin/react-static/plugin.js +25 -10
- package/dist/plugin/react-static/plugin.js.map +1 -1
- package/dist/plugin/react-static/renderPage.d.ts.map +1 -1
- package/dist/plugin/react-static/renderPage.js.map +1 -1
- package/dist/plugin/transformer/plugin.client.d.ts.map +1 -1
- package/dist/plugin/transformer/plugin.client.js +13 -3
- package/dist/plugin/transformer/plugin.client.js.map +1 -1
- package/dist/plugin/transformer/plugin.server.d.ts.map +1 -1
- package/dist/plugin/transformer/plugin.server.js +13 -3
- package/dist/plugin/transformer/plugin.server.js.map +1 -1
- package/dist/plugin/worker/createWorker.d.ts +1 -0
- package/dist/plugin/worker/createWorker.d.ts.map +1 -1
- package/dist/plugin/worker/createWorker.js +9 -16
- package/dist/plugin/worker/createWorker.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugin/config/autoDiscover/resolveBuildPages.ts +1 -1
- package/plugin/config/resolveUrlOption.ts +19 -10
- package/plugin/config/resolveUserConfig.ts +19 -1
- package/plugin/helpers/createRscStream.tsx +2 -2
- package/plugin/helpers/requestToRoute.ts +23 -0
- package/plugin/html.tsx +2 -0
- package/plugin/react-client/plugin.ts +1 -0
- package/plugin/react-client/server.ts +62 -40
- package/plugin/react-server/server.ts +50 -25
- package/plugin/react-static/plugin.ts +31 -13
- package/plugin/react-static/renderPage.ts +0 -1
- package/plugin/transformer/plugin.client.ts +13 -3
- package/plugin/transformer/plugin.server.ts +14 -4
- package/plugin/worker/createWorker.ts +19 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sources":["../../../plugin/react-client/server.ts"],"sourcesContent":["import type { ViteDevServer } from \"vite\";\nimport type {\n AutoDiscoveredFiles,\n RequestHandler,\n ResolvedUserOptions,\n} from \"../types.js\";\nimport type {\n RscWorkerOutputMessage,\n RscRenderMessage,\n} from \"../worker/types.js\";\nimport { join } from \"node:path\";\nimport type { Worker as NodeWorker } from \"node:worker_threads\";\nimport { MessageChannel } from \"node:worker_threads\";\nimport {\n serializedDevServerConfig,\n serializedOptions,\n} from \"../helpers/serializeUserOptions.js\";\nimport { createWorker } from \"../worker/createWorker.js\";\nimport { getRouteFiles } from \"../helpers/getRouteFiles.js\";\n\nlet currentWorker: NodeWorker | null = null;\nlet isRestarting = false;\n\nasync function restartWorker(\n server: ViteDevServer,\n autoDiscoveredFiles: AutoDiscoveredFiles,\n userOptions: ResolvedUserOptions,\n hmrChannel: MessageChannel\n) {\n if (isRestarting) return;\n isRestarting = true;\n\n try {\n // Terminate the current worker if it exists\n if (currentWorker) {\n currentWorker.terminate();\n currentWorker = null;\n }\n\n const workerResult = await createWorker({\n projectRoot: server.config.root,\n workerPath: userOptions.rscWorkerPath,\n reverseCondition: \"react-server\",\n currentCondition: \"react-client\",\n workerData: {\n hmrPort: hmrChannel.port2,\n resolvedConfig: serializedDevServerConfig(server.config),\n userOptions: serializedOptions(userOptions, autoDiscoveredFiles),\n },\n transferList: [hmrChannel.port2],\n });\n\n if (workerResult.type === \"success\") {\n currentWorker = workerResult.worker;\n } else if (workerResult.type === \"error\") {\n server.config.logger.error(\"Failed to start rsc-worker\", {\n error: workerResult.error,\n });\n }\n } finally {\n isRestarting = false;\n }\n}\n\n/**\n * Creates an async generator that yields RSC chunks from the worker.\n * Handles both module requests and RSC streaming.\n *\n * @param worker - The worker thread\n * @param server - The Vite dev server\n * @param message - The RSC render message\n * @param rscWorkerLoaderPort - Optional loader port for module loading\n * @returns An async generator that yields RSC chunks\n */\nasync function* createWorkerStream(\n worker: NodeWorker,\n message: Omit<RscRenderMessage, \"type\" | \"id\">\n): AsyncGenerator<Uint8Array, void, unknown> {\n let messageHandler: (message: RscWorkerOutputMessage) => void;\n let cleanup: () => void = () => {};\n\n // First yield: wait for initial message and handle module requests\n yield await new Promise<Uint8Array>((resolve) => {\n messageHandler = (message: RscWorkerOutputMessage) => {\n if (message.type === \"RSC_CHUNK\") {\n resolve(message.chunk);\n }\n if (message.type === \"ERROR\") {\n resolve(new Uint8Array());\n }\n };\n\n cleanup = () => {\n worker.off(\"message\", messageHandler);\n };\n\n worker.on(\"message\", messageHandler);\n\n // Send the render message to start the RSC stream\n worker.postMessage({\n type: \"RSC_RENDER\",\n id: message.route,\n ...message,\n });\n });\n\n // Subsequent yields: handle RSC chunks until stream ends\n while (true) {\n const chunk = await new Promise<Uint8Array>((resolve) => {\n messageHandler = (message: RscWorkerOutputMessage) => {\n if (message.type === \"RSC_END\") {\n cleanup();\n resolve(new Uint8Array());\n return;\n }\n if (message.type === \"RSC_CHUNK\") {\n resolve(message.chunk);\n }\n if (message.type === \"ERROR\") {\n cleanup();\n resolve(new Uint8Array());\n return;\n }\n };\n worker.once(\"message\", messageHandler);\n });\n\n if (chunk.length === 0) {\n break;\n }\n yield chunk;\n }\n}\n\n/**\n * Handles the RSC stream from the worker.\n * Creates a ReadableStream that pipes RSC chunks to the response.\n *\n * @param worker - The worker thread\n * @param message - The RSC render message\n * @returns A ReadableStream that yields RSC chunks\n */\nexport function handleWorkerRscStream(\n worker: NodeWorker,\n message: Omit<RscRenderMessage, \"type\" | \"id\">\n): ReadableStream<Uint8Array> {\n // Create a ReadableStream from the async generator\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n try {\n for await (const chunk of createWorkerStream(worker, message)) {\n controller.enqueue(chunk);\n }\n } catch (error) {\n controller.error(error);\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Configures the worker request handler.\n * @param server - The Vite dev server\n * @param autoDiscoveredFiles - The auto discovered files\n * @param userOptions - The user options\n */\nexport async function configureWorkerRequestHandler({\n server,\n autoDiscoveredFiles,\n userOptions,\n hmrChannel,\n}: {\n server: ViteDevServer;\n autoDiscoveredFiles: AutoDiscoveredFiles;\n userOptions: ResolvedUserOptions;\n hmrChannel: MessageChannel;\n}) {\n if(server.config.root !== userOptions.projectRoot) {\n server.config.logger.error(\"[react-client] Project root mismatch\", {\n error: new Error(`Server root ${server.config.root} does not match user options root ${userOptions.projectRoot}`)\n });\n return;\n }\n\n // Start the worker\n await restartWorker(server, autoDiscoveredFiles, userOptions, hmrChannel);\n\n // Create the request handler\n const handler: RequestHandler = async (req, res, next) => {\n if (!req.url || req.headers.accept !== \"text/x-component\") return next();\n try {\n if (!currentWorker) {\n server.config.logger.error(\"[react-client] No worker available\");\n return next();\n }\n\n // Get the route from the request\n let route = req.url;\n if (!route || route === \"\") route = \"/\";\n // in the case of the no build.pages and a async Page and or props userOption, we need to await those\n // if they are already autoDiscovered then the promise will resolve immediately\n const routeFiles = await getRouteFiles(\n route,\n autoDiscoveredFiles,\n userOptions\n );\n if (routeFiles.type === \"error\") {\n server.config.logger.error(\"[react-client] Error getting route files\", {\n error: routeFiles.error,\n });\n return next();\n }\n const { page, props } = routeFiles;\n\n // Set up response headers for streaming\n res.setHeader(\"Content-Type\", \"text/x-component; charset=utf-8\");\n res.setHeader(\"Transfer-Encoding\", \"chunked\");\n res.setHeader(\"Connection\", \"keep-alive\");\n let timeout = setTimeout(() => {\n server.config.logger.error(\"[react-client] RSC render timeout\");\n res.end();\n }, 5000);\n const serializedUserOptions = serializedOptions(\n userOptions,\n autoDiscoveredFiles\n );\n const stream = handleWorkerRscStream(currentWorker, {\n ...serializedUserOptions,\n // we make the worker stream aware of the route, pagePath, propsPath\n route,\n pagePath: page,\n propsPath: props,\n // override these at all times to ensure the settings will work for the dev server\n projectRoot: server.config.root,\n moduleRootPath: join(server.config.root, userOptions.moduleBase),\n moduleBaseURL: \"\",\n moduleBasePath: \"\",\n build: serializedUserOptions.build,\n manifest: autoDiscoveredFiles.staticManifest,\n cssFiles: new Map(),\n globalCss: new Map(),\n });\n\n // Pipe the stream to the response\n stream.pipeTo(\n new WritableStream({\n write(chunk) {\n res.write(chunk);\n },\n\n close() {\n clearTimeout(timeout);\n res.end();\n },\n abort() {\n clearTimeout(timeout);\n // Restart worker on error\n restartWorker(server, autoDiscoveredFiles, userOptions, hmrChannel);\n res.end();\n },\n })\n );\n } catch (error) {\n if (error instanceof Error) {\n server.config.logger.error(\"[react-client] Error handling request\", {\n error,\n });\n }\n }\n };\n // attach handler to the server\n server.middlewares.use(handler);\n // done\n}\n"],"names":["message"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sources":["../../../plugin/react-client/server.ts"],"sourcesContent":["import type { ViteDevServer } from \"vite\";\nimport type {\n AutoDiscoveredFiles,\n RequestHandler,\n ResolvedUserOptions,\n} from \"../types.js\";\nimport type {\n RscWorkerOutputMessage,\n RscRenderMessage,\n} from \"../worker/types.js\";\nimport type { Worker as NodeWorker } from \"node:worker_threads\";\nimport { MessageChannel } from \"node:worker_threads\";\nimport {\n serializedDevServerConfig,\n serializedOptions,\n} from \"../helpers/serializeUserOptions.js\";\nimport { createWorker } from \"../worker/createWorker.js\";\nimport { getRouteFiles } from \"../helpers/getRouteFiles.js\";\nimport { requestToRoute } from \"../helpers/requestToRoute.js\";\n\nlet currentWorker: NodeWorker | null = null;\nlet isRestarting = false;\n\nasync function restartWorker(\n server: ViteDevServer,\n autoDiscoveredFiles: AutoDiscoveredFiles,\n userOptions: ResolvedUserOptions,\n hmrChannel: MessageChannel\n) {\n if (isRestarting) return;\n isRestarting = true;\n\n try {\n // Terminate the current worker if it exists\n if (currentWorker) {\n currentWorker.terminate();\n currentWorker = null;\n }\n\n const workerResult = await createWorker({\n projectRoot: server.config.root,\n workerPath: userOptions.rscWorkerPath,\n reverseCondition: \"react-server\",\n currentCondition: \"react-client\",\n workerData: {\n hmrPort: hmrChannel.port2,\n resolvedConfig: serializedDevServerConfig(server.config),\n userOptions: serializedOptions(userOptions, autoDiscoveredFiles),\n },\n transferList: [hmrChannel.port2],\n });\n\n if (workerResult.type === \"success\") {\n currentWorker = workerResult.worker;\n } else if (workerResult.type === \"error\") {\n server.config.logger.error(\"Failed to start rsc-worker\", {\n error: workerResult.error,\n });\n }\n } finally {\n isRestarting = false;\n }\n}\n\n/**\n * Creates an async generator that yields RSC chunks from the worker.\n * Handles both module requests and RSC streaming.\n *\n * @param worker - The worker thread\n * @param server - The Vite dev server\n * @param message - The RSC render message\n * @param rscWorkerLoaderPort - Optional loader port for module loading\n * @returns An async generator that yields RSC chunks\n */\nasync function* createWorkerStream(\n worker: NodeWorker,\n message: Omit<RscRenderMessage, \"type\" | \"id\">\n): AsyncGenerator<Uint8Array, void, unknown> {\n let messageHandler: (message: RscWorkerOutputMessage) => void;\n let cleanup: () => void = () => {};\n\n // First yield: wait for initial message and handle module requests\n yield await new Promise<Uint8Array>((resolve) => {\n messageHandler = (message: RscWorkerOutputMessage) => {\n if (message.type === \"RSC_CHUNK\") {\n resolve(message.chunk);\n }\n if (message.type === \"ERROR\") {\n resolve(new Uint8Array());\n }\n };\n\n cleanup = () => {\n worker.off(\"message\", messageHandler);\n };\n\n worker.on(\"message\", messageHandler);\n\n // Send the render message to start the RSC stream\n worker.postMessage({\n type: \"RSC_RENDER\",\n id: message.route,\n ...message,\n });\n });\n\n // Subsequent yields: handle RSC chunks until stream ends\n while (true) {\n const chunk = await new Promise<Uint8Array>((resolve) => {\n messageHandler = (message: RscWorkerOutputMessage) => {\n if (message.type === \"RSC_END\") {\n cleanup();\n resolve(new Uint8Array());\n return;\n }\n if (message.type === \"RSC_CHUNK\") {\n resolve(message.chunk);\n }\n if (message.type === \"ERROR\") {\n cleanup();\n resolve(new Uint8Array());\n return;\n }\n };\n worker.once(\"message\", messageHandler);\n });\n\n if (chunk.length === 0) {\n break;\n }\n yield chunk;\n }\n}\n\n/**\n * Handles the RSC stream from the worker.\n * Creates a ReadableStream that pipes RSC chunks to the response.\n *\n * @param worker - The worker thread\n * @param message - The RSC render message\n * @returns A ReadableStream that yields RSC chunks\n */\nexport function handleWorkerRscStream(\n worker: NodeWorker,\n message: Omit<RscRenderMessage, \"type\" | \"id\">\n): ReadableStream<Uint8Array> {\n // Create a ReadableStream from the async generator\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n try {\n for await (const chunk of createWorkerStream(worker, message)) {\n controller.enqueue(chunk);\n }\n } catch (error) {\n controller.error(error);\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Configures the worker request handler.\n * @param server - The Vite dev server\n * @param autoDiscoveredFiles - The auto discovered files\n * @param userOptions - The user options\n */\nexport async function configureWorkerRequestHandler({\n server,\n autoDiscoveredFiles,\n userOptions: _userOptions,\n hmrChannel,\n}: {\n server: ViteDevServer;\n autoDiscoveredFiles: AutoDiscoveredFiles;\n userOptions: ResolvedUserOptions;\n hmrChannel: MessageChannel;\n}) {\n let {\n // remove these\n moduleBaseURL: _moduleBaseURL,\n projectRoot: _projectRoot,\n ...handlerUserOptions\n } = _userOptions;\n const handlerOptions = Object.assign({}, handlerUserOptions, {\n moduleBaseURL:\n typeof server.config.server.host === \"string\"\n ? `${server.config.server.https ? \"https\" : \"http\"}://${\n server.config.server.host\n }:${server.config.server.port}`\n : \"\",\n moduleBasePath:\n server.config.base === \"/\"\n ? \"\"\n : server.config.base.endsWith(\"/\")\n ? server.config.base.slice(0, -1)\n : server.config.base,\n projectRoot: server.config.root,\n });\n\n // Start the worker\n await restartWorker(server, autoDiscoveredFiles, handlerOptions, hmrChannel);\n\n // Create the request handler\n const handler: RequestHandler = async (req, res, next) => {\n if (!req.url || req.headers.accept !== \"text/x-component\") return next();\n try {\n if (!currentWorker) {\n server.config.logger.error(\"[react-client] No worker available\");\n return next();\n }\n\n // Get the route from the request\n let route = requestToRoute(req, {\n moduleBasePath: handlerOptions.moduleBasePath,\n build: handlerOptions.build\n });\n if (!route) {\n return next();\n }\n // in the case of the no build.pages and a async Page and or props userOption, we need to await those\n // if they are already autoDiscovered then the promise will resolve immediately\n const routeFiles = await getRouteFiles(\n route,\n autoDiscoveredFiles,\n handlerOptions\n );\n if (routeFiles.type === \"error\") {\n server.config.logger.error(routeFiles.error.message, {\n error: routeFiles.error,\n timestamp: true,\n });\n return next();\n }\n const { page, props } = routeFiles;\n\n // Set up response headers for streaming\n res.setHeader(\"Content-Type\", \"text/x-component; charset=utf-8\");\n res.setHeader(\"Transfer-Encoding\", \"chunked\");\n res.setHeader(\"Connection\", \"keep-alive\");\n const serializedUserOptions = serializedOptions(\n handlerOptions,\n autoDiscoveredFiles\n );\n const stream = handleWorkerRscStream(currentWorker, {\n ...serializedUserOptions,\n // we make the worker stream aware of the route, pagePath, propsPath\n route,\n pagePath: page,\n propsPath: props,\n // override these at all times to ensure the settings will work for the dev server\n projectRoot: server.config.root,\n build: serializedUserOptions.build,\n manifest: autoDiscoveredFiles.staticManifest,\n cssFiles: new Map(),\n globalCss: new Map(),\n });\n const writeStream = new WritableStream({\n write(chunk) {\n res.write(chunk);\n },\n\n close() {\n clearTimeout(timeout);\n res.end();\n },\n abort() {\n clearTimeout(timeout);\n // Restart worker on error\n restartWorker(\n server,\n autoDiscoveredFiles,\n handlerOptions,\n hmrChannel\n );\n res.end();\n },\n })\n let timeout = setTimeout(() => {\n server.config.logger.error(\"[react-client] RSC render timeout\");\n res.end();\n }, 5000);\n\n // Pipe the stream to the response\n stream.pipeTo(writeStream);\n } catch (error) {\n if (error instanceof Error) {\n server.config.logger.error(error.message, {\n error,\n });\n }\n }\n };\n // attach handler to the server\n server.middlewares.use(handler);\n // done\n}\n"],"names":["message"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Manifest, ViteDevServer } from "vite";
|
|
2
2
|
import type { AutoDiscoveredFiles, ResolvedUserOptions } from "../types.js";
|
|
3
|
-
export declare function configureReactServer({ server, autoDiscoveredFiles, userOptions, serverManifest, }: {
|
|
3
|
+
export declare function configureReactServer({ server, autoDiscoveredFiles, userOptions: _userOptions, serverManifest, }: {
|
|
4
4
|
server: ViteDevServer;
|
|
5
5
|
autoDiscoveredFiles: AutoDiscoveredFiles;
|
|
6
6
|
userOptions: ResolvedUserOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../plugin/react-server/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../plugin/react-server/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAEpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAO5E,wBAAsB,oBAAoB,CAAC,EACzC,MAAM,EACN,mBAAmB,EACnB,WAAW,EAAE,YAAY,EACzB,cAAc,GACf,EAAE;IACD,MAAM,EAAE,aAAa,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,WAAW,EAAE,mBAAmB,CAAC;IACjC,cAAc,EAAE,QAAQ,CAAC;CAC1B,iBAuIA"}
|
|
@@ -12,10 +12,24 @@ import React__default from 'react';
|
|
|
12
12
|
async function configureReactServer({
|
|
13
13
|
server,
|
|
14
14
|
autoDiscoveredFiles,
|
|
15
|
-
userOptions,
|
|
15
|
+
userOptions: _userOptions,
|
|
16
16
|
serverManifest
|
|
17
17
|
}) {
|
|
18
18
|
const activeStreams = /* @__PURE__ */ new Set();
|
|
19
|
+
const {
|
|
20
|
+
Html: _UserHtmlComponent,
|
|
21
|
+
onEvent,
|
|
22
|
+
// remove these
|
|
23
|
+
moduleBaseURL: _moduleBaseURL,
|
|
24
|
+
moduleBasePath: _moduleBasePath,
|
|
25
|
+
projectRoot: _projectRoot,
|
|
26
|
+
...handlerUserOptions
|
|
27
|
+
} = _userOptions;
|
|
28
|
+
const handlerOptions = Object.assign({}, handlerUserOptions, {
|
|
29
|
+
moduleBaseURL: typeof server.config.server.host === "string" ? `${server.config.server.https ? "https" : "http"}://${server.config.server.host}:${server.config.server.port}` : "",
|
|
30
|
+
moduleBasePath: server.config.base === "/" ? "" : server.config.base.endsWith("/") ? server.config.base.slice(0, -1) : server.config.base,
|
|
31
|
+
projectRoot: server.config.root
|
|
32
|
+
});
|
|
19
33
|
server.ws.on("restart", (path) => {
|
|
20
34
|
console.log(
|
|
21
35
|
"[vite-plugin-react-server] 🔧 Plugin changed, preparing for restart:",
|
|
@@ -33,36 +47,39 @@ async function configureReactServer({
|
|
|
33
47
|
server.middlewares.use(async (req, res, next) => {
|
|
34
48
|
try {
|
|
35
49
|
if (req.headers.accept !== "text/x-component") return next();
|
|
36
|
-
let route = req.url?.replace("/" +
|
|
50
|
+
let route = req.url?.replace("/" + handlerOptions.build.rscOutputPath, "");
|
|
51
|
+
if (!route?.startsWith(handlerOptions.moduleBasePath)) {
|
|
52
|
+
next();
|
|
53
|
+
} else {
|
|
54
|
+
route = route.slice(handlerOptions.moduleBasePath.length);
|
|
55
|
+
}
|
|
56
|
+
if (typeof route !== "string") {
|
|
57
|
+
throw new Error("req.url is not a string");
|
|
58
|
+
}
|
|
37
59
|
if (!route || route === "") {
|
|
38
60
|
route = "/";
|
|
39
61
|
}
|
|
62
|
+
if (!route.startsWith("/")) {
|
|
63
|
+
route = "/" + route;
|
|
64
|
+
}
|
|
40
65
|
if (!autoDiscoveredFiles.urlMap.has(route)) {
|
|
41
66
|
return next();
|
|
42
67
|
}
|
|
43
68
|
const routeFiles = autoDiscoveredFiles.urlMap.get(route);
|
|
44
69
|
const pagePath = routeFiles.page;
|
|
45
70
|
const propsPath = routeFiles.props;
|
|
46
|
-
const {
|
|
47
|
-
Html: _UserHtmlComponent,
|
|
48
|
-
onEvent,
|
|
49
|
-
// remove these
|
|
50
|
-
moduleBaseURL,
|
|
51
|
-
...handlerUserOptions
|
|
52
|
-
} = userOptions;
|
|
53
71
|
await server.warmupRequest(pagePath);
|
|
54
72
|
const eventHandler = createEventHandler(onEvent);
|
|
55
|
-
const moduleBasePathForDevServer = "/" + userOptions.moduleBase;
|
|
56
73
|
const cssFilesResult = await collectViteModuleGraphCss({
|
|
57
74
|
moduleGraph: server.moduleGraph,
|
|
58
75
|
pagePath,
|
|
59
76
|
loader: (i) => server.ssrLoadModule(i, { fixStacktrace: true }),
|
|
60
|
-
// explicitly set
|
|
61
|
-
moduleBaseURL:
|
|
62
|
-
moduleBasePath:
|
|
63
|
-
moduleRootPath:
|
|
64
|
-
projectRoot:
|
|
65
|
-
css:
|
|
77
|
+
// explicitly set for development server
|
|
78
|
+
moduleBaseURL: handlerOptions.moduleBaseURL,
|
|
79
|
+
moduleBasePath: handlerOptions.moduleBasePath,
|
|
80
|
+
moduleRootPath: handlerOptions.moduleRootPath,
|
|
81
|
+
projectRoot: handlerOptions.projectRoot,
|
|
82
|
+
css: handlerOptions.css,
|
|
66
83
|
parentUrl: pagePath
|
|
67
84
|
});
|
|
68
85
|
if (cssFilesResult.type === "skip") {
|
|
@@ -76,8 +93,8 @@ async function configureReactServer({
|
|
|
76
93
|
propsPath,
|
|
77
94
|
route,
|
|
78
95
|
loader: server.ssrLoadModule,
|
|
79
|
-
pageExportName:
|
|
80
|
-
propsExportName:
|
|
96
|
+
pageExportName: handlerOptions.pageExportName ?? "default",
|
|
97
|
+
propsExportName: handlerOptions.propsExportName ?? "default"
|
|
81
98
|
});
|
|
82
99
|
if (pageAndPropsResult.type === "error") {
|
|
83
100
|
throw pageAndPropsResult.error;
|
|
@@ -87,7 +104,7 @@ async function configureReactServer({
|
|
|
87
104
|
}
|
|
88
105
|
const { PageComponent, pageProps } = pageAndPropsResult;
|
|
89
106
|
const rscResult = await createHandler({
|
|
90
|
-
...
|
|
107
|
+
...handlerOptions,
|
|
91
108
|
PageComponent,
|
|
92
109
|
pageProps,
|
|
93
110
|
logger: server.config.logger,
|
|
@@ -100,9 +117,6 @@ async function configureReactServer({
|
|
|
100
117
|
pagePath,
|
|
101
118
|
propsPath,
|
|
102
119
|
cssFiles: cssFilesResult.cssFiles ?? /* @__PURE__ */ new Map(),
|
|
103
|
-
// explicitly set to empty string, because we let vite handle the resolving during development
|
|
104
|
-
moduleBaseURL: "",
|
|
105
|
-
moduleBasePath: "",
|
|
106
120
|
globalCss: /* @__PURE__ */ new Map()
|
|
107
121
|
});
|
|
108
122
|
if (rscResult.type === "success") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sources":["../../../plugin/react-server/server.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"server.js","sources":["../../../plugin/react-server/server.ts"],"sourcesContent":["import type { Manifest, ViteDevServer } from \"vite\";\nimport type { ServerResponse } from \"http\";\nimport type { AutoDiscoveredFiles, ResolvedUserOptions } from \"../types.js\";\nimport { createEventHandler } from \"../helpers/createEventHandler.js\";\nimport { collectViteModuleGraphCss } from \"../helpers/collectViteModuleGraphCss.js\";\nimport { resolvePageAndProps } from \"../helpers/resolvePageAndProps.js\";\nimport { createHandler } from \"../helpers/createHandler.js\";\nimport React from \"react\";\n\nexport async function configureReactServer({\n server,\n autoDiscoveredFiles,\n userOptions: _userOptions,\n serverManifest,\n}: {\n server: ViteDevServer;\n autoDiscoveredFiles: AutoDiscoveredFiles;\n userOptions: ResolvedUserOptions;\n serverManifest: Manifest;\n}) {\n const activeStreams = new Set<ServerResponse>();\n\n const {\n Html: _UserHtmlComponent,\n onEvent,\n // remove these\n moduleBaseURL: _moduleBaseURL,\n moduleBasePath: _moduleBasePath,\n projectRoot: _projectRoot,\n ...handlerUserOptions\n } = _userOptions;\n\n const handlerOptions = Object.assign({}, handlerUserOptions, {\n moduleBaseURL:\n typeof server.config.server.host === \"string\"\n ? `${server.config.server.https ? \"https\" : \"http\"}://${\n server.config.server.host\n }:${server.config.server.port}`\n : \"\",\n moduleBasePath:\n server.config.base === \"/\"\n ? \"\"\n : server.config.base.endsWith(\"/\")\n ? server.config.base.slice(0, -1)\n : server.config.base,\n projectRoot: server.config.root,\n });\n // Handle Vite server restarts\n server.ws.on(\"restart\", (path) => {\n console.log(\n \"[vite-plugin-react-server] 🔧 Plugin changed, preparing for restart:\",\n path\n );\n\n // Close streams with restart message\n for (const res of activeStreams) {\n res.writeHead(503, {\n \"Content-Type\": \"text/x-component\",\n \"Retry-After\": \"1\",\n });\n res.end('{\"error\":\"Server restarting...\"}');\n }\n activeStreams.clear();\n });\n\n server.middlewares.use(async (req, res, next) => {\n try {\n if (req.headers.accept !== \"text/x-component\") return next();\n let route = req.url?.replace(\"/\" + handlerOptions.build.rscOutputPath, \"\");\n if(!route?.startsWith(handlerOptions.moduleBasePath)) {\n next();\n } else {\n route = route.slice(handlerOptions.moduleBasePath.length);\n }\n if(typeof route !== \"string\" ) {\n throw new Error(\"req.url is not a string\");\n }\n if (!route || route === \"\") {\n route = \"/\";\n }\n if(!route.startsWith(\"/\")) {\n route = \"/\" + route;\n }\n if (!autoDiscoveredFiles.urlMap.has(route)) {\n return next();\n }\n const routeFiles = autoDiscoveredFiles.urlMap.get(route)!;\n const pagePath = routeFiles.page;\n const propsPath = routeFiles.props;\n\n // Create a unified event handler\n await server.warmupRequest(pagePath);\n const eventHandler = createEventHandler(onEvent);\n const cssFilesResult = await collectViteModuleGraphCss({\n moduleGraph: server.moduleGraph,\n pagePath,\n loader: (i) => server.ssrLoadModule(i, { fixStacktrace: true }),\n // explicitly set for development server\n moduleBaseURL: handlerOptions.moduleBaseURL,\n moduleBasePath: handlerOptions.moduleBasePath,\n moduleRootPath: handlerOptions.moduleRootPath,\n projectRoot: handlerOptions.projectRoot,\n css: handlerOptions.css,\n parentUrl: pagePath,\n });\n if (cssFilesResult.type === \"skip\") {\n return next();\n }\n if (cssFilesResult.type === \"error\") {\n throw cssFilesResult.error;\n }\n const pageAndPropsResult = await resolvePageAndProps({\n pagePath,\n propsPath,\n route,\n loader: server.ssrLoadModule,\n pageExportName: handlerOptions.pageExportName ?? \"default\",\n propsExportName: handlerOptions.propsExportName ?? \"default\",\n });\n if (pageAndPropsResult.type === \"error\") {\n throw pageAndPropsResult.error;\n }\n if (pageAndPropsResult.type === \"skip\") {\n return next();\n }\n const { PageComponent, pageProps } = pageAndPropsResult;\n // Create the headless RSC stream directly;\n const rscResult = await createHandler({\n ...handlerOptions,\n PageComponent: PageComponent,\n pageProps: pageProps,\n logger: server.config.logger,\n loader: server.ssrLoadModule,\n Html: React.Fragment,\n onEvent: eventHandler,\n manifest: serverManifest,\n worker: server as any,\n route,\n pagePath,\n propsPath,\n cssFiles: cssFilesResult.cssFiles ?? new Map(),\n globalCss: new Map(),\n });\n if (rscResult.type === \"success\") {\n rscResult.stream!.pipe(res);\n }\n activeStreams.add(res);\n res.on(\"close\", () => {\n activeStreams.delete(res);\n });\n } catch (error) {\n res.end();\n }\n });\n}\n"],"names":["React"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../plugin/react-static/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAGL,KAAK,MAAM,IAAI,UAAU,EAE1B,MAAM,MAAM,CAAC;AAId,OAAO,KAAK,EAEV,qBAAqB,EAOtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AA6BvD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,UAAU,CAAC;IAC1E,IAAI,EAAE,qBAAqB,CAAC;CAC7B,CAAC,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../plugin/react-static/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAGL,KAAK,MAAM,IAAI,UAAU,EAE1B,MAAM,MAAM,CAAC;AAId,OAAO,KAAK,EAEV,qBAAqB,EAOtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AA6BvD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,UAAU,CAAC;IAC1E,IAAI,EAAE,qBAAqB,CAAC;CAC7B,CAAC,CAgVD"}
|
|
@@ -111,7 +111,11 @@ function reactStaticPlugin(options) {
|
|
|
111
111
|
}
|
|
112
112
|
const clientManifestResult = await tryManifest({
|
|
113
113
|
root: userOptions.projectRoot,
|
|
114
|
-
outDir: join(
|
|
114
|
+
outDir: join(
|
|
115
|
+
userOptions.build.outDir,
|
|
116
|
+
userOptions.build.client,
|
|
117
|
+
userOptions.moduleBasePath
|
|
118
|
+
),
|
|
115
119
|
ssrManifest: false
|
|
116
120
|
});
|
|
117
121
|
if (clientManifestResult.type === "error") {
|
|
@@ -206,7 +210,12 @@ function reactStaticPlugin(options) {
|
|
|
206
210
|
const pipeableStreamOptions = {
|
|
207
211
|
...userOptions.pipeableStreamOptions,
|
|
208
212
|
bootstrapModules: [
|
|
209
|
-
...indexHtml ? [
|
|
213
|
+
...indexHtml ? [
|
|
214
|
+
userOptions.moduleBaseURL !== "" ? new URL(
|
|
215
|
+
join(userOptions.moduleBasePath, indexHtml),
|
|
216
|
+
userOptions.moduleBaseURL
|
|
217
|
+
).href : join(userOptions.moduleBasePath, indexHtml)
|
|
218
|
+
] : [],
|
|
210
219
|
...userOptions.pipeableStreamOptions?.bootstrapModules ?? []
|
|
211
220
|
]
|
|
212
221
|
};
|
|
@@ -216,33 +225,36 @@ function reactStaticPlugin(options) {
|
|
|
216
225
|
autoDiscoveredFiles
|
|
217
226
|
);
|
|
218
227
|
if (!worker) {
|
|
228
|
+
const viteEnvPrefix = typeof resolvedConfig.envPrefix === "string" ? resolvedConfig.envPrefix : Array.isArray(resolvedConfig.envPrefix) ? resolvedConfig.envPrefix[0] : "VITE_";
|
|
219
229
|
const workerResult = await createWorker({
|
|
220
230
|
projectRoot: userOptions.projectRoot,
|
|
221
231
|
workerPath: userOptions.htmlWorkerPath,
|
|
222
232
|
currentCondition: "react-server",
|
|
223
233
|
reverseCondition: "react-client",
|
|
234
|
+
envPrefix: viteEnvPrefix,
|
|
224
235
|
workerData: {
|
|
225
236
|
resolvedConfig: serializeResolvedConfig(resolvedConfig),
|
|
226
237
|
userOptions: {
|
|
227
|
-
...serializedUserOptions
|
|
228
|
-
moduleBasePath: ""
|
|
238
|
+
...serializedUserOptions
|
|
229
239
|
}
|
|
230
240
|
}
|
|
231
241
|
});
|
|
232
242
|
if (workerResult.type === "error") {
|
|
233
243
|
throw workerResult.error;
|
|
234
244
|
} else if (workerResult.type === "skip") {
|
|
235
|
-
this.environment.logger.info(
|
|
245
|
+
this.environment.logger.info(
|
|
246
|
+
"Worker not created, skipping static build"
|
|
247
|
+
);
|
|
236
248
|
return;
|
|
237
249
|
} else {
|
|
238
250
|
worker = workerResult.worker;
|
|
239
251
|
}
|
|
240
252
|
}
|
|
241
|
-
const { onEvent, ...
|
|
253
|
+
const { onEvent, ...handlerOptions } = userOptions;
|
|
242
254
|
const renderPagesGenerator = renderPages(
|
|
243
255
|
autoDiscoveredFiles,
|
|
244
256
|
{
|
|
245
|
-
...
|
|
257
|
+
...handlerOptions,
|
|
246
258
|
loader: buildLoader,
|
|
247
259
|
worker,
|
|
248
260
|
logger: createLogger(),
|
|
@@ -256,7 +268,6 @@ function reactStaticPlugin(options) {
|
|
|
256
268
|
},
|
|
257
269
|
pipeableStreamOptions,
|
|
258
270
|
manifest: serverManifest ?? {},
|
|
259
|
-
moduleBasePath: "",
|
|
260
271
|
build: {
|
|
261
272
|
htmlOutputPath: userOptions.build.htmlOutputPath,
|
|
262
273
|
rscOutputPath: userOptions.build.rscOutputPath,
|
|
@@ -280,8 +291,12 @@ function reactStaticPlugin(options) {
|
|
|
280
291
|
if (!finalResult) {
|
|
281
292
|
throw new Error("No render result produced");
|
|
282
293
|
}
|
|
283
|
-
finalResult.streamMetrics.duration = Math.round(
|
|
284
|
-
|
|
294
|
+
finalResult.streamMetrics.duration = Math.round(
|
|
295
|
+
performance.now() - finalResult.streamMetrics.startTime
|
|
296
|
+
);
|
|
297
|
+
this.environment.logger.info(
|
|
298
|
+
`Rendered ${finalResult.completedRoutes.size} unique routes in ${finalResult.streamMetrics.duration}ms`
|
|
299
|
+
);
|
|
285
300
|
timing.render = Date.now() - (timing.renderStart ?? timing.start);
|
|
286
301
|
} catch (error) {
|
|
287
302
|
throw error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../../plugin/react-static/plugin.ts"],"sourcesContent":["/**\n * plugin.ts\n *\n * PURPOSE: Main Vite plugin for React Server Components (RSC) static site generation\n *\n * This module:\n * 1. Orchestrates the entire static site generation process\n * 2. Manages the lifecycle of the RSC rendering process\n * 3. Handles file writing for both initial page loads and client-side navigation\n * - Writes .html files for initial page loads (complete HTML document)\n * - Writes .rsc files for client-side navigation (RSC content only)\n * 4. Provides hooks for Vite to integrate with the build process\n * 5. Manages worker threads for parallel rendering\n * 6. Handles error reporting and metrics collection\n */\n\nimport { join } from \"node:path\";\nimport { Worker } from \"node:worker_threads\";\nimport {\n type Manifest,\n type ResolvedConfig,\n type Plugin as VitePlugin,\n createLogger,\n} from \"vite\";\nimport { resolveOptions } from \"../config/resolveOptions.js\";\nimport { resolveUserConfig } from \"../config/resolveUserConfig.js\";\nimport { createBuildLoader } from \"../loader/createBuildLoader.js\";\nimport type {\n BuildTiming,\n ReactStreamPluginMeta,\n ResolvedUserConfig,\n ResolvedUserOptions,\n PluginEvent,\n RenderPagesResult,\n AutoDiscoveredFiles,\n CssContent,\n} from \"../types.js\";\nimport { type StreamPluginOptions } from \"../types.js\";\nimport { renderPages } from \"./renderPages.js\";\nimport { getBundleManifest } from \"../helpers/getBundleManifest.js\";\nimport { createWorker } from \"../worker/createWorker.js\";\nimport { resolveAutoDiscover } from \"../config/resolveAutoDiscover.js\";\nimport { getCondition } from \"../config/getCondition.js\";\nimport {\n serializedOptions,\n serializeResolvedConfig,\n} from \"../helpers/serializeUserOptions.js\";\nimport { collectManifestCss } from \"../helpers/collectManifestCss.js\";\nimport { createCssProps } from \"../helpers/createCssProps.js\";\nimport { tryManifest } from \"../helpers/tryManifest.js\";\n\nif (getCondition() !== \"react-server\") {\n throw new Error(\n \"Condition mismatch, should be react-server but got \" +\n process.env[\"NODE_OPTIONS\"]\n );\n}\n\nlet worker: Worker;\nlet userConfig: ResolvedUserConfig;\nlet resolvedConfig: ResolvedConfig;\nlet userOptions: ResolvedUserOptions;\nlet autoDiscoveredFiles: AutoDiscoveredFiles | null = null;\nlet serverManifest: Manifest | undefined = undefined;\nlet buildLoader: Awaited<ReturnType<typeof createBuildLoader>> | undefined;\n\nexport function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{\n meta: ReactStreamPluginMeta;\n}> {\n const timing: BuildTiming = {\n start: Date.now(),\n configResolved: 0,\n buildStart: 0,\n renderStart: 0,\n };\n\n const resolvedOptions = resolveOptions(options);\n if (resolvedOptions.type === \"error\") {\n throw resolvedOptions.error;\n }\n userOptions = resolvedOptions.userOptions;\n\n return {\n name: \"vite:plugin-react-server/static\",\n enforce: \"post\",\n api: {\n meta: { timing },\n },\n\n async config(config, configEnv) {\n if (config.root && config.root !== userOptions.projectRoot) {\n userOptions.projectRoot = config.root;\n }\n\n const autoDiscoverResult = await resolveAutoDiscover({\n config,\n configEnv,\n userOptions,\n condition: \"react-server\",\n });\n if (autoDiscoverResult.type === \"error\") {\n throw autoDiscoverResult.error;\n }\n autoDiscoveredFiles = autoDiscoverResult.autoDiscoveredFiles;\n\n const resolvedConfig = resolveUserConfig({\n condition: \"react-server\",\n config,\n configEnv,\n userOptions,\n autoDiscoveredFiles,\n });\n if (resolvedConfig.type === \"error\") {\n throw resolvedConfig.error;\n }\n\n userConfig = resolvedConfig.userConfig;\n timing.configResolved = Date.now();\n },\n configResolved(config) {\n resolvedConfig = config;\n },\n\n async buildStart() {\n timing.buildStart = Date.now();\n if (userOptions.onEvent && autoDiscoveredFiles) {\n userOptions.onEvent({\n type: \"build.start\",\n data: {\n pages: Array.from(autoDiscoveredFiles.urlMap.keys()),\n files: autoDiscoveredFiles,\n },\n });\n }\n },\n\n async renderStart() {\n timing.renderStart = Date.now();\n },\n\n async writeBundle(options, bundle) {\n try {\n const bundleManifest = getBundleManifest<false>({\n bundle,\n normalizer: userOptions.normalizer,\n });\n if (!(\"source\" in bundleManifest[\".vite/manifest.json\"])) {\n throw new Error(\"Server manifest not found\");\n }\n\n serverManifest = JSON.parse(\n bundleManifest[\".vite/manifest.json\"].source as string\n );\n\n if (!serverManifest) {\n throw new Error(\"Failed to parse server manifest\");\n }\n\n const clientManifestResult = await tryManifest({\n root: userOptions.projectRoot,\n outDir: join(userOptions.build.outDir, userOptions.build.client),\n ssrManifest: false,\n });\n if (clientManifestResult.type === \"error\") {\n throw clientManifestResult.error;\n }\n const clientManifest = clientManifestResult.manifest;\n\n buildLoader = await createBuildLoader(\n {\n userConfig,\n userOptions,\n serverManifest: serverManifest ?? {},\n staticManifest: autoDiscoveredFiles?.staticManifest ?? {},\n clientManifest: clientManifest ?? {},\n },\n bundle\n );\n\n // Create CSS props for each CSS file\n const cssFilesByPage = new Map();\n\n // First collect global styles from index.html\n const globalCssInputs = collectManifestCss(\n autoDiscoveredFiles?.staticManifest ?? {},\n \"index.html\",\n userOptions\n );\n\n const globalCss: Map<string, CssContent> = new Map();\n // Collect CSS files for each page and its props\n for (const [url, { page, props }] of autoDiscoveredFiles?.urlMap ??\n []) {\n const cssInputs = collectManifestCss(\n serverManifest,\n props ? [page, props] : page,\n userOptions\n );\n\n // Create a map for this page's CSS files\n const pageCssMap: Map<string, CssContent> = new Map();\n\n // Add global styles if they exist\n if (Object.keys(globalCssInputs).length > 0) {\n for (const [, value] of Object.entries(globalCssInputs)) {\n const cssContent = await buildLoader(value + \"?inline\").then(\n (r) => String(r.default)\n );\n if (cssContent === \"undefined\") {\n throw new Error(`CSS content is undefined for ${value}`);\n }\n if (cssContent) {\n globalCss.set(\n value,\n createCssProps({\n id: value,\n code: cssContent,\n css: userOptions.css,\n moduleBaseURL: userOptions.moduleBaseURL,\n moduleBasePath: userOptions.moduleBasePath,\n moduleRootPath: userOptions.moduleRootPath,\n projectRoot: userOptions.projectRoot,\n })\n );\n }\n }\n }\n\n // Add page-specific styles\n for (const [, value] of Object.entries(cssInputs)) {\n const { default: cssContent } = await buildLoader(\n value + \"?inline\"\n );\n if (typeof cssContent !== \"string\") {\n continue;\n }\n if (cssContent) {\n pageCssMap.set(\n value,\n createCssProps({\n id: value,\n code: cssContent,\n css: userOptions.css,\n moduleBaseURL: userOptions.moduleBaseURL,\n moduleBasePath: userOptions.moduleBasePath,\n moduleRootPath: userOptions.moduleRootPath,\n projectRoot: userOptions.projectRoot,\n })\n );\n }\n }\n cssFilesByPage.set(url, pageCssMap);\n }\n\n if (userOptions.onEvent) {\n userOptions.onEvent({\n type: \"build.writeBundle\",\n data: {\n pages: Array.from(autoDiscoveredFiles?.urlMap.keys() ?? []),\n options,\n bundle,\n manifest: serverManifest,\n },\n });\n }\n const staticManifest = autoDiscoveredFiles?.staticManifest ?? {};\n const indexHtml = staticManifest?.[\"index.html\"]?.file;\n const pipeableStreamOptions = {\n ...userOptions.pipeableStreamOptions,\n bootstrapModules: [\n ...(indexHtml ? [new URL(indexHtml, userOptions.moduleBaseURL).href] : []),\n ...(userOptions.pipeableStreamOptions?.bootstrapModules ?? []),\n ],\n };\n userOptions.pipeableStreamOptions = pipeableStreamOptions;\n const serializedUserOptions = serializedOptions(\n userOptions,\n autoDiscoveredFiles!\n );\n // Create worker\n if (!worker) {\n const workerResult = await createWorker({\n projectRoot: userOptions.projectRoot,\n workerPath: userOptions.htmlWorkerPath,\n currentCondition: \"react-server\",\n reverseCondition: \"react-client\",\n workerData: {\n resolvedConfig: serializeResolvedConfig(resolvedConfig),\n userOptions: {\n ...serializedUserOptions,\n moduleBasePath: '',\n },\n },\n });\n if (workerResult.type === \"error\") {\n throw workerResult.error;\n } else if (workerResult.type === \"skip\") {\n this.environment.logger.info(\"Worker not created, skipping static build\");\n return;\n } else {\n worker = workerResult.worker;\n }\n }\n // Render pages\n const { onEvent, ...rest } = userOptions;\n const renderPagesGenerator = renderPages(\n autoDiscoveredFiles!,\n {\n ...rest,\n loader: buildLoader,\n worker: worker,\n logger: createLogger(),\n onEvent: async (event: PluginEvent) => {\n if (userOptions.onEvent) {\n userOptions.onEvent(event);\n }\n // Add file write completion event\n if (event.type === \"file.write\") {\n await event.data.onComplete();\n }\n },\n pipeableStreamOptions: pipeableStreamOptions,\n manifest: serverManifest ?? {},\n moduleBasePath: '',\n build: {\n htmlOutputPath: userOptions.build.htmlOutputPath,\n rscOutputPath: userOptions.build.rscOutputPath,\n outDir: userOptions.build.outDir,\n pages: userOptions.build.pages,\n server: userOptions.build.server,\n static: userOptions.build.static,\n client: userOptions.build.client,\n },\n globalCss: globalCss,\n },\n cssFilesByPage,\n );\n\n // Process render results\n let finalResult: RenderPagesResult | undefined;\n for await (const result of renderPagesGenerator) {\n if (result.type === \"error\") {\n throw result.error;\n }\n finalResult = result;\n }\n\n if (!finalResult) {\n throw new Error(\"No render result produced\");\n }\n finalResult.streamMetrics.duration = Math.round(performance.now() - finalResult.streamMetrics.startTime);\n \n this.environment.logger.info(`Rendered ${finalResult.completedRoutes.size} unique routes in ${\n finalResult.streamMetrics.duration\n }ms`);\n\n // Update timing\n timing.render = Date.now() - (timing.renderStart ?? timing.start);\n } catch (error) {\n throw error;\n }\n\n // Cleanup\n try {\n worker.postMessage({ type: \"SHUTDOWN\", id: \"*\" });\n await new Promise<void>((resolve, reject) => {\n const shutdownHandler = (msg: any) => {\n if (msg.type === \"SHUTDOWN_COMPLETE\") {\n worker.removeListener(\"message\", shutdownHandler);\n worker\n .terminate()\n .then((code) =>\n code === 1\n ? resolve()\n : reject(new Error(`Worker terminated with code ${code}`))\n )\n .catch(reject);\n }\n };\n worker.on(\"message\", shutdownHandler);\n });\n } catch (error) {\n throw error;\n }\n },\n } as const;\n}\n"],"names":["resolvedConfig","options"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../../plugin/react-static/plugin.ts"],"sourcesContent":["/**\n * plugin.ts\n *\n * PURPOSE: Main Vite plugin for React Server Components (RSC) static site generation\n *\n * This module:\n * 1. Orchestrates the entire static site generation process\n * 2. Manages the lifecycle of the RSC rendering process\n * 3. Handles file writing for both initial page loads and client-side navigation\n * - Writes .html files for initial page loads (complete HTML document)\n * - Writes .rsc files for client-side navigation (RSC content only)\n * 4. Provides hooks for Vite to integrate with the build process\n * 5. Manages worker threads for parallel rendering\n * 6. Handles error reporting and metrics collection\n */\n\nimport { join } from \"node:path\";\nimport { Worker } from \"node:worker_threads\";\nimport {\n type Manifest,\n type ResolvedConfig,\n type Plugin as VitePlugin,\n createLogger,\n} from \"vite\";\nimport { resolveOptions } from \"../config/resolveOptions.js\";\nimport { resolveUserConfig } from \"../config/resolveUserConfig.js\";\nimport { createBuildLoader } from \"../loader/createBuildLoader.js\";\nimport type {\n BuildTiming,\n ReactStreamPluginMeta,\n ResolvedUserConfig,\n ResolvedUserOptions,\n PluginEvent,\n RenderPagesResult,\n AutoDiscoveredFiles,\n CssContent,\n} from \"../types.js\";\nimport { type StreamPluginOptions } from \"../types.js\";\nimport { renderPages } from \"./renderPages.js\";\nimport { getBundleManifest } from \"../helpers/getBundleManifest.js\";\nimport { createWorker } from \"../worker/createWorker.js\";\nimport { resolveAutoDiscover } from \"../config/resolveAutoDiscover.js\";\nimport { getCondition } from \"../config/getCondition.js\";\nimport {\n serializedOptions,\n serializeResolvedConfig,\n} from \"../helpers/serializeUserOptions.js\";\nimport { collectManifestCss } from \"../helpers/collectManifestCss.js\";\nimport { createCssProps } from \"../helpers/createCssProps.js\";\nimport { tryManifest } from \"../helpers/tryManifest.js\";\n\nif (getCondition() !== \"react-server\") {\n throw new Error(\n \"Condition mismatch, should be react-server but got \" +\n process.env[\"NODE_OPTIONS\"]\n );\n}\n\nlet worker: Worker;\nlet userConfig: ResolvedUserConfig;\nlet resolvedConfig: ResolvedConfig;\nlet userOptions: ResolvedUserOptions;\nlet autoDiscoveredFiles: AutoDiscoveredFiles | null = null;\nlet serverManifest: Manifest | undefined = undefined;\nlet buildLoader: Awaited<ReturnType<typeof createBuildLoader>> | undefined;\n\nexport function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{\n meta: ReactStreamPluginMeta;\n}> {\n const timing: BuildTiming = {\n start: Date.now(),\n configResolved: 0,\n buildStart: 0,\n renderStart: 0,\n };\n\n const resolvedOptions = resolveOptions(options);\n if (resolvedOptions.type === \"error\") {\n throw resolvedOptions.error;\n }\n userOptions = resolvedOptions.userOptions;\n\n return {\n name: \"vite:plugin-react-server/static\",\n enforce: \"post\",\n api: {\n meta: { timing },\n },\n\n async config(config, configEnv) {\n if (config.root && config.root !== userOptions.projectRoot) {\n userOptions.projectRoot = config.root;\n }\n\n const autoDiscoverResult = await resolveAutoDiscover({\n config,\n configEnv,\n userOptions,\n condition: \"react-server\",\n });\n if (autoDiscoverResult.type === \"error\") {\n throw autoDiscoverResult.error;\n }\n autoDiscoveredFiles = autoDiscoverResult.autoDiscoveredFiles;\n\n const resolvedConfig = resolveUserConfig({\n condition: \"react-server\",\n config,\n configEnv,\n userOptions,\n autoDiscoveredFiles,\n });\n if (resolvedConfig.type === \"error\") {\n throw resolvedConfig.error;\n }\n\n userConfig = resolvedConfig.userConfig;\n timing.configResolved = Date.now();\n },\n configResolved(config) {\n resolvedConfig = config;\n },\n\n async buildStart() {\n timing.buildStart = Date.now();\n if (userOptions.onEvent && autoDiscoveredFiles) {\n userOptions.onEvent({\n type: \"build.start\",\n data: {\n pages: Array.from(autoDiscoveredFiles.urlMap.keys()),\n files: autoDiscoveredFiles,\n },\n });\n }\n },\n\n async renderStart() {\n timing.renderStart = Date.now();\n },\n\n\n async writeBundle(options, bundle) {\n try {\n const bundleManifest = getBundleManifest<false>({\n bundle,\n normalizer: userOptions.normalizer,\n });\n if (!(\"source\" in bundleManifest[\".vite/manifest.json\"])) {\n throw new Error(\"Server manifest not found\");\n }\n\n serverManifest = JSON.parse(\n bundleManifest[\".vite/manifest.json\"].source as string\n );\n\n if (!serverManifest) {\n throw new Error(\"Failed to parse server manifest\");\n }\n\n const clientManifestResult = await tryManifest({\n root: userOptions.projectRoot,\n outDir: join(\n userOptions.build.outDir,\n userOptions.build.client,\n userOptions.moduleBasePath\n ),\n ssrManifest: false,\n });\n if (clientManifestResult.type === \"error\") {\n throw clientManifestResult.error;\n }\n const clientManifest = clientManifestResult.manifest;\n\n buildLoader = await createBuildLoader(\n {\n userConfig,\n userOptions,\n serverManifest: serverManifest ?? {},\n staticManifest: autoDiscoveredFiles?.staticManifest ?? {},\n clientManifest: clientManifest ?? {},\n },\n bundle\n );\n\n // Create CSS props for each CSS file\n const cssFilesByPage = new Map();\n\n // First collect global styles from index.html\n const globalCssInputs = collectManifestCss(\n autoDiscoveredFiles?.staticManifest ?? {},\n \"index.html\",\n userOptions\n );\n\n const globalCss: Map<string, CssContent> = new Map();\n // Collect CSS files for each page and its props\n for (const [url, { page, props }] of autoDiscoveredFiles?.urlMap ??\n []) {\n const cssInputs = collectManifestCss(\n serverManifest,\n props ? [page, props] : page,\n userOptions\n );\n\n // Create a map for this page's CSS files\n const pageCssMap: Map<string, CssContent> = new Map();\n\n // Add global styles if they exist\n if (Object.keys(globalCssInputs).length > 0) {\n for (const [, value] of Object.entries(globalCssInputs)) {\n const cssContent = await buildLoader(value + \"?inline\").then(\n (r) => String(r.default)\n );\n if (cssContent === \"undefined\") {\n throw new Error(`CSS content is undefined for ${value}`);\n }\n if (cssContent) {\n globalCss.set(\n value,\n createCssProps({\n id: value,\n code: cssContent,\n css: userOptions.css,\n moduleBaseURL: userOptions.moduleBaseURL,\n moduleBasePath: userOptions.moduleBasePath,\n moduleRootPath: userOptions.moduleRootPath,\n projectRoot: userOptions.projectRoot,\n })\n );\n }\n }\n }\n\n // Add page-specific styles\n for (const [, value] of Object.entries(cssInputs)) {\n const { default: cssContent } = await buildLoader(\n value + \"?inline\"\n );\n if (typeof cssContent !== \"string\") {\n continue;\n }\n if (cssContent) {\n pageCssMap.set(\n value,\n createCssProps({\n id: value,\n code: cssContent,\n css: userOptions.css,\n moduleBaseURL: userOptions.moduleBaseURL,\n moduleBasePath: userOptions.moduleBasePath,\n moduleRootPath: userOptions.moduleRootPath,\n projectRoot: userOptions.projectRoot,\n })\n );\n }\n }\n cssFilesByPage.set(url, pageCssMap);\n }\n\n if (userOptions.onEvent) {\n userOptions.onEvent({\n type: \"build.writeBundle\",\n data: {\n pages: Array.from(autoDiscoveredFiles?.urlMap.keys() ?? []),\n options,\n bundle,\n manifest: serverManifest,\n },\n });\n }\n const staticManifest = autoDiscoveredFiles?.staticManifest ?? {};\n const indexHtml = staticManifest?.[\"index.html\"]?.file;\n const pipeableStreamOptions = {\n ...userOptions.pipeableStreamOptions,\n bootstrapModules: [\n ...(indexHtml\n ? [\n userOptions.moduleBaseURL !== \"\"\n ? new URL(\n join(userOptions.moduleBasePath, indexHtml),\n userOptions.moduleBaseURL\n ).href\n : join(userOptions.moduleBasePath, indexHtml),\n ]\n : []),\n ...(userOptions.pipeableStreamOptions?.bootstrapModules ?? []),\n ],\n };\n userOptions.pipeableStreamOptions = pipeableStreamOptions;\n const serializedUserOptions = serializedOptions(\n userOptions,\n autoDiscoveredFiles!\n );\n // Create worker\n if (!worker) {\n const viteEnvPrefix = typeof resolvedConfig.envPrefix === 'string' ? resolvedConfig.envPrefix : Array.isArray(resolvedConfig.envPrefix) ? resolvedConfig.envPrefix[0] : 'VITE_'\n const workerResult = await createWorker({\n projectRoot: userOptions.projectRoot,\n workerPath: userOptions.htmlWorkerPath,\n currentCondition: \"react-server\",\n reverseCondition: \"react-client\",\n envPrefix: viteEnvPrefix,\n workerData: {\n resolvedConfig: serializeResolvedConfig(resolvedConfig),\n userOptions: {\n ...serializedUserOptions,\n },\n },\n });\n if (workerResult.type === \"error\") {\n throw workerResult.error;\n } else if (workerResult.type === \"skip\") {\n this.environment.logger.info(\n \"Worker not created, skipping static build\"\n );\n return;\n } else {\n worker = workerResult.worker;\n }\n }\n // Render pages\n const { onEvent, ...handlerOptions } = userOptions;\n const renderPagesGenerator = renderPages(\n autoDiscoveredFiles!,\n {\n ...handlerOptions,\n loader: buildLoader,\n worker: worker,\n logger: createLogger(),\n onEvent: async (event: PluginEvent) => {\n if (userOptions.onEvent) {\n userOptions.onEvent(event);\n }\n // Add file write completion event\n if (event.type === \"file.write\") {\n await event.data.onComplete();\n }\n },\n pipeableStreamOptions: pipeableStreamOptions,\n manifest: serverManifest ?? {},\n build: {\n htmlOutputPath: userOptions.build.htmlOutputPath,\n rscOutputPath: userOptions.build.rscOutputPath,\n outDir: userOptions.build.outDir,\n pages: userOptions.build.pages,\n server: userOptions.build.server,\n static: userOptions.build.static,\n client: userOptions.build.client,\n },\n globalCss: globalCss,\n },\n cssFilesByPage\n );\n\n // Process render results\n let finalResult: RenderPagesResult | undefined;\n for await (const result of renderPagesGenerator) {\n if (result.type === \"error\") {\n throw result.error;\n }\n finalResult = result;\n }\n\n if (!finalResult) {\n throw new Error(\"No render result produced\");\n }\n finalResult.streamMetrics.duration = Math.round(\n performance.now() - finalResult.streamMetrics.startTime\n );\n\n this.environment.logger.info(\n `Rendered ${finalResult.completedRoutes.size} unique routes in ${finalResult.streamMetrics.duration}ms`\n );\n\n // Update timing\n timing.render = Date.now() - (timing.renderStart ?? timing.start);\n } catch (error) {\n throw error;\n }\n\n // Cleanup\n try {\n worker.postMessage({ type: \"SHUTDOWN\", id: \"*\" });\n await new Promise<void>((resolve, reject) => {\n const shutdownHandler = (msg: any) => {\n if (msg.type === \"SHUTDOWN_COMPLETE\") {\n worker.removeListener(\"message\", shutdownHandler);\n worker\n .terminate()\n .then((code) =>\n code === 1\n ? resolve()\n : reject(new Error(`Worker terminated with code ${code}`))\n )\n .catch(reject);\n }\n };\n worker.on(\"message\", shutdownHandler);\n });\n } catch (error) {\n throw error;\n }\n },\n } as const;\n}\n"],"names":["resolvedConfig","options"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderPage.d.ts","sourceRoot":"","sources":["../../../plugin/react-static/renderPage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK1E,wBAAuB,UAAU,CAC/B,cAAc,EAAE,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAC1E,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"renderPage.d.ts","sourceRoot":"","sources":["../../../plugin/react-static/renderPage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK1E,wBAAuB,UAAU,CAC/B,cAAc,EAAE,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAC1E,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC,CA4IjD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderPage.js","sources":["../../../plugin/react-static/renderPage.ts"],"sourcesContent":["import { createRenderMetrics } from \"../helpers/metrics.js\";\nimport { resolvePageAndProps } from \"../helpers/resolvePageAndProps.js\";\nimport type { CreateHandlerOptions, RenderPageResult } from \"../types.js\";\nimport { renderStreams } from \"./renderStreams.js\";\nimport { collectHtmlWorkerContent } from \"./collectHtmlWorkerContent.js\";\nimport { collectRscContent } from \"./collectRscContent.js\";\n\nexport async function* renderPage(\n handlerOptions: CreateHandlerOptions<unknown, React.ComponentType<unknown>>\n): AsyncGenerator<RenderPageResult, void, unknown> {\n if (!handlerOptions.pagePath) {\n yield {\n type: \"skip\",\n };\n return;\n }\n\n try {\n const metrics = createRenderMetrics(handlerOptions.route);\n\n const pageAndPropsResult = await resolvePageAndProps(handlerOptions);\n\n if (pageAndPropsResult.type === \"error\") {\n yield {\n type: \"error\",\n error: pageAndPropsResult.error,\n };\n return;\n }\n\n if (pageAndPropsResult.type === \"skip\") {\n yield {\n type: \"skip\",\n };\n return;\n }\n\n const { PageComponent, pageProps } = pageAndPropsResult;\n\n const newHandlerOptions = {\n ...handlerOptions,\n PageComponent: PageComponent,\n pageProps: pageProps,\n } satisfies CreateHandlerOptions;\n // Create streams with CSS files\n const [rscFull, rscHeadless] = await renderStreams(newHandlerOptions);\n
|
|
1
|
+
{"version":3,"file":"renderPage.js","sources":["../../../plugin/react-static/renderPage.ts"],"sourcesContent":["import { createRenderMetrics } from \"../helpers/metrics.js\";\nimport { resolvePageAndProps } from \"../helpers/resolvePageAndProps.js\";\nimport type { CreateHandlerOptions, RenderPageResult } from \"../types.js\";\nimport { renderStreams } from \"./renderStreams.js\";\nimport { collectHtmlWorkerContent } from \"./collectHtmlWorkerContent.js\";\nimport { collectRscContent } from \"./collectRscContent.js\";\n\nexport async function* renderPage(\n handlerOptions: CreateHandlerOptions<unknown, React.ComponentType<unknown>>\n): AsyncGenerator<RenderPageResult, void, unknown> {\n if (!handlerOptions.pagePath) {\n yield {\n type: \"skip\",\n };\n return;\n }\n\n try {\n const metrics = createRenderMetrics(handlerOptions.route);\n\n const pageAndPropsResult = await resolvePageAndProps(handlerOptions);\n\n if (pageAndPropsResult.type === \"error\") {\n yield {\n type: \"error\",\n error: pageAndPropsResult.error,\n };\n return;\n }\n\n if (pageAndPropsResult.type === \"skip\") {\n yield {\n type: \"skip\",\n };\n return;\n }\n\n const { PageComponent, pageProps } = pageAndPropsResult;\n\n const newHandlerOptions = {\n ...handlerOptions,\n PageComponent: PageComponent,\n pageProps: pageProps,\n } satisfies CreateHandlerOptions;\n // Create streams with CSS files\n const [rscFull, rscHeadless] = await renderStreams(newHandlerOptions);\n // Handle stream creation errors\n if (rscFull.type !== \"success\") {\n yield {\n type: \"error\",\n error: new Error(\n rscFull.type === \"error\"\n ? `Failed to create RSC full stream: ${\n rscFull.error instanceof Error\n ? rscFull.error.message\n : String(rscFull.error)\n }`\n : \"RSC full stream creation was skipped\"\n ),\n };\n return;\n }\n\n if (!rscFull.stream) {\n yield {\n type: \"error\",\n error: new Error(\"RSC full stream is undefined\"),\n };\n return;\n }\n\n if (rscHeadless.type !== \"success\") {\n yield {\n type: \"error\",\n error: new Error(\n rscHeadless.type === \"error\"\n ? `Failed to create RSC headless stream: ${\n rscHeadless.error instanceof Error\n ? rscHeadless.error.message\n : String(rscHeadless.error)\n }`\n : \"RSC headless stream creation was skipped\"\n ),\n };\n return;\n }\n\n if (!rscHeadless.stream) {\n yield {\n type: \"error\",\n error: new Error(\"RSC headless stream is undefined\"),\n };\n return;\n }\n\n // Collect HTML and RSC content\n const [\n { stream: rscStream, metrics: rscMetrics },\n { stream: htmlStream, metrics: htmlMetrics },\n ] = await Promise.all([\n collectRscContent(rscHeadless.stream, handlerOptions),\n collectHtmlWorkerContent(rscFull.stream, handlerOptions),\n ]);\n\n // Update metrics\n metrics.htmlSizes.set(handlerOptions.route, htmlMetrics.bytes);\n metrics.rscSizes.set(handlerOptions.route, rscMetrics.bytes);\n metrics.htmlSize = htmlMetrics.bytes;\n metrics.rscSize = rscMetrics.bytes;\n\n // Combine metrics from both streams\n metrics.streamMetrics = {\n ...htmlMetrics,\n chunks: Math.max(htmlMetrics.chunks, rscMetrics.chunks),\n bytes: Math.max(htmlMetrics.bytes, rscMetrics.bytes),\n duration: Math.max(htmlMetrics.duration, rscMetrics.duration),\n startTime: Math.min(htmlMetrics.startTime, rscMetrics.startTime),\n };\n\n metrics.processingTime = metrics.streamMetrics.duration;\n metrics.chunks = metrics.streamMetrics.chunks;\n metrics.chunkRate =\n metrics.streamMetrics.chunks / (metrics.processingTime / 1000);\n\n // Emit metrics via callback\n if (handlerOptions.onMetrics) {\n handlerOptions.onMetrics(metrics);\n }\n\n yield {\n type: \"success\",\n html: htmlStream,\n rsc: rscStream,\n metrics: {\n rscFull: htmlMetrics,\n rscHeadless: rscMetrics,\n },\n } as const;\n } catch (err) {\n yield {\n type: \"error\",\n error:\n err instanceof Error\n ? err\n : typeof err === \"string\"\n ? new Error(err)\n : (err as Error),\n };\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.client.d.ts","sourceRoot":"","sources":["../../../plugin/transformer/plugin.client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAuB,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AA+BlD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"plugin.client.d.ts","sourceRoot":"","sources":["../../../plugin/transformer/plugin.client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAuB,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AA+BlD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAqFzE"}
|
|
@@ -16,6 +16,15 @@ function reactTransformPlugin(options) {
|
|
|
16
16
|
if (resolvedOptionsResult.type === "error") throw resolvedOptionsResult.error;
|
|
17
17
|
userOptions = resolvedOptionsResult.userOptions;
|
|
18
18
|
let staticManifest;
|
|
19
|
+
const getID = (id) => {
|
|
20
|
+
if (userOptions.moduleBasePath !== "" && !id.startsWith(userOptions.moduleBasePath)) {
|
|
21
|
+
id = join(userOptions.moduleBasePath, id);
|
|
22
|
+
}
|
|
23
|
+
if (!id.startsWith("/")) {
|
|
24
|
+
id = "/" + id;
|
|
25
|
+
}
|
|
26
|
+
return id;
|
|
27
|
+
};
|
|
19
28
|
return {
|
|
20
29
|
name: "vite:react-server-action-transform",
|
|
21
30
|
enforce: "pre",
|
|
@@ -52,13 +61,14 @@ function reactTransformPlugin(options) {
|
|
|
52
61
|
}
|
|
53
62
|
if (isServer && isBuild) {
|
|
54
63
|
const [key] = userOptions.normalizer(id);
|
|
55
|
-
id =
|
|
64
|
+
id = key + ".js";
|
|
56
65
|
}
|
|
57
|
-
const
|
|
66
|
+
const finalID = getID(id);
|
|
67
|
+
const transformed = await transformModuleIfNeeded(code, finalID, null);
|
|
58
68
|
if (!transformed) return null;
|
|
59
69
|
return {
|
|
60
70
|
code: transformed,
|
|
61
|
-
id,
|
|
71
|
+
id: finalID,
|
|
62
72
|
map: null
|
|
63
73
|
};
|
|
64
74
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.client.js","sources":["../../../plugin/transformer/plugin.client.ts"],"sourcesContent":["import { resolveOptions } from \"../config/resolveOptions.js\";\nimport type { ResolvedUserOptions, StreamPluginOptions } from \"../types.js\";\nimport { type Manifest, type Plugin } from \"vite\";\nimport { transformModuleIfNeeded } from \"../loader/react-loader.js\";\nimport { join } from \"node:path\";\nimport { tryManifest } from \"../helpers/tryManifest.js\";\n\n/**\n * Plugin for transforming server actions for the client build.\n *\n * Core responsibilities:\n * 1. Transforms \"use server\" directives\n * 2. Transforms server actions for the client build\n * 3. Uses react-loader's transformModuleIfNeeded to create a server action reference\n *\n * When a component is marked with \"use server\", it:\n * - Gets transformed into a server action\n * - Maintains module ID for RSC boundaries\n * - Preserves class/function behavior\n *\n * @example\n * ```ts\n * export default defineConfig({\n * plugins: [\n * viteReactClientTransformPlugin({\n * projectRoot: process.cwd(),\n * })\n * ]\n * });\n * ```\n */\nlet isBuild = true;\n\nexport function reactTransformPlugin(options: StreamPluginOptions): Plugin {\n let userOptions: ResolvedUserOptions;\n const resolvedOptionsResult = resolveOptions(options);\n if (resolvedOptionsResult.type === \"error\") throw resolvedOptionsResult.error;\n userOptions = resolvedOptionsResult.userOptions;\n let staticManifest: Manifest;\n return {\n name: \"vite:react-server-action-transform\",\n enforce: \"pre\",\n async config(_, configEnv) {\n isBuild = configEnv.command !== \"serve\";\n if (!configEnv.isSsrBuild) {\n staticManifest = {};\n } else {\n const staticManifestResult = await tryManifest({\n root: userOptions.projectRoot,\n ssrManifest: false,\n outDir: join(userOptions.build.outDir, userOptions.build.static),\n });\n if (staticManifestResult.type === \"error\") {\n staticManifest = {};\n } else {\n staticManifest = staticManifestResult.manifest;\n }\n }\n },\n async transform(code, id, options) {\n const ssr = options?.ssr;\n const isServer = code.match('\"use server\"') !== null;\n const isClient = code.match('\"use client\"') !== null;\n if (!ssr) return null;\n if (!isServer && !isClient) return null;\n if (isServer && isClient) {\n throw new Error(\n \"Server and client components cannot be used in the same file\"\n );\n }\n if (isClient) {\n return null;\n }\n if (isServer && isBuild) {\n const [key] = userOptions.normalizer(id);\n id =
|
|
1
|
+
{"version":3,"file":"plugin.client.js","sources":["../../../plugin/transformer/plugin.client.ts"],"sourcesContent":["import { resolveOptions } from \"../config/resolveOptions.js\";\nimport type { ResolvedUserOptions, StreamPluginOptions } from \"../types.js\";\nimport { type Manifest, type Plugin } from \"vite\";\nimport { transformModuleIfNeeded } from \"../loader/react-loader.js\";\nimport { join } from \"node:path\";\nimport { tryManifest } from \"../helpers/tryManifest.js\";\n\n/**\n * Plugin for transforming server actions for the client build.\n *\n * Core responsibilities:\n * 1. Transforms \"use server\" directives\n * 2. Transforms server actions for the client build\n * 3. Uses react-loader's transformModuleIfNeeded to create a server action reference\n *\n * When a component is marked with \"use server\", it:\n * - Gets transformed into a server action\n * - Maintains module ID for RSC boundaries\n * - Preserves class/function behavior\n *\n * @example\n * ```ts\n * export default defineConfig({\n * plugins: [\n * viteReactClientTransformPlugin({\n * projectRoot: process.cwd(),\n * })\n * ]\n * });\n * ```\n */\nlet isBuild = true;\n\nexport function reactTransformPlugin(options: StreamPluginOptions): Plugin {\n let userOptions: ResolvedUserOptions;\n const resolvedOptionsResult = resolveOptions(options);\n if (resolvedOptionsResult.type === \"error\") throw resolvedOptionsResult.error;\n userOptions = resolvedOptionsResult.userOptions;\n let staticManifest: Manifest;\n const getID = (id: string) => {\n if(userOptions.moduleBasePath !== '' && !id.startsWith(userOptions.moduleBasePath)) {\n id = join(userOptions.moduleBasePath, id);\n }\n if(!id.startsWith('/')) {\n id = '/' + id;\n }\n return id;\n }\n return {\n name: \"vite:react-server-action-transform\",\n enforce: \"pre\",\n async config(_, configEnv) {\n isBuild = configEnv.command !== \"serve\";\n if (!configEnv.isSsrBuild) {\n staticManifest = {};\n } else {\n const staticManifestResult = await tryManifest({\n root: userOptions.projectRoot,\n ssrManifest: false,\n outDir: join(userOptions.build.outDir, userOptions.build.static),\n });\n if (staticManifestResult.type === \"error\") {\n staticManifest = {};\n } else {\n staticManifest = staticManifestResult.manifest;\n }\n }\n },\n async transform(code, id, options) {\n const ssr = options?.ssr;\n const isServer = code.match('\"use server\"') !== null;\n const isClient = code.match('\"use client\"') !== null;\n if (!ssr) return null;\n if (!isServer && !isClient) return null;\n if (isServer && isClient) {\n throw new Error(\n \"Server and client components cannot be used in the same file\"\n );\n }\n if (isClient) {\n return null;\n }\n if (isServer && isBuild) {\n const [key] = userOptions.normalizer(id);\n id = key + \".js\";\n }\n const finalID = getID(id);\n const transformed = await transformModuleIfNeeded(code, finalID, null);\n if (!transformed) return null;\n return {\n code: transformed,\n id: finalID,\n map: null,\n };\n },\n renderChunk(code, chunk, _options) {\n // Only process client components\n if (!chunk.fileName.includes(\".client\")) return null;\n\n // Get the original file name without extension\n const originalName = chunk.fileName.replace(\".js\", \"\");\n\n // Find matching entry in static manifest\n const manifestEntry = Object.entries(staticManifest).find(([_, info]) =>\n info.file.startsWith(originalName)\n );\n\n if (manifestEntry) {\n // Use the static manifest's file name\n return {\n code,\n fileName: manifestEntry[1].file,\n };\n }\n\n return null;\n },\n };\n}\n"],"names":["options"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.server.d.ts","sourceRoot":"","sources":["../../../plugin/transformer/plugin.server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAuB,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAY,MAAM,EAAE,MAAM,MAAM,CAAC;AA8B7C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"plugin.server.d.ts","sourceRoot":"","sources":["../../../plugin/transformer/plugin.server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAuB,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAY,MAAM,EAAE,MAAM,MAAM,CAAC;AA8B7C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA2EzE"}
|
|
@@ -15,6 +15,15 @@ function reactTransformPlugin(options) {
|
|
|
15
15
|
if (resolvedOptionsResult.type === "error") throw resolvedOptionsResult.error;
|
|
16
16
|
userOptions = resolvedOptionsResult.userOptions;
|
|
17
17
|
let staticManifest;
|
|
18
|
+
const getID = (id) => {
|
|
19
|
+
if (userOptions.moduleBasePath !== "" && !id.startsWith(userOptions.moduleBasePath)) {
|
|
20
|
+
id = join(userOptions.moduleBasePath, id);
|
|
21
|
+
}
|
|
22
|
+
if (!id.startsWith("/")) {
|
|
23
|
+
id = "/" + id;
|
|
24
|
+
}
|
|
25
|
+
return id;
|
|
26
|
+
};
|
|
18
27
|
return {
|
|
19
28
|
name: "vite:react-server-transform",
|
|
20
29
|
enforce: "pre",
|
|
@@ -41,7 +50,7 @@ function reactTransformPlugin(options) {
|
|
|
41
50
|
const [key, value] = userOptions.normalizer(id);
|
|
42
51
|
if (staticManifest) {
|
|
43
52
|
if (value in staticManifest) {
|
|
44
|
-
id =
|
|
53
|
+
id = staticManifest[value].file;
|
|
45
54
|
} else {
|
|
46
55
|
const hash = this.emitFile({
|
|
47
56
|
id,
|
|
@@ -50,15 +59,16 @@ function reactTransformPlugin(options) {
|
|
|
50
59
|
name: value
|
|
51
60
|
});
|
|
52
61
|
const fileName = this.getFileName(hash);
|
|
53
|
-
id =
|
|
62
|
+
id = fileName;
|
|
54
63
|
}
|
|
55
64
|
} else {
|
|
56
65
|
throw new Error(`Client manifest not found.`);
|
|
57
66
|
}
|
|
58
67
|
}
|
|
68
|
+
const finalID = getID(id);
|
|
59
69
|
const transformed = await transformModuleIfNeeded(
|
|
60
70
|
code,
|
|
61
|
-
|
|
71
|
+
finalID,
|
|
62
72
|
// Pass null for nextLoad since we don't need module loading in the plugin
|
|
63
73
|
null
|
|
64
74
|
);
|