vite-plugin-react-server 1.1.3 → 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/resolveOptions.d.ts.map +1 -1
- package/dist/plugin/config/resolveOptions.js +1 -1
- package/dist/plugin/config/resolveOptions.js.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 -20
- 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 +27 -8
- 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/resolveOptions.ts +1 -3
- 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 -23
- package/plugin/react-static/plugin.ts +34 -12
- 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
|
@@ -8,7 +8,6 @@ import type {
|
|
|
8
8
|
RscWorkerOutputMessage,
|
|
9
9
|
RscRenderMessage,
|
|
10
10
|
} from "../worker/types.js";
|
|
11
|
-
import { join } from "node:path";
|
|
12
11
|
import type { Worker as NodeWorker } from "node:worker_threads";
|
|
13
12
|
import { MessageChannel } from "node:worker_threads";
|
|
14
13
|
import {
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
} from "../helpers/serializeUserOptions.js";
|
|
18
17
|
import { createWorker } from "../worker/createWorker.js";
|
|
19
18
|
import { getRouteFiles } from "../helpers/getRouteFiles.js";
|
|
19
|
+
import { requestToRoute } from "../helpers/requestToRoute.js";
|
|
20
20
|
|
|
21
21
|
let currentWorker: NodeWorker | null = null;
|
|
22
22
|
let isRestarting = false;
|
|
@@ -169,7 +169,7 @@ export function handleWorkerRscStream(
|
|
|
169
169
|
export async function configureWorkerRequestHandler({
|
|
170
170
|
server,
|
|
171
171
|
autoDiscoveredFiles,
|
|
172
|
-
userOptions,
|
|
172
|
+
userOptions: _userOptions,
|
|
173
173
|
hmrChannel,
|
|
174
174
|
}: {
|
|
175
175
|
server: ViteDevServer;
|
|
@@ -177,15 +177,30 @@ export async function configureWorkerRequestHandler({
|
|
|
177
177
|
userOptions: ResolvedUserOptions;
|
|
178
178
|
hmrChannel: MessageChannel;
|
|
179
179
|
}) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
180
|
+
let {
|
|
181
|
+
// remove these
|
|
182
|
+
moduleBaseURL: _moduleBaseURL,
|
|
183
|
+
projectRoot: _projectRoot,
|
|
184
|
+
...handlerUserOptions
|
|
185
|
+
} = _userOptions;
|
|
186
|
+
const handlerOptions = Object.assign({}, handlerUserOptions, {
|
|
187
|
+
moduleBaseURL:
|
|
188
|
+
typeof server.config.server.host === "string"
|
|
189
|
+
? `${server.config.server.https ? "https" : "http"}://${
|
|
190
|
+
server.config.server.host
|
|
191
|
+
}:${server.config.server.port}`
|
|
192
|
+
: "",
|
|
193
|
+
moduleBasePath:
|
|
194
|
+
server.config.base === "/"
|
|
195
|
+
? ""
|
|
196
|
+
: server.config.base.endsWith("/")
|
|
197
|
+
? server.config.base.slice(0, -1)
|
|
198
|
+
: server.config.base,
|
|
199
|
+
projectRoot: server.config.root,
|
|
200
|
+
});
|
|
186
201
|
|
|
187
202
|
// Start the worker
|
|
188
|
-
await restartWorker(server, autoDiscoveredFiles,
|
|
203
|
+
await restartWorker(server, autoDiscoveredFiles, handlerOptions, hmrChannel);
|
|
189
204
|
|
|
190
205
|
// Create the request handler
|
|
191
206
|
const handler: RequestHandler = async (req, res, next) => {
|
|
@@ -197,18 +212,24 @@ export async function configureWorkerRequestHandler({
|
|
|
197
212
|
}
|
|
198
213
|
|
|
199
214
|
// Get the route from the request
|
|
200
|
-
let route = req
|
|
201
|
-
|
|
215
|
+
let route = requestToRoute(req, {
|
|
216
|
+
moduleBasePath: handlerOptions.moduleBasePath,
|
|
217
|
+
build: handlerOptions.build
|
|
218
|
+
});
|
|
219
|
+
if (!route) {
|
|
220
|
+
return next();
|
|
221
|
+
}
|
|
202
222
|
// in the case of the no build.pages and a async Page and or props userOption, we need to await those
|
|
203
223
|
// if they are already autoDiscovered then the promise will resolve immediately
|
|
204
224
|
const routeFiles = await getRouteFiles(
|
|
205
225
|
route,
|
|
206
226
|
autoDiscoveredFiles,
|
|
207
|
-
|
|
227
|
+
handlerOptions
|
|
208
228
|
);
|
|
209
229
|
if (routeFiles.type === "error") {
|
|
210
|
-
server.config.logger.error(
|
|
230
|
+
server.config.logger.error(routeFiles.error.message, {
|
|
211
231
|
error: routeFiles.error,
|
|
232
|
+
timestamp: true,
|
|
212
233
|
});
|
|
213
234
|
return next();
|
|
214
235
|
}
|
|
@@ -218,12 +239,8 @@ export async function configureWorkerRequestHandler({
|
|
|
218
239
|
res.setHeader("Content-Type", "text/x-component; charset=utf-8");
|
|
219
240
|
res.setHeader("Transfer-Encoding", "chunked");
|
|
220
241
|
res.setHeader("Connection", "keep-alive");
|
|
221
|
-
let timeout = setTimeout(() => {
|
|
222
|
-
server.config.logger.error("[react-client] RSC render timeout");
|
|
223
|
-
res.end();
|
|
224
|
-
}, 5000);
|
|
225
242
|
const serializedUserOptions = serializedOptions(
|
|
226
|
-
|
|
243
|
+
handlerOptions,
|
|
227
244
|
autoDiscoveredFiles
|
|
228
245
|
);
|
|
229
246
|
const stream = handleWorkerRscStream(currentWorker, {
|
|
@@ -234,37 +251,42 @@ export async function configureWorkerRequestHandler({
|
|
|
234
251
|
propsPath: props,
|
|
235
252
|
// override these at all times to ensure the settings will work for the dev server
|
|
236
253
|
projectRoot: server.config.root,
|
|
237
|
-
moduleRootPath: join(server.config.root, userOptions.moduleBase),
|
|
238
|
-
moduleBaseURL: "",
|
|
239
|
-
moduleBasePath: "",
|
|
240
254
|
build: serializedUserOptions.build,
|
|
241
255
|
manifest: autoDiscoveredFiles.staticManifest,
|
|
242
256
|
cssFiles: new Map(),
|
|
243
257
|
globalCss: new Map(),
|
|
244
258
|
});
|
|
259
|
+
const writeStream = new WritableStream({
|
|
260
|
+
write(chunk) {
|
|
261
|
+
res.write(chunk);
|
|
262
|
+
},
|
|
245
263
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
264
|
+
close() {
|
|
265
|
+
clearTimeout(timeout);
|
|
266
|
+
res.end();
|
|
267
|
+
},
|
|
268
|
+
abort() {
|
|
269
|
+
clearTimeout(timeout);
|
|
270
|
+
// Restart worker on error
|
|
271
|
+
restartWorker(
|
|
272
|
+
server,
|
|
273
|
+
autoDiscoveredFiles,
|
|
274
|
+
handlerOptions,
|
|
275
|
+
hmrChannel
|
|
276
|
+
);
|
|
277
|
+
res.end();
|
|
278
|
+
},
|
|
279
|
+
})
|
|
280
|
+
let timeout = setTimeout(() => {
|
|
281
|
+
server.config.logger.error("[react-client] RSC render timeout");
|
|
282
|
+
res.end();
|
|
283
|
+
}, 5000);
|
|
252
284
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
res.end();
|
|
256
|
-
},
|
|
257
|
-
abort() {
|
|
258
|
-
clearTimeout(timeout);
|
|
259
|
-
// Restart worker on error
|
|
260
|
-
restartWorker(server, autoDiscoveredFiles, userOptions, hmrChannel);
|
|
261
|
-
res.end();
|
|
262
|
-
},
|
|
263
|
-
})
|
|
264
|
-
);
|
|
285
|
+
// Pipe the stream to the response
|
|
286
|
+
stream.pipeTo(writeStream);
|
|
265
287
|
} catch (error) {
|
|
266
288
|
if (error instanceof Error) {
|
|
267
|
-
server.config.logger.error(
|
|
289
|
+
server.config.logger.error(error.message, {
|
|
268
290
|
error,
|
|
269
291
|
});
|
|
270
292
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Manifest, ViteDevServer } from "vite";
|
|
2
2
|
import type { ServerResponse } from "http";
|
|
3
3
|
import type { AutoDiscoveredFiles, ResolvedUserOptions } from "../types.js";
|
|
4
4
|
import { createEventHandler } from "../helpers/createEventHandler.js";
|
|
@@ -10,7 +10,7 @@ import React from "react";
|
|
|
10
10
|
export async function configureReactServer({
|
|
11
11
|
server,
|
|
12
12
|
autoDiscoveredFiles,
|
|
13
|
-
userOptions,
|
|
13
|
+
userOptions: _userOptions,
|
|
14
14
|
serverManifest,
|
|
15
15
|
}: {
|
|
16
16
|
server: ViteDevServer;
|
|
@@ -20,6 +20,31 @@ export async function configureReactServer({
|
|
|
20
20
|
}) {
|
|
21
21
|
const activeStreams = new Set<ServerResponse>();
|
|
22
22
|
|
|
23
|
+
const {
|
|
24
|
+
Html: _UserHtmlComponent,
|
|
25
|
+
onEvent,
|
|
26
|
+
// remove these
|
|
27
|
+
moduleBaseURL: _moduleBaseURL,
|
|
28
|
+
moduleBasePath: _moduleBasePath,
|
|
29
|
+
projectRoot: _projectRoot,
|
|
30
|
+
...handlerUserOptions
|
|
31
|
+
} = _userOptions;
|
|
32
|
+
|
|
33
|
+
const handlerOptions = Object.assign({}, handlerUserOptions, {
|
|
34
|
+
moduleBaseURL:
|
|
35
|
+
typeof server.config.server.host === "string"
|
|
36
|
+
? `${server.config.server.https ? "https" : "http"}://${
|
|
37
|
+
server.config.server.host
|
|
38
|
+
}:${server.config.server.port}`
|
|
39
|
+
: "",
|
|
40
|
+
moduleBasePath:
|
|
41
|
+
server.config.base === "/"
|
|
42
|
+
? ""
|
|
43
|
+
: server.config.base.endsWith("/")
|
|
44
|
+
? server.config.base.slice(0, -1)
|
|
45
|
+
: server.config.base,
|
|
46
|
+
projectRoot: server.config.root,
|
|
47
|
+
});
|
|
23
48
|
// Handle Vite server restarts
|
|
24
49
|
server.ws.on("restart", (path) => {
|
|
25
50
|
console.log(
|
|
@@ -41,10 +66,21 @@ export async function configureReactServer({
|
|
|
41
66
|
server.middlewares.use(async (req, res, next) => {
|
|
42
67
|
try {
|
|
43
68
|
if (req.headers.accept !== "text/x-component") return next();
|
|
44
|
-
let route = req.url?.replace(
|
|
69
|
+
let route = req.url?.replace("/" + handlerOptions.build.rscOutputPath, "");
|
|
70
|
+
if(!route?.startsWith(handlerOptions.moduleBasePath)) {
|
|
71
|
+
next();
|
|
72
|
+
} else {
|
|
73
|
+
route = route.slice(handlerOptions.moduleBasePath.length);
|
|
74
|
+
}
|
|
75
|
+
if(typeof route !== "string" ) {
|
|
76
|
+
throw new Error("req.url is not a string");
|
|
77
|
+
}
|
|
45
78
|
if (!route || route === "") {
|
|
46
79
|
route = "/";
|
|
47
80
|
}
|
|
81
|
+
if(!route.startsWith("/")) {
|
|
82
|
+
route = "/" + route;
|
|
83
|
+
}
|
|
48
84
|
if (!autoDiscoveredFiles.urlMap.has(route)) {
|
|
49
85
|
return next();
|
|
50
86
|
}
|
|
@@ -52,26 +88,19 @@ export async function configureReactServer({
|
|
|
52
88
|
const pagePath = routeFiles.page;
|
|
53
89
|
const propsPath = routeFiles.props;
|
|
54
90
|
|
|
55
|
-
const {
|
|
56
|
-
Html: _UserHtmlComponent,
|
|
57
|
-
onEvent,
|
|
58
|
-
// remove these
|
|
59
|
-
moduleBaseURL,
|
|
60
|
-
...handlerUserOptions
|
|
61
|
-
} = userOptions;
|
|
62
91
|
// Create a unified event handler
|
|
63
92
|
await server.warmupRequest(pagePath);
|
|
64
93
|
const eventHandler = createEventHandler(onEvent);
|
|
65
94
|
const cssFilesResult = await collectViteModuleGraphCss({
|
|
66
95
|
moduleGraph: server.moduleGraph,
|
|
67
96
|
pagePath,
|
|
68
|
-
loader: (i)=>server.ssrLoadModule(i, {fixStacktrace: true}),
|
|
69
|
-
// explicitly set
|
|
70
|
-
moduleBaseURL:
|
|
71
|
-
moduleBasePath:
|
|
72
|
-
moduleRootPath:
|
|
73
|
-
projectRoot:
|
|
74
|
-
css:
|
|
97
|
+
loader: (i) => server.ssrLoadModule(i, { fixStacktrace: true }),
|
|
98
|
+
// explicitly set for development server
|
|
99
|
+
moduleBaseURL: handlerOptions.moduleBaseURL,
|
|
100
|
+
moduleBasePath: handlerOptions.moduleBasePath,
|
|
101
|
+
moduleRootPath: handlerOptions.moduleRootPath,
|
|
102
|
+
projectRoot: handlerOptions.projectRoot,
|
|
103
|
+
css: handlerOptions.css,
|
|
75
104
|
parentUrl: pagePath,
|
|
76
105
|
});
|
|
77
106
|
if (cssFilesResult.type === "skip") {
|
|
@@ -85,8 +114,8 @@ export async function configureReactServer({
|
|
|
85
114
|
propsPath,
|
|
86
115
|
route,
|
|
87
116
|
loader: server.ssrLoadModule,
|
|
88
|
-
pageExportName:
|
|
89
|
-
propsExportName:
|
|
117
|
+
pageExportName: handlerOptions.pageExportName ?? "default",
|
|
118
|
+
propsExportName: handlerOptions.propsExportName ?? "default",
|
|
90
119
|
});
|
|
91
120
|
if (pageAndPropsResult.type === "error") {
|
|
92
121
|
throw pageAndPropsResult.error;
|
|
@@ -95,9 +124,9 @@ export async function configureReactServer({
|
|
|
95
124
|
return next();
|
|
96
125
|
}
|
|
97
126
|
const { PageComponent, pageProps } = pageAndPropsResult;
|
|
98
|
-
// Create the headless RSC stream directly
|
|
127
|
+
// Create the headless RSC stream directly;
|
|
99
128
|
const rscResult = await createHandler({
|
|
100
|
-
...
|
|
129
|
+
...handlerOptions,
|
|
101
130
|
PageComponent: PageComponent,
|
|
102
131
|
pageProps: pageProps,
|
|
103
132
|
logger: server.config.logger,
|
|
@@ -110,8 +139,6 @@ export async function configureReactServer({
|
|
|
110
139
|
pagePath,
|
|
111
140
|
propsPath,
|
|
112
141
|
cssFiles: cssFilesResult.cssFiles ?? new Map(),
|
|
113
|
-
// explicitly set to empty string, because we let vite handle the resolving during development
|
|
114
|
-
moduleBaseURL: "",
|
|
115
142
|
globalCss: new Map(),
|
|
116
143
|
});
|
|
117
144
|
if (rscResult.type === "success") {
|
|
@@ -138,6 +138,7 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
138
138
|
timing.renderStart = Date.now();
|
|
139
139
|
},
|
|
140
140
|
|
|
141
|
+
|
|
141
142
|
async writeBundle(options, bundle) {
|
|
142
143
|
try {
|
|
143
144
|
const bundleManifest = getBundleManifest<false>({
|
|
@@ -158,7 +159,11 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
158
159
|
|
|
159
160
|
const clientManifestResult = await tryManifest({
|
|
160
161
|
root: userOptions.projectRoot,
|
|
161
|
-
outDir: join(
|
|
162
|
+
outDir: join(
|
|
163
|
+
userOptions.build.outDir,
|
|
164
|
+
userOptions.build.client,
|
|
165
|
+
userOptions.moduleBasePath
|
|
166
|
+
),
|
|
162
167
|
ssrManifest: false,
|
|
163
168
|
});
|
|
164
169
|
if (clientManifestResult.type === "error") {
|
|
@@ -268,7 +273,16 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
268
273
|
const pipeableStreamOptions = {
|
|
269
274
|
...userOptions.pipeableStreamOptions,
|
|
270
275
|
bootstrapModules: [
|
|
271
|
-
...(indexHtml
|
|
276
|
+
...(indexHtml
|
|
277
|
+
? [
|
|
278
|
+
userOptions.moduleBaseURL !== ""
|
|
279
|
+
? new URL(
|
|
280
|
+
join(userOptions.moduleBasePath, indexHtml),
|
|
281
|
+
userOptions.moduleBaseURL
|
|
282
|
+
).href
|
|
283
|
+
: join(userOptions.moduleBasePath, indexHtml),
|
|
284
|
+
]
|
|
285
|
+
: []),
|
|
272
286
|
...(userOptions.pipeableStreamOptions?.bootstrapModules ?? []),
|
|
273
287
|
],
|
|
274
288
|
};
|
|
@@ -279,31 +293,37 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
279
293
|
);
|
|
280
294
|
// Create worker
|
|
281
295
|
if (!worker) {
|
|
296
|
+
const viteEnvPrefix = typeof resolvedConfig.envPrefix === 'string' ? resolvedConfig.envPrefix : Array.isArray(resolvedConfig.envPrefix) ? resolvedConfig.envPrefix[0] : 'VITE_'
|
|
282
297
|
const workerResult = await createWorker({
|
|
283
298
|
projectRoot: userOptions.projectRoot,
|
|
284
299
|
workerPath: userOptions.htmlWorkerPath,
|
|
285
300
|
currentCondition: "react-server",
|
|
286
301
|
reverseCondition: "react-client",
|
|
302
|
+
envPrefix: viteEnvPrefix,
|
|
287
303
|
workerData: {
|
|
288
304
|
resolvedConfig: serializeResolvedConfig(resolvedConfig),
|
|
289
|
-
userOptions:
|
|
305
|
+
userOptions: {
|
|
306
|
+
...serializedUserOptions,
|
|
307
|
+
},
|
|
290
308
|
},
|
|
291
309
|
});
|
|
292
310
|
if (workerResult.type === "error") {
|
|
293
311
|
throw workerResult.error;
|
|
294
312
|
} else if (workerResult.type === "skip") {
|
|
295
|
-
this.environment.logger.info(
|
|
313
|
+
this.environment.logger.info(
|
|
314
|
+
"Worker not created, skipping static build"
|
|
315
|
+
);
|
|
296
316
|
return;
|
|
297
317
|
} else {
|
|
298
318
|
worker = workerResult.worker;
|
|
299
319
|
}
|
|
300
320
|
}
|
|
301
321
|
// Render pages
|
|
302
|
-
const { onEvent, ...
|
|
322
|
+
const { onEvent, ...handlerOptions } = userOptions;
|
|
303
323
|
const renderPagesGenerator = renderPages(
|
|
304
324
|
autoDiscoveredFiles!,
|
|
305
325
|
{
|
|
306
|
-
...
|
|
326
|
+
...handlerOptions,
|
|
307
327
|
loader: buildLoader,
|
|
308
328
|
worker: worker,
|
|
309
329
|
logger: createLogger(),
|
|
@@ -329,7 +349,7 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
329
349
|
},
|
|
330
350
|
globalCss: globalCss,
|
|
331
351
|
},
|
|
332
|
-
cssFilesByPage
|
|
352
|
+
cssFilesByPage
|
|
333
353
|
);
|
|
334
354
|
|
|
335
355
|
// Process render results
|
|
@@ -344,11 +364,13 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
344
364
|
if (!finalResult) {
|
|
345
365
|
throw new Error("No render result produced");
|
|
346
366
|
}
|
|
347
|
-
finalResult.streamMetrics.duration = Math.round(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
367
|
+
finalResult.streamMetrics.duration = Math.round(
|
|
368
|
+
performance.now() - finalResult.streamMetrics.startTime
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
this.environment.logger.info(
|
|
372
|
+
`Rendered ${finalResult.completedRoutes.size} unique routes in ${finalResult.streamMetrics.duration}ms`
|
|
373
|
+
);
|
|
352
374
|
|
|
353
375
|
// Update timing
|
|
354
376
|
timing.render = Date.now() - (timing.renderStart ?? timing.start);
|
|
@@ -44,7 +44,6 @@ export async function* renderPage(
|
|
|
44
44
|
} satisfies CreateHandlerOptions;
|
|
45
45
|
// Create streams with CSS files
|
|
46
46
|
const [rscFull, rscHeadless] = await renderStreams(newHandlerOptions);
|
|
47
|
-
|
|
48
47
|
// Handle stream creation errors
|
|
49
48
|
if (rscFull.type !== "success") {
|
|
50
49
|
yield {
|
|
@@ -37,6 +37,15 @@ export function reactTransformPlugin(options: StreamPluginOptions): Plugin {
|
|
|
37
37
|
if (resolvedOptionsResult.type === "error") throw resolvedOptionsResult.error;
|
|
38
38
|
userOptions = resolvedOptionsResult.userOptions;
|
|
39
39
|
let staticManifest: Manifest;
|
|
40
|
+
const getID = (id: string) => {
|
|
41
|
+
if(userOptions.moduleBasePath !== '' && !id.startsWith(userOptions.moduleBasePath)) {
|
|
42
|
+
id = join(userOptions.moduleBasePath, id);
|
|
43
|
+
}
|
|
44
|
+
if(!id.startsWith('/')) {
|
|
45
|
+
id = '/' + id;
|
|
46
|
+
}
|
|
47
|
+
return id;
|
|
48
|
+
}
|
|
40
49
|
return {
|
|
41
50
|
name: "vite:react-server-action-transform",
|
|
42
51
|
enforce: "pre",
|
|
@@ -73,13 +82,14 @@ export function reactTransformPlugin(options: StreamPluginOptions): Plugin {
|
|
|
73
82
|
}
|
|
74
83
|
if (isServer && isBuild) {
|
|
75
84
|
const [key] = userOptions.normalizer(id);
|
|
76
|
-
id =
|
|
85
|
+
id = key + ".js";
|
|
77
86
|
}
|
|
78
|
-
const
|
|
87
|
+
const finalID = getID(id);
|
|
88
|
+
const transformed = await transformModuleIfNeeded(code, finalID, null);
|
|
79
89
|
if (!transformed) return null;
|
|
80
90
|
return {
|
|
81
91
|
code: transformed,
|
|
82
|
-
id:
|
|
92
|
+
id: finalID,
|
|
83
93
|
map: null,
|
|
84
94
|
};
|
|
85
95
|
},
|
|
@@ -38,6 +38,15 @@ export function reactTransformPlugin(options: StreamPluginOptions): Plugin {
|
|
|
38
38
|
|
|
39
39
|
let staticManifest: Manifest;
|
|
40
40
|
|
|
41
|
+
const getID = (id: string) => {
|
|
42
|
+
if(userOptions.moduleBasePath !== '' && !id.startsWith(userOptions.moduleBasePath)) {
|
|
43
|
+
id = join(userOptions.moduleBasePath, id);
|
|
44
|
+
}
|
|
45
|
+
if(!id.startsWith('/')) {
|
|
46
|
+
id = '/' + id;
|
|
47
|
+
}
|
|
48
|
+
return id;
|
|
49
|
+
}
|
|
41
50
|
return {
|
|
42
51
|
name: "vite:react-server-transform",
|
|
43
52
|
enforce: "pre", // Run before Vite's transforms
|
|
@@ -59,12 +68,12 @@ export function reactTransformPlugin(options: StreamPluginOptions): Plugin {
|
|
|
59
68
|
if (!ssr) return null;
|
|
60
69
|
if (!userOptions.autoDiscover.modulePattern(id)) return null;
|
|
61
70
|
if (!code.match('"use client"')) return null;
|
|
62
|
-
|
|
71
|
+
|
|
63
72
|
if (isBuild) {
|
|
64
73
|
const [key, value] = userOptions.normalizer(id);
|
|
65
74
|
if (staticManifest) {
|
|
66
75
|
if (value in staticManifest) {
|
|
67
|
-
id =
|
|
76
|
+
id = staticManifest[value].file
|
|
68
77
|
} else {
|
|
69
78
|
const hash = this.emitFile({
|
|
70
79
|
id,
|
|
@@ -75,15 +84,16 @@ export function reactTransformPlugin(options: StreamPluginOptions): Plugin {
|
|
|
75
84
|
// get fileName from hash
|
|
76
85
|
|
|
77
86
|
const fileName = this.getFileName(hash);
|
|
78
|
-
id =
|
|
87
|
+
id = fileName;
|
|
79
88
|
}
|
|
80
89
|
} else {
|
|
81
90
|
throw new Error(`Client manifest not found.`);
|
|
82
91
|
}
|
|
83
92
|
}
|
|
93
|
+
const finalID = getID(id);
|
|
84
94
|
const transformed = await transformModuleIfNeeded(
|
|
85
95
|
code,
|
|
86
|
-
|
|
96
|
+
finalID,
|
|
87
97
|
// Pass null for nextLoad since we don't need module loading in the plugin
|
|
88
98
|
null
|
|
89
99
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Worker,
|
|
3
3
|
type ResourceLimits,
|
|
4
|
-
type TransferListItem
|
|
4
|
+
type TransferListItem,
|
|
5
5
|
} from "node:worker_threads";
|
|
6
6
|
import { getMode, getNodePath } from "../config/getPaths.js";
|
|
7
7
|
import { getCondition } from "../config/getCondition.js";
|
|
@@ -14,6 +14,7 @@ export type CreateWorkerOptions = {
|
|
|
14
14
|
currentCondition?: "react-server" | "react-client";
|
|
15
15
|
nodePath?: string;
|
|
16
16
|
nodeOptions?: string[];
|
|
17
|
+
envPrefix?: string;
|
|
17
18
|
mode?: "production" | "development";
|
|
18
19
|
reverseCondition?: string;
|
|
19
20
|
maxListeners?: number;
|
|
@@ -50,6 +51,7 @@ export async function createWorker(
|
|
|
50
51
|
projectRoot = process.cwd(),
|
|
51
52
|
nodePath = getNodePath(projectRoot),
|
|
52
53
|
currentCondition = getCondition(),
|
|
54
|
+
envPrefix = "VITE_",
|
|
53
55
|
reverseCondition = currentCondition === "react-server"
|
|
54
56
|
? "react-client"
|
|
55
57
|
: "react-server",
|
|
@@ -61,7 +63,7 @@ export async function createWorker(
|
|
|
61
63
|
maxYoungGenerationSizeMb: 64,
|
|
62
64
|
},
|
|
63
65
|
htmlChunkSize = 8 * 1024,
|
|
64
|
-
transferList = []
|
|
66
|
+
transferList = [],
|
|
65
67
|
} = options;
|
|
66
68
|
let workerPathWithDefault =
|
|
67
69
|
typeof workerPath === "string" ? workerPath : undefined;
|
|
@@ -78,20 +80,10 @@ export async function createWorker(
|
|
|
78
80
|
// Ensure worker uses the same React version
|
|
79
81
|
const workerData = {
|
|
80
82
|
...options.workerData,
|
|
81
|
-
importMeta: {
|
|
82
|
-
env: {
|
|
83
|
-
DEV: mode === 'development' ? 'true' : 'false',
|
|
84
|
-
MODE: mode,
|
|
85
|
-
PROD: mode === 'production' ? 'true' : 'false',
|
|
86
|
-
SSR: true,
|
|
87
|
-
BASE_URL: '/',
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
83
|
reactVersion: React.version,
|
|
91
84
|
};
|
|
92
85
|
|
|
93
86
|
try {
|
|
94
|
-
|
|
95
87
|
// Ensure consistent NODE_ENV between main thread and worker
|
|
96
88
|
const isTestEnv =
|
|
97
89
|
process.env["VITEST"] || process.env["NODE_ENV"] === "test";
|
|
@@ -99,12 +91,17 @@ export async function createWorker(
|
|
|
99
91
|
|
|
100
92
|
const env = {
|
|
101
93
|
...process.env,
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
94
|
+
[envPrefix + "DEV"]: mode === "development" ? "1" : "0",
|
|
95
|
+
[envPrefix + "MODE"]: mode,
|
|
96
|
+
[envPrefix + "PROD"]: mode === "production" ? "1" : "0",
|
|
97
|
+
[envPrefix + "SSR"]: "true",
|
|
98
|
+
[envPrefix + "BASE"]:
|
|
99
|
+
options.workerData.userOptions.moduleBasePath === "" ||
|
|
100
|
+
options.workerData.userOptions.moduleBasePath === "/"
|
|
101
|
+
? "/"
|
|
102
|
+
: !options.workerData.userOptions.moduleBasePath.endsWith("/")
|
|
103
|
+
? options.workerData.userOptions.moduleBasePath + "/"
|
|
104
|
+
: options.workerData.userOptions.moduleBasePath,
|
|
108
105
|
NODE_ENV: nodeEnv,
|
|
109
106
|
NODE_PATH: nodePath,
|
|
110
107
|
NODE_OPTIONS: process.env["NODE_OPTIONS"]?.includes(reverseCondition)
|
|
@@ -140,10 +137,12 @@ export async function createWorker(
|
|
|
140
137
|
worker.once("message", (msg) => {
|
|
141
138
|
if (msg.type === "READY") {
|
|
142
139
|
clearTimeout(timeout);
|
|
143
|
-
if(msg.env !== nodeEnv) {
|
|
140
|
+
if (msg.env !== nodeEnv) {
|
|
144
141
|
reject({
|
|
145
142
|
type: "error",
|
|
146
|
-
error: new Error(
|
|
143
|
+
error: new Error(
|
|
144
|
+
`Worker environment mismatch: ${msg.env} !== ${nodeEnv}`
|
|
145
|
+
),
|
|
147
146
|
workerPath: workerPathWithDefault,
|
|
148
147
|
} satisfies CreateWorkerError);
|
|
149
148
|
}
|
|
@@ -185,4 +184,3 @@ export async function createWorker(
|
|
|
185
184
|
return error as CreateWorkerError;
|
|
186
185
|
}
|
|
187
186
|
}
|
|
188
|
-
|