vite-plugin-react-server 0.3.18 → 0.3.19
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/README.md +119 -118
- package/bin/patch.mjs +8 -2
- package/dist/package.json +3 -3
- package/dist/plugin/checkFilesExist.d.ts.map +1 -1
- package/dist/plugin/checkFilesExist.js +6 -2
- package/dist/plugin/checkFilesExist.js.map +1 -1
- package/dist/plugin/collect-manifest-client-files.d.ts +23 -0
- package/dist/plugin/collect-manifest-client-files.d.ts.map +1 -0
- package/dist/plugin/collect-manifest-client-files.js +117 -0
- package/dist/plugin/collect-manifest-client-files.js.map +1 -0
- package/dist/plugin/components.d.ts +9 -9
- package/dist/plugin/components.d.ts.map +1 -1
- package/dist/plugin/components.js +50 -9
- package/dist/plugin/components.js.map +1 -0
- package/dist/plugin/config/defaults.d.ts +7 -6
- package/dist/plugin/config/defaults.d.ts.map +1 -1
- package/dist/plugin/config/defaults.js +8 -5
- package/dist/plugin/config/defaults.js.map +1 -1
- package/dist/plugin/config/getPaths.d.ts +0 -1
- package/dist/plugin/config/getPaths.d.ts.map +1 -1
- package/dist/plugin/config/getPaths.js +2 -7
- package/dist/plugin/config/getPaths.js.map +1 -1
- package/dist/plugin/config/mimeTypes.d.ts +2 -0
- package/dist/plugin/config/mimeTypes.d.ts.map +1 -0
- package/dist/plugin/config/mimeTypes.js +24 -0
- package/dist/plugin/config/mimeTypes.js.map +1 -0
- package/dist/plugin/config/resolveOptions.d.ts +1 -1
- package/dist/plugin/config/resolveOptions.d.ts.map +1 -1
- package/dist/plugin/config/resolveOptions.js +41 -28
- package/dist/plugin/config/resolveOptions.js.map +1 -1
- package/dist/plugin/config/resolvePages.d.ts +1 -0
- package/dist/plugin/config/resolvePages.d.ts.map +1 -1
- package/dist/plugin/config/resolvePages.js +9 -5
- package/dist/plugin/config/resolvePages.js.map +1 -1
- package/dist/plugin/config/resolveUserConfig.d.ts +2 -1
- package/dist/plugin/config/resolveUserConfig.d.ts.map +1 -1
- package/dist/plugin/config/resolveUserConfig.js +10 -5
- package/dist/plugin/config/resolveUserConfig.js.map +1 -1
- package/dist/plugin/copy-dir.js +23 -18
- package/dist/plugin/copy-dir.js.map +1 -0
- package/dist/plugin/helpers/createHandler.d.ts +22 -0
- package/dist/plugin/helpers/createHandler.d.ts.map +1 -0
- package/dist/plugin/{react-server → helpers}/createHandler.js +36 -48
- package/dist/plugin/helpers/createHandler.js.map +1 -0
- package/dist/plugin/{react-server → helpers}/createRscStream.d.ts +2 -1
- package/dist/plugin/helpers/createRscStream.d.ts.map +1 -0
- package/dist/plugin/helpers/createRscStream.js +71 -0
- package/dist/plugin/helpers/createRscStream.js.map +1 -0
- package/dist/plugin/helpers/getBundleManifest.d.ts.map +1 -1
- package/dist/plugin/helpers/getBundleManifest.js +12 -4
- package/dist/plugin/helpers/getBundleManifest.js.map +1 -1
- package/dist/plugin/loader/createBuildLoader.d.ts +1 -1
- package/dist/plugin/loader/createBuildLoader.d.ts.map +1 -1
- package/dist/plugin/loader/createBuildLoader.js +8 -5
- package/dist/plugin/loader/createBuildLoader.js.map +1 -1
- package/dist/plugin/loader/css-loader.d.ts.map +1 -1
- package/dist/plugin/loader/css-loader.js.map +1 -1
- package/dist/plugin/loader/react-loader.js +2 -2
- package/dist/plugin/loader/react-loader.js.map +1 -1
- package/dist/plugin/preserver/plugin.d.ts.map +1 -1
- package/dist/plugin/preserver/plugin.js +49 -14
- package/dist/plugin/preserver/plugin.js.map +1 -1
- package/dist/plugin/react-client/plugin.d.ts.map +1 -1
- package/dist/plugin/react-client/plugin.js +18 -76
- package/dist/plugin/react-client/plugin.js.map +1 -1
- package/dist/plugin/react-server/index.d.ts.map +1 -1
- package/dist/plugin/react-server/index.js +2 -0
- package/dist/plugin/react-server/index.js.map +1 -1
- package/dist/plugin/react-server/plugin.d.ts +2 -1
- package/dist/plugin/react-server/plugin.d.ts.map +1 -1
- package/dist/plugin/react-server/plugin.js +53 -217
- package/dist/plugin/react-server/plugin.js.map +1 -1
- package/dist/plugin/react-static/index.d.ts +2 -0
- package/dist/plugin/react-static/index.d.ts.map +1 -0
- package/dist/plugin/react-static/index.js +1 -0
- package/dist/plugin/react-static/plugin.d.ts +7 -0
- package/dist/plugin/react-static/plugin.d.ts.map +1 -0
- package/dist/plugin/react-static/plugin.js +199 -0
- package/dist/plugin/react-static/plugin.js.map +1 -0
- package/dist/plugin/resolvePage.d.ts.map +1 -1
- package/dist/plugin/resolvePage.js +9 -0
- package/dist/plugin/resolvePage.js.map +1 -1
- package/dist/plugin/root.d.ts +2 -0
- package/dist/plugin/root.d.ts.map +1 -0
- package/dist/plugin/root.js +12 -0
- package/dist/plugin/root.js.map +1 -0
- package/dist/plugin/transformer/plugin.d.ts.map +1 -1
- package/dist/plugin/transformer/plugin.js +32 -23
- package/dist/plugin/transformer/plugin.js.map +1 -1
- package/dist/plugin/transformer/types.d.ts +1 -18
- package/dist/plugin/transformer/types.d.ts.map +1 -1
- package/dist/plugin/types.d.ts +24 -6
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/plugin/worker/createWorker.js +0 -1
- package/dist/plugin/worker/createWorker.js.map +1 -1
- package/dist/plugin/worker/html/html-worker.development.d.ts +30 -0
- package/dist/plugin/worker/html/html-worker.development.d.ts.map +1 -1
- package/dist/plugin/worker/html/html-worker.development.js +30 -2
- package/dist/plugin/worker/html/html-worker.development.js.map +1 -1
- package/dist/plugin/worker/html/html-worker.production.js +3 -5
- package/dist/plugin/worker/html/html-worker.production.js.map +1 -1
- package/dist/plugin/worker/html/messageHandler.d.ts.map +1 -1
- package/dist/plugin/worker/html/messageHandler.js +8 -2
- package/dist/plugin/worker/html/messageHandler.js.map +1 -1
- package/dist/plugin/worker/html/plugin.d.ts.map +1 -1
- package/dist/plugin/worker/html/plugin.js +2 -3
- package/dist/plugin/worker/html/renderPages.d.ts +8 -4
- package/dist/plugin/worker/html/renderPages.d.ts.map +1 -1
- package/dist/plugin/worker/html/renderPages.js +118 -83
- package/dist/plugin/worker/html/renderPages.js.map +1 -1
- package/dist/plugin/worker/rsc/messageHandler.d.ts.map +1 -1
- package/dist/plugin/worker/rsc/messageHandler.js +89 -84
- package/dist/plugin/worker/rsc/messageHandler.js.map +1 -1
- package/dist/plugin/worker/rsc/plugin.d.ts.map +1 -1
- package/dist/plugin/worker/rsc/plugin.js +1 -2
- package/dist/plugin/worker/rsc/rsc-worker.development.js +13 -18
- package/dist/plugin/worker/rsc/rsc-worker.development.js.map +1 -1
- package/dist/plugin/worker/rsc/rsc-worker.production.js +4 -1
- package/dist/plugin/worker/rsc/rsc-worker.production.js.map +1 -1
- package/dist/plugin/worker/rsc/state.d.ts.map +1 -1
- package/dist/plugin/worker/rsc/state.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/plugin/checkFilesExist.ts +7 -3
- package/plugin/collect-manifest-client-files.ts +152 -0
- package/plugin/components.tsx +55 -10
- package/plugin/config/defaults.tsx +69 -0
- package/plugin/config/getPaths.ts +1 -7
- package/plugin/config/mimeTypes.ts +17 -0
- package/plugin/config/resolveOptions.ts +48 -40
- package/plugin/config/resolvePages.ts +8 -4
- package/plugin/config/resolveUserConfig.ts +12 -9
- package/plugin/{react-server → helpers}/createHandler.ts +46 -63
- package/plugin/helpers/createRscStream.ts +81 -0
- package/plugin/helpers/getBundleManifest.ts +14 -5
- package/plugin/loader/createBuildLoader.ts +9 -6
- package/plugin/loader/css-loader.ts +0 -2
- package/plugin/loader/react-loader.ts +2 -2
- package/plugin/preserver/plugin.ts +64 -17
- package/plugin/react-client/plugin.ts +20 -91
- package/plugin/react-server/index.ts +2 -0
- package/plugin/react-server/plugin.ts +66 -293
- package/plugin/react-static/index.ts +1 -0
- package/plugin/react-static/plugin.ts +247 -0
- package/plugin/resolvePage.ts +9 -0
- package/plugin/root.ts +4 -0
- package/plugin/transformer/plugin.ts +40 -31
- package/plugin/transformer/types.ts +0 -19
- package/plugin/types.ts +25 -6
- package/plugin/worker/createWorker.ts +1 -1
- package/plugin/worker/html/README.md +63 -0
- package/plugin/worker/html/html-worker.development.tsx +89 -2
- package/plugin/worker/html/html-worker.production.tsx +8 -10
- package/plugin/worker/html/messageHandler.ts +8 -2
- package/plugin/worker/html/plugin.ts +2 -3
- package/plugin/worker/html/renderPages.ts +150 -114
- package/plugin/worker/rsc/README.md +58 -0
- package/plugin/worker/rsc/messageHandler.tsx +95 -111
- package/plugin/worker/rsc/plugin.ts +1 -2
- package/plugin/worker/rsc/rsc-worker.development.ts +12 -22
- package/plugin/worker/rsc/rsc-worker.production.ts +5 -1
- package/plugin/worker/rsc/state.ts +0 -3
- package/scripts/react+0.0.0-experimental-eda36a1c-20250228.patch +114 -12
- package/scripts/react-dom+0.0.0-experimental-eda36a1c-20250228.patch +10571 -121
- package/tsconfig.json +2 -2
- package/dist/plugin/collect-css-manifest.d.ts +0 -4
- package/dist/plugin/collect-css-manifest.d.ts.map +0 -1
- package/dist/plugin/collect-css-manifest.js +0 -65
- package/dist/plugin/collect-css-manifest.js.map +0 -1
- package/dist/plugin/config/createModuleIdGenerator.d.ts +0 -11
- package/dist/plugin/config/createModuleIdGenerator.d.ts.map +0 -1
- package/dist/plugin/config/createModuleIdGenerator.js +0 -44
- package/dist/plugin/config/createModuleIdGenerator.js.map +0 -1
- package/dist/plugin/loader/createCssLoader.d.ts +0 -30
- package/dist/plugin/loader/createCssLoader.d.ts.map +0 -1
- package/dist/plugin/loader/createCssLoader.js +0 -35
- package/dist/plugin/loader/createPageLoader.d.ts +0 -24
- package/dist/plugin/loader/createPageLoader.d.ts.map +0 -1
- package/dist/plugin/loader/createPageLoader.js +0 -50
- package/dist/plugin/loader/rsc/messageHandler.d.ts +0 -2
- package/dist/plugin/loader/rsc/messageHandler.d.ts.map +0 -1
- package/dist/plugin/loader/rsc/messageHandler.js +0 -1
- package/dist/plugin/loader/rsc/rsc-worker.development.d.ts +0 -2
- package/dist/plugin/loader/rsc/rsc-worker.development.d.ts.map +0 -1
- package/dist/plugin/loader/rsc/rsc-worker.development.js +0 -1
- package/dist/plugin/react-server/createHandler.d.ts +0 -17
- package/dist/plugin/react-server/createHandler.d.ts.map +0 -1
- package/dist/plugin/react-server/createHandler.js.map +0 -1
- package/dist/plugin/react-server/createRscStream.d.ts.map +0 -1
- package/dist/plugin/react-server/createRscStream.js +0 -70
- package/dist/plugin/react-server/createRscStream.js.map +0 -1
- package/dist/plugin/react-server/createSsrHandler.d.ts +0 -4
- package/dist/plugin/react-server/createSsrHandler.d.ts.map +0 -1
- package/dist/plugin/react-server/createSsrHandler.js +0 -95
- package/dist/plugin/utils/logger.d.ts +0 -9
- package/dist/plugin/utils/logger.d.ts.map +0 -1
- package/dist/plugin/utils/logger.js +0 -68
- package/dist/plugin/utils/logger.js.map +0 -1
- package/plugin/collect-css-manifest.ts +0 -82
- package/plugin/config/createModuleIdGenerator.ts +0 -52
- package/plugin/config/defaults.ts +0 -51
- package/plugin/loader/createCssLoader.ts +0 -73
- package/plugin/loader/createPageLoader.ts +0 -103
- package/plugin/loader/rsc/messageHandler.tsx +0 -1
- package/plugin/loader/rsc/rsc-worker.development.ts +0 -1
- package/plugin/react-server/createRscStream.ts +0 -86
- package/plugin/react-server/createSsrHandler.ts +0 -125
- package/plugin/utils/logger.ts +0 -52
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
createFromNodeStream,
|
|
8
8
|
// @ts-ignore
|
|
9
9
|
} from "react-server-dom-esm/client.node";
|
|
10
|
-
import { join } from "path";
|
|
11
10
|
|
|
12
11
|
// Track active renders and streams
|
|
13
12
|
const activeRenders = new Map<string, HtmlRenderState>();
|
|
@@ -29,7 +28,7 @@ export const messageHandler = async (message: HtmlWorkerMessage) => {
|
|
|
29
28
|
moduleRootPath,
|
|
30
29
|
moduleBaseURL,
|
|
31
30
|
outDir: '',
|
|
32
|
-
htmlOutputPath: htmlOutputPath
|
|
31
|
+
htmlOutputPath: htmlOutputPath,
|
|
33
32
|
pipableStreamOptions: pipableStreamOptions,
|
|
34
33
|
});
|
|
35
34
|
} else {
|
|
@@ -88,6 +87,13 @@ export const messageHandler = async (message: HtmlWorkerMessage) => {
|
|
|
88
87
|
reactElements as React.ReactNode,
|
|
89
88
|
{
|
|
90
89
|
...render.pipableStreamOptions,
|
|
90
|
+
// Calculate relative paths based on route depth
|
|
91
|
+
bootstrapModules: render.pipableStreamOptions?.bootstrapModules?.map(path => {
|
|
92
|
+
if (!path) return path;
|
|
93
|
+
const depth = id.split('/').filter(Boolean).length ;
|
|
94
|
+
const prefix = depth > 0 ? '../'.repeat(depth) : '/';
|
|
95
|
+
return path.startsWith('/') ? prefix + path.slice(1) : prefix + path;
|
|
96
|
+
}),
|
|
91
97
|
onShellReady() {
|
|
92
98
|
parentPort?.postMessage({ type: "SHELL_READY", id });
|
|
93
99
|
}
|
|
@@ -3,12 +3,12 @@ import { join, resolve } from "path";
|
|
|
3
3
|
import type { ModuleFormat, RollupOptions } from 'rollup';
|
|
4
4
|
import type { ResolvedUserOptions, StreamPluginOptions } from "../../types.js";
|
|
5
5
|
import { DEFAULT_CONFIG } from "../../config/defaults.js";
|
|
6
|
-
import {
|
|
6
|
+
import { pluginRoot } from "../../root.js";
|
|
7
7
|
import { resolveOptions } from "../../config/resolveOptions.js";
|
|
8
8
|
|
|
9
9
|
let userOptions: ResolvedUserOptions;
|
|
10
10
|
export function reactHtmlWorkerPlugin(options: StreamPluginOptions): Plugin {
|
|
11
|
-
const resolvedUserOptions = resolveOptions(options);
|
|
11
|
+
const resolvedUserOptions = resolveOptions(options, false);
|
|
12
12
|
if(resolvedUserOptions.type === 'error') {
|
|
13
13
|
throw resolvedUserOptions.error
|
|
14
14
|
}
|
|
@@ -17,7 +17,6 @@ export function reactHtmlWorkerPlugin(options: StreamPluginOptions): Plugin {
|
|
|
17
17
|
name: "vite:react-html-worker",
|
|
18
18
|
config(config) {
|
|
19
19
|
const root = config.root ?? process.cwd();
|
|
20
|
-
const pluginRoot = getPluginRoot();
|
|
21
20
|
const htmlWorkerPath = typeof options.htmlWorkerPath === 'string'
|
|
22
21
|
? resolve(root, options.htmlWorkerPath)
|
|
23
22
|
: resolve(pluginRoot, DEFAULT_CONFIG.HTML_WORKER_PATH);
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import { mkdirSync } from "node:fs";
|
|
2
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
-
import { dirname, join
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
4
3
|
import { Transform } from "node:stream";
|
|
5
4
|
import type { Worker } from "node:worker_threads";
|
|
6
|
-
import { createHandler } from "../../
|
|
7
|
-
import type { CheckFilesExistReturn, ResolvedUserConfig, ResolvedUserOptions } from "../../types.js";
|
|
5
|
+
import { createHandler } from "../../helpers/createHandler.js";
|
|
8
6
|
import type {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "
|
|
7
|
+
CheckFilesExistReturn,
|
|
8
|
+
PageData,
|
|
9
|
+
ResolvedUserConfig,
|
|
10
|
+
ResolvedUserOptions,
|
|
11
|
+
} from "../../types.js";
|
|
12
|
+
import type { HtmlWorkerResponse } from "../types.js";
|
|
13
|
+
import type { Manifest, IndexHtmlTransformHook } from "vite";
|
|
16
14
|
import React from "react";
|
|
17
|
-
import { collectManifestCss } from "../../collect-css-manifest.js";
|
|
18
15
|
|
|
19
16
|
interface PipeableStreamOptions {
|
|
20
17
|
bootstrapModules?: string[];
|
|
@@ -42,48 +39,82 @@ type RenderPagesOptions = {
|
|
|
42
39
|
pipableStreamOptions?: PipeableStreamOptions;
|
|
43
40
|
loader: (id: string) => Promise<Record<string, any>>;
|
|
44
41
|
onCssFile?: (url: string, parentUrl: string) => void;
|
|
42
|
+
onClientJSFile?: (url: string, parentUrl: string) => void;
|
|
43
|
+
onPage?: (pageData: PageData) => Promise<void>;
|
|
45
44
|
clientCss?: string[];
|
|
46
45
|
moduleBasePath: string;
|
|
47
46
|
moduleBaseURL: string;
|
|
47
|
+
transformIndexHtml: IndexHtmlTransformHook;
|
|
48
|
+
outDir: string;
|
|
49
|
+
htmlOutputPath: string;
|
|
48
50
|
};
|
|
49
51
|
|
|
50
52
|
export async function renderPages(
|
|
51
|
-
pluginContext: PluginContext,
|
|
52
53
|
routes: string[],
|
|
53
54
|
files: CheckFilesExistReturn,
|
|
54
|
-
options: RenderPagesOptions
|
|
55
|
+
options: RenderPagesOptions
|
|
55
56
|
) {
|
|
56
|
-
const root = pluginContext.environment.config.root;
|
|
57
|
-
const outDir = pluginContext.environment.config.build.outDir;
|
|
58
57
|
const failedRoutes = new Map<string, Error>();
|
|
59
58
|
const completedRoutes = new Set<string>();
|
|
60
|
-
const writePromises = new Map<string, Promise<void>>();
|
|
61
59
|
const clientCss = options.clientCss ?? [];
|
|
60
|
+
const partialPageData = new Map<string, Partial<PageData>>();
|
|
61
|
+
|
|
62
|
+
const mergeAndSendPageData = async (route: string, resolve: () => void) => {
|
|
63
|
+
const partial = partialPageData.get(route);
|
|
64
|
+
if (!partial?.html || !partial.rsc) {
|
|
65
|
+
return; // Wait for both parts
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const pageData: PageData = {
|
|
69
|
+
route,
|
|
70
|
+
html: partial.html,
|
|
71
|
+
rsc: partial.rsc,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Write RSC file
|
|
75
|
+
console.log('route', route)
|
|
76
|
+
// Write HTML file
|
|
77
|
+
let routeHtmlPath = route === '/' ? options.htmlOutputPath : options.htmlOutputPath.replace('index.html', join(route, 'index.html'));
|
|
78
|
+
if(routeHtmlPath.startsWith('/')) {
|
|
79
|
+
routeHtmlPath = routeHtmlPath.slice(1);
|
|
80
|
+
}
|
|
81
|
+
const routeRscPath = routeHtmlPath.slice(0, -5) + '.rsc';
|
|
82
|
+
await mkdir(dirname(routeHtmlPath), { recursive: true });
|
|
83
|
+
await writeFile(routeRscPath, partial.rsc.content);
|
|
84
|
+
await writeFile(routeHtmlPath, partial.html.raw);
|
|
85
|
+
|
|
86
|
+
await options.onPage?.(pageData);
|
|
87
|
+
completedRoutes.add(route);
|
|
88
|
+
if (completedRoutes.size === routes.length) {
|
|
89
|
+
resolve();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
62
93
|
try {
|
|
63
94
|
// Set up worker message handling
|
|
64
95
|
const allRoutesComplete = new Promise<void>((resolve, reject) => {
|
|
65
|
-
options.worker.on("message", (msg: HtmlWorkerResponse) => {
|
|
96
|
+
options.worker.on("message", async (msg: HtmlWorkerResponse) => {
|
|
66
97
|
switch (msg.type) {
|
|
67
98
|
case "ALL_READY": {
|
|
68
|
-
const { id, html
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
99
|
+
const { id, html } = msg;
|
|
100
|
+
try {
|
|
101
|
+
const partial = partialPageData.get(id) || { route: id };
|
|
102
|
+
|
|
103
|
+
partial.html = {
|
|
104
|
+
raw: html,
|
|
105
|
+
transformed: "", // Will be set by main thread transform
|
|
106
|
+
assets: [],
|
|
107
|
+
};
|
|
108
|
+
partialPageData.set(id, partial);
|
|
109
|
+
await mergeAndSendPageData(id, resolve);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
failedRoutes.set(id, error as Error);
|
|
112
|
+
reject(error);
|
|
113
|
+
}
|
|
83
114
|
break;
|
|
84
115
|
}
|
|
85
116
|
case "ERROR": {
|
|
86
|
-
console.error(
|
|
117
|
+
console.error("Worker error for route:", msg.id, msg.error);
|
|
87
118
|
failedRoutes.set(msg.id, new Error(msg.error));
|
|
88
119
|
reject(new Error(msg.error));
|
|
89
120
|
break;
|
|
@@ -92,124 +123,130 @@ export async function renderPages(
|
|
|
92
123
|
});
|
|
93
124
|
});
|
|
94
125
|
|
|
95
|
-
const newCssFiles = collectManifestCss(
|
|
96
|
-
options.clientManifest,
|
|
97
|
-
options.moduleBasePath,
|
|
98
|
-
'index.html',
|
|
99
|
-
(url, parentUrl)=>{
|
|
100
|
-
options?.onCssFile?.(url, parentUrl);
|
|
101
|
-
if(!clientCss.includes(url)){
|
|
102
|
-
clientCss.push(url);
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
join(root, options.pluginOptions.build.outDir, options.pluginOptions.build.client)
|
|
106
|
-
);
|
|
107
|
-
|
|
108
126
|
// Process routes sequentially
|
|
109
127
|
for (const route of routes) {
|
|
110
128
|
const routeFiles = files.urlMap.get(route);
|
|
111
129
|
if (!routeFiles) {
|
|
112
|
-
console.error(
|
|
130
|
+
console.error("No files found for route:", route);
|
|
113
131
|
failedRoutes.set(route, new Error(`No files found for ${route}`));
|
|
114
132
|
continue;
|
|
115
133
|
}
|
|
116
134
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
options.onCssFile?.(url, parentUrl);
|
|
123
|
-
if(!clientCss.includes(url)){
|
|
124
|
-
clientCss.push(url);
|
|
125
|
-
}
|
|
135
|
+
if (options.pipableStreamOptions?.importMap?.imports) {
|
|
136
|
+
for (let [, value] of Object.entries(
|
|
137
|
+
options.pipableStreamOptions?.importMap?.imports
|
|
138
|
+
)) {
|
|
139
|
+
options.onClientJSFile?.(value, route);
|
|
126
140
|
}
|
|
127
|
-
|
|
141
|
+
}
|
|
142
|
+
|
|
128
143
|
// Create handler for pure RSC output
|
|
129
|
-
const rscResult = await createHandler(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
const rscResult = await createHandler({
|
|
145
|
+
url: route,
|
|
146
|
+
urlMap: files.urlMap,
|
|
147
|
+
pluginOptions: {
|
|
148
|
+
...options.pluginOptions,
|
|
149
|
+
Html: React.Fragment, // Use Fragment for pure RSC output
|
|
150
|
+
},
|
|
151
|
+
streamOptions: {
|
|
152
|
+
loader: options.loader,
|
|
153
|
+
clientManifest: options.clientManifest,
|
|
154
|
+
serverManifest: options.serverManifest,
|
|
155
|
+
cssFiles: clientCss,
|
|
156
|
+
moduleBasePath: '',
|
|
157
|
+
moduleBaseURL: '',
|
|
158
|
+
pipableStreamOptions: {
|
|
159
|
+
...options.pipableStreamOptions,
|
|
160
|
+
importMap: {
|
|
161
|
+
imports: {
|
|
162
|
+
...options.pipableStreamOptions?.importMap?.imports,
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
144
166
|
},
|
|
145
167
|
});
|
|
146
168
|
|
|
147
169
|
// Create handler for HTML output
|
|
148
|
-
const htmlResult = await createHandler(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
170
|
+
const htmlResult = await createHandler({
|
|
171
|
+
url: route,
|
|
172
|
+
urlMap: files.urlMap,
|
|
173
|
+
pluginOptions: options.pluginOptions,
|
|
174
|
+
streamOptions: {
|
|
175
|
+
loader: options.loader,
|
|
176
|
+
clientManifest: options.clientManifest,
|
|
177
|
+
serverManifest: options.serverManifest,
|
|
178
|
+
cssFiles: clientCss,
|
|
179
|
+
moduleBasePath: '',
|
|
180
|
+
moduleBaseURL: '',
|
|
181
|
+
pipableStreamOptions: {
|
|
182
|
+
...options.pipableStreamOptions,
|
|
183
|
+
importMap: {
|
|
184
|
+
imports: {
|
|
185
|
+
...options.pipableStreamOptions?.importMap?.imports,
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
},
|
|
160
189
|
},
|
|
161
190
|
});
|
|
162
191
|
|
|
163
192
|
if (rscResult.type !== "success" || htmlResult.type !== "success") {
|
|
164
|
-
|
|
193
|
+
if (rscResult.type !== "success") {
|
|
194
|
+
if (rscResult.type !== "skip") {
|
|
195
|
+
console.error("Handler failed for route:", route, rscResult.error);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (htmlResult.type !== "success") {
|
|
199
|
+
if (htmlResult.type !== "skip") {
|
|
200
|
+
console.error("Handler failed for route:", route, htmlResult.error);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
165
203
|
failedRoutes.set(route, new Error(`Handler failed for ${route}`));
|
|
166
204
|
continue;
|
|
167
205
|
}
|
|
168
206
|
|
|
169
207
|
// Process both streams
|
|
170
208
|
await Promise.all([
|
|
171
|
-
//
|
|
209
|
+
// Handle RSC stream
|
|
172
210
|
new Promise<void>((resolve, reject) => {
|
|
173
211
|
const chunks: Buffer[] = [];
|
|
174
212
|
const rscTransform = new Transform({
|
|
175
213
|
transform(chunk, _encoding, callback) {
|
|
176
214
|
try {
|
|
177
|
-
|
|
178
|
-
|
|
215
|
+
if (chunk) {
|
|
216
|
+
chunks.push(Buffer.from(chunk));
|
|
217
|
+
callback(null, chunk);
|
|
218
|
+
}
|
|
179
219
|
} catch (error) {
|
|
180
220
|
callback(error as Error);
|
|
181
221
|
}
|
|
182
222
|
},
|
|
183
|
-
flush(callback) {
|
|
223
|
+
async flush(callback) {
|
|
184
224
|
try {
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
callback(error as Error);
|
|
199
|
-
reject(error);
|
|
200
|
-
});
|
|
225
|
+
const rscContent = Buffer.concat(chunks).toString("utf-8");
|
|
226
|
+
|
|
227
|
+
// Update partial page data with raw RSC content
|
|
228
|
+
const partial = partialPageData.get(route) || { route };
|
|
229
|
+
partial.rsc = {
|
|
230
|
+
modules: [], // Will be parsed by the client
|
|
231
|
+
content: rscContent,
|
|
232
|
+
};
|
|
233
|
+
partialPageData.set(route, partial);
|
|
234
|
+
await mergeAndSendPageData(route, resolve);
|
|
235
|
+
|
|
236
|
+
callback();
|
|
237
|
+
resolve();
|
|
201
238
|
} catch (error) {
|
|
202
239
|
callback(error as Error);
|
|
203
240
|
reject(error);
|
|
204
241
|
}
|
|
205
|
-
}
|
|
242
|
+
},
|
|
206
243
|
});
|
|
207
244
|
|
|
208
245
|
rscResult.stream.pipe(rscTransform);
|
|
209
246
|
}),
|
|
210
247
|
|
|
211
248
|
// Send HTML stream to worker
|
|
212
|
-
new Promise<void>((resolve
|
|
249
|
+
new Promise<void>((resolve) => {
|
|
213
250
|
const htmlTransform = new Transform({
|
|
214
251
|
transform(chunk, _encoding, callback) {
|
|
215
252
|
try {
|
|
@@ -217,9 +254,9 @@ export async function renderPages(
|
|
|
217
254
|
type: "RSC_CHUNK",
|
|
218
255
|
id: route,
|
|
219
256
|
chunk: chunk.toString(),
|
|
220
|
-
moduleRootPath:
|
|
257
|
+
moduleRootPath: options.moduleBasePath,
|
|
221
258
|
moduleBaseURL: options.moduleBaseURL,
|
|
222
|
-
htmlOutputPath:
|
|
259
|
+
htmlOutputPath: options.htmlOutputPath,
|
|
223
260
|
pipableStreamOptions: options.pipableStreamOptions,
|
|
224
261
|
});
|
|
225
262
|
callback(null, chunk);
|
|
@@ -234,18 +271,17 @@ export async function renderPages(
|
|
|
234
271
|
});
|
|
235
272
|
callback();
|
|
236
273
|
resolve();
|
|
237
|
-
}
|
|
274
|
+
},
|
|
238
275
|
});
|
|
239
276
|
|
|
240
277
|
htmlResult.stream.pipe(htmlTransform);
|
|
241
|
-
})
|
|
278
|
+
}),
|
|
242
279
|
]);
|
|
243
280
|
}
|
|
244
281
|
|
|
245
282
|
await allRoutesComplete;
|
|
246
|
-
|
|
247
283
|
} catch (error) {
|
|
248
|
-
console.error(
|
|
284
|
+
console.error("Render error:", error);
|
|
249
285
|
throw error;
|
|
250
286
|
}
|
|
251
287
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# RSC Worker
|
|
2
|
+
|
|
3
|
+
The RSC worker is used by the client plugin to handle React Server Components when the main thread is running without the `react-server` condition. It provides the server-condition capabilities that the client plugin needs but can't access directly.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
The RSC worker serves several key functions:
|
|
8
|
+
|
|
9
|
+
1. **Server Condition Access**: Enables RSC processing in a client-focused environment
|
|
10
|
+
2. **Message-Based Communication**: Handles RSC streaming through a message passing interface
|
|
11
|
+
|
|
12
|
+
## Implementation Details
|
|
13
|
+
|
|
14
|
+
The worker comes in two variants:
|
|
15
|
+
|
|
16
|
+
- `rsc-worker.development.ts`: Full implementation with detailed logging and error handling
|
|
17
|
+
- `rsc-worker.production.ts`: Optimized implementation for production builds
|
|
18
|
+
|
|
19
|
+
## Extending the Worker
|
|
20
|
+
|
|
21
|
+
Users can create their own RSC workers for application-level use. This allows for:
|
|
22
|
+
|
|
23
|
+
1. Custom RSC processing logic
|
|
24
|
+
2. Application-specific message handling
|
|
25
|
+
3. Specialized worker architectures
|
|
26
|
+
|
|
27
|
+
Example of creating a custom RSC worker:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { messageHandler } from 'vite-plugin-react-server/worker/rsc/messageHandler'
|
|
31
|
+
import type { RscWorkerMessage } from 'vite-plugin-react-server/worker/types'
|
|
32
|
+
|
|
33
|
+
// Create your custom message handler
|
|
34
|
+
const customMessageHandler = async (msg: RscWorkerMessage) => {
|
|
35
|
+
// Add your custom logic here
|
|
36
|
+
return messageHandler(msg)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Initialize your worker
|
|
40
|
+
if (typeof WorkerGlobalScope !== 'undefined') {
|
|
41
|
+
parentPort.on('message', customMessageHandler)
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Future Possibilities
|
|
46
|
+
|
|
47
|
+
The RSC worker architecture is designed to be extensible. Future enhancements could include:
|
|
48
|
+
|
|
49
|
+
- Custom streaming strategies
|
|
50
|
+
- Advanced caching mechanisms
|
|
51
|
+
- Specialized RSC processing pipelines
|
|
52
|
+
- Integration with other build tools
|
|
53
|
+
|
|
54
|
+
## Notes
|
|
55
|
+
|
|
56
|
+
- The worker must be initialized with appropriate Node conditions
|
|
57
|
+
- Message handling must account for streaming data
|
|
58
|
+
- Consider memory usage when processing large RSC payloads
|