vite-plugin-react-server 0.3.11 → 0.3.12

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.
Files changed (220) hide show
  1. package/dist/package.json +15 -11
  2. package/dist/plugin/checkFilesExist.d.ts +2 -2
  3. package/dist/plugin/checkFilesExist.d.ts.map +1 -1
  4. package/dist/plugin/checkFilesExist.js +39 -57
  5. package/dist/plugin/checkFilesExist.js.map +1 -1
  6. package/dist/plugin/collect-css-manifest.d.ts.map +1 -1
  7. package/dist/plugin/collect-css-manifest.js +5 -0
  8. package/dist/plugin/collect-css-manifest.js.map +1 -1
  9. package/dist/plugin/components.js +10 -15
  10. package/dist/plugin/config/createModuleIdGenerator.js +1 -1
  11. package/dist/plugin/config/createModuleIdGenerator.js.map +1 -1
  12. package/dist/plugin/config/defaults.d.ts +5 -14
  13. package/dist/plugin/config/defaults.d.ts.map +1 -1
  14. package/dist/plugin/config/defaults.js +12 -12
  15. package/dist/plugin/config/defaults.js.map +1 -1
  16. package/dist/plugin/config/getPaths.js +1 -1
  17. package/dist/plugin/config/resolveOptions.d.ts.map +1 -1
  18. package/dist/plugin/config/resolveOptions.js +73 -52
  19. package/dist/plugin/config/resolveOptions.js.map +1 -1
  20. package/dist/plugin/config/resolveUserConfig.d.ts.map +1 -1
  21. package/dist/plugin/config/resolveUserConfig.js +53 -65
  22. package/dist/plugin/config/resolveUserConfig.js.map +1 -1
  23. package/dist/plugin/helpers/getBundleManifest.d.ts +6 -1
  24. package/dist/plugin/helpers/getBundleManifest.d.ts.map +1 -1
  25. package/dist/plugin/helpers/getBundleManifest.js +48 -19
  26. package/dist/plugin/helpers/getBundleManifest.js.map +1 -1
  27. package/dist/plugin/helpers/inputNormalizer.d.ts +1 -2
  28. package/dist/plugin/helpers/inputNormalizer.d.ts.map +1 -1
  29. package/dist/plugin/helpers/inputNormalizer.js +52 -46
  30. package/dist/plugin/helpers/inputNormalizer.js.map +1 -1
  31. package/dist/plugin/helpers/tryManifest.d.ts +1 -1
  32. package/dist/plugin/helpers/tryManifest.d.ts.map +1 -1
  33. package/dist/plugin/helpers/tryManifest.js.map +1 -1
  34. package/dist/plugin/loader/createBuildLoader.d.ts +1 -1
  35. package/dist/plugin/loader/createBuildLoader.d.ts.map +1 -1
  36. package/dist/plugin/loader/createBuildLoader.js +29 -26
  37. package/dist/plugin/loader/createBuildLoader.js.map +1 -1
  38. package/dist/plugin/loader/css-loader.d.ts +16 -0
  39. package/dist/plugin/loader/css-loader.d.ts.map +1 -0
  40. package/dist/plugin/loader/css-loader.js +70 -0
  41. package/dist/plugin/loader/css-loader.js.map +1 -0
  42. package/dist/plugin/loader/react-loader.d.ts +17 -0
  43. package/dist/plugin/loader/react-loader.d.ts.map +1 -0
  44. package/dist/plugin/loader/react-loader.js +647 -0
  45. package/dist/plugin/loader/react-loader.js.map +1 -0
  46. package/dist/plugin/loader/rsc/messageHandler.d.ts +2 -0
  47. package/dist/plugin/loader/rsc/messageHandler.d.ts.map +1 -0
  48. package/dist/plugin/loader/rsc/messageHandler.js +1 -0
  49. package/dist/plugin/loader/rsc/rsc-worker.development.d.ts +2 -0
  50. package/dist/plugin/loader/rsc/rsc-worker.development.d.ts.map +1 -0
  51. package/dist/plugin/loader/rsc/rsc-worker.development.js +1 -0
  52. package/dist/plugin/react-client/index.js +2 -2
  53. package/dist/plugin/react-client/index.js.map +1 -1
  54. package/dist/plugin/react-client/plugin.d.ts.map +1 -1
  55. package/dist/plugin/react-client/plugin.js +202 -25
  56. package/dist/plugin/react-client/plugin.js.map +1 -1
  57. package/dist/plugin/react-server/createHandler.d.ts.map +1 -1
  58. package/dist/plugin/react-server/createHandler.js +10 -4
  59. package/dist/plugin/react-server/createHandler.js.map +1 -1
  60. package/dist/plugin/react-server/createRscStream.d.ts +15 -3
  61. package/dist/plugin/react-server/createRscStream.d.ts.map +1 -1
  62. package/dist/plugin/react-server/createRscStream.js +52 -49
  63. package/dist/plugin/react-server/createRscStream.js.map +1 -1
  64. package/dist/plugin/react-server/plugin.d.ts.map +1 -1
  65. package/dist/plugin/react-server/plugin.js +24 -20
  66. package/dist/plugin/react-server/plugin.js.map +1 -1
  67. package/dist/plugin/transformer/plugin.d.ts.map +1 -1
  68. package/dist/plugin/transformer/plugin.js +65 -52
  69. package/dist/plugin/transformer/plugin.js.map +1 -1
  70. package/dist/plugin/types.d.ts +5 -0
  71. package/dist/plugin/types.d.ts.map +1 -1
  72. package/dist/plugin/utils/logger.d.ts +9 -0
  73. package/dist/plugin/utils/logger.d.ts.map +1 -0
  74. package/dist/plugin/utils/logger.js +68 -0
  75. package/dist/plugin/utils/logger.js.map +1 -0
  76. package/dist/plugin/worker/createWorker.d.ts +1 -0
  77. package/dist/plugin/worker/createWorker.d.ts.map +1 -1
  78. package/dist/plugin/worker/createWorker.js +23 -36
  79. package/dist/plugin/worker/createWorker.js.map +1 -1
  80. package/dist/plugin/worker/html/html-worker.production.js +5 -1
  81. package/dist/plugin/worker/html/html-worker.production.js.map +1 -1
  82. package/dist/plugin/worker/html/messageHandler.d.ts.map +1 -1
  83. package/dist/plugin/worker/html/messageHandler.js +10 -19
  84. package/dist/plugin/worker/html/messageHandler.js.map +1 -1
  85. package/dist/plugin/worker/html/renderPages.d.ts +2 -2
  86. package/dist/plugin/worker/html/renderPages.d.ts.map +1 -1
  87. package/dist/plugin/worker/html/renderPages.js +130 -131
  88. package/dist/plugin/worker/html/renderPages.js.map +1 -1
  89. package/dist/plugin/worker/rsc/index.d.ts +1 -3
  90. package/dist/plugin/worker/rsc/index.d.ts.map +1 -1
  91. package/dist/plugin/worker/rsc/index.js +1 -9
  92. package/dist/plugin/worker/rsc/index.js.map +1 -1
  93. package/dist/plugin/worker/rsc/messageHandler.d.ts +3 -0
  94. package/dist/plugin/worker/rsc/messageHandler.d.ts.map +1 -0
  95. package/dist/plugin/worker/rsc/messageHandler.js +107 -0
  96. package/dist/plugin/worker/rsc/messageHandler.js.map +1 -0
  97. package/dist/plugin/worker/rsc/plugin.d.ts.map +1 -1
  98. package/dist/plugin/worker/rsc/plugin.js +74 -80
  99. package/dist/plugin/worker/rsc/rsc-worker.development.d.ts +32 -0
  100. package/dist/plugin/worker/rsc/rsc-worker.development.d.ts.map +1 -0
  101. package/dist/plugin/worker/rsc/rsc-worker.development.js +43 -0
  102. package/dist/plugin/worker/rsc/rsc-worker.development.js.map +1 -0
  103. package/dist/plugin/worker/rsc/rsc-worker.js +4 -106
  104. package/dist/plugin/worker/rsc/rsc-worker.production.d.ts +2 -0
  105. package/dist/plugin/worker/rsc/rsc-worker.production.d.ts.map +1 -0
  106. package/dist/plugin/worker/rsc/rsc-worker.production.js +14 -0
  107. package/dist/plugin/worker/rsc/rsc-worker.production.js.map +1 -0
  108. package/dist/plugin/worker/rsc/state.d.ts +11 -0
  109. package/dist/plugin/worker/rsc/state.d.ts.map +1 -0
  110. package/dist/plugin/worker/rsc/state.js +12 -0
  111. package/dist/plugin/worker/rsc/state.js.map +1 -0
  112. package/dist/plugin/worker/types.d.ts +60 -46
  113. package/dist/plugin/worker/types.d.ts.map +1 -1
  114. package/dist/tsconfig.tsbuildinfo +1 -1
  115. package/package.json +15 -11
  116. package/plugin/checkFilesExist.ts +42 -62
  117. package/plugin/collect-css-manifest.ts +5 -1
  118. package/plugin/config/createModuleIdGenerator.ts +1 -1
  119. package/plugin/config/defaults.ts +13 -15
  120. package/plugin/config/resolveOptions.ts +134 -76
  121. package/plugin/config/resolveUserConfig.ts +75 -76
  122. package/plugin/helpers/getBundleManifest.ts +69 -31
  123. package/plugin/helpers/inputNormalizer.ts +82 -70
  124. package/plugin/helpers/tryManifest.ts +1 -1
  125. package/plugin/loader/createBuildLoader.ts +38 -41
  126. package/plugin/loader/css-loader.ts +96 -0
  127. package/plugin/loader/react-loader.ts +945 -0
  128. package/plugin/loader/rsc/messageHandler.tsx +1 -0
  129. package/plugin/loader/rsc/rsc-worker.development.ts +1 -0
  130. package/plugin/react-client/index.ts +1 -1
  131. package/plugin/react-client/plugin.ts +266 -41
  132. package/plugin/react-server/createHandler.ts +9 -5
  133. package/plugin/react-server/createRscStream.ts +75 -54
  134. package/plugin/react-server/plugin.ts +26 -21
  135. package/plugin/transformer/plugin.ts +67 -76
  136. package/plugin/types/global.d.ts +8 -0
  137. package/plugin/types.ts +2 -0
  138. package/plugin/utils/logger.ts +52 -0
  139. package/plugin/worker/createWorker.ts +43 -44
  140. package/plugin/worker/html/html-worker.production.tsx +7 -2
  141. package/plugin/worker/html/messageHandler.ts +13 -21
  142. package/plugin/worker/html/renderPages.ts +146 -179
  143. package/plugin/worker/rsc/index.ts +4 -13
  144. package/plugin/worker/rsc/messageHandler.tsx +143 -0
  145. package/plugin/worker/rsc/plugin.ts +38 -37
  146. package/plugin/worker/rsc/rsc-worker.development.ts +107 -0
  147. package/plugin/worker/rsc/rsc-worker.production.ts +13 -0
  148. package/plugin/worker/rsc/rsc-worker.tsx +5 -128
  149. package/plugin/worker/rsc/state.ts +37 -0
  150. package/plugin/worker/types.ts +79 -55
  151. package/scripts/check-react-version.mjs +17 -7
  152. package/scripts/react+0.0.0-experimental-b3a95caf-20250113.patch +143 -4170
  153. package/scripts/react-dom+0.0.0-experimental-b3a95caf-20250113.patch +14271 -90079
  154. package/dist/plugin/components.js.map +0 -1
  155. package/dist/plugin/helpers/createClientInputNormalizer.d.ts +0 -8
  156. package/dist/plugin/helpers/createClientInputNormalizer.d.ts.map +0 -1
  157. package/dist/plugin/helpers/createClientInputNormalizer.js +0 -35
  158. package/dist/plugin/helpers/createServerInputNormalizer.d.ts +0 -9
  159. package/dist/plugin/helpers/createServerInputNormalizer.d.ts.map +0 -1
  160. package/dist/plugin/helpers/createServerInputNormalizer.js +0 -37
  161. package/dist/plugin/helpers/createStaticInputNormalizer.d.ts +0 -7
  162. package/dist/plugin/helpers/createStaticInputNormalizer.d.ts.map +0 -1
  163. package/dist/plugin/helpers/createStaticInputNormalizer.js +0 -18
  164. package/dist/plugin/helpers/getModuleManifest.d.ts +0 -17
  165. package/dist/plugin/helpers/getModuleManifest.d.ts.map +0 -1
  166. package/dist/plugin/helpers/getModuleManifest.js +0 -23
  167. package/dist/plugin/helpers/inputNormalizerWorker.d.ts +0 -12
  168. package/dist/plugin/helpers/inputNormalizerWorker.d.ts.map +0 -1
  169. package/dist/plugin/helpers/inputNormalizerWorker.js +0 -33
  170. package/dist/plugin/helpers/normalizedRelativePath.d.ts +0 -11
  171. package/dist/plugin/helpers/normalizedRelativePath.d.ts.map +0 -1
  172. package/dist/plugin/helpers/normalizedRelativePath.js +0 -36
  173. package/dist/plugin/helpers/resolveFilePath.d.ts +0 -13
  174. package/dist/plugin/helpers/resolveFilePath.d.ts.map +0 -1
  175. package/dist/plugin/helpers/resolveFilePath.js +0 -74
  176. package/dist/plugin/helpers/resolveWorkerModule.d.ts +0 -6
  177. package/dist/plugin/helpers/resolveWorkerModule.d.ts.map +0 -1
  178. package/dist/plugin/helpers/resolveWorkerModule.js +0 -24
  179. package/dist/plugin/helpers/validateModuleBase.d.ts +0 -3
  180. package/dist/plugin/helpers/validateModuleBase.d.ts.map +0 -1
  181. package/dist/plugin/helpers/validateModuleBase.js +0 -16
  182. package/dist/plugin/helpers/validateResolvedConfig.d.ts +0 -3
  183. package/dist/plugin/helpers/validateResolvedConfig.d.ts.map +0 -1
  184. package/dist/plugin/helpers/validateResolvedConfig.js +0 -17
  185. package/dist/plugin/transformer/transformer-client-components.d.ts +0 -30
  186. package/dist/plugin/transformer/transformer-client-components.d.ts.map +0 -1
  187. package/dist/plugin/transformer/transformer-client-components.js +0 -122
  188. package/dist/plugin/transformer/transformer-client-components.js.map +0 -1
  189. package/dist/plugin/transformer/transformer-server-actions.d.ts +0 -29
  190. package/dist/plugin/transformer/transformer-server-actions.d.ts.map +0 -1
  191. package/dist/plugin/transformer/transformer-server-actions.js +0 -90
  192. package/dist/plugin/worker/rsc/createRscStream.d.ts +0 -5
  193. package/dist/plugin/worker/rsc/createRscStream.d.ts.map +0 -1
  194. package/dist/plugin/worker/rsc/createRscStream.js +0 -39
  195. package/dist/plugin/worker/rsc/createRscStream.js.map +0 -1
  196. package/dist/plugin/worker/rsc/development.d.ts +0 -5
  197. package/dist/plugin/worker/rsc/development.d.ts.map +0 -1
  198. package/dist/plugin/worker/rsc/development.js +0 -13
  199. package/dist/plugin/worker/rsc/development.js.map +0 -1
  200. package/dist/plugin/worker/rsc/plugin.js.map +0 -1
  201. package/dist/plugin/worker/rsc/production.d.ts +0 -5
  202. package/dist/plugin/worker/rsc/production.d.ts.map +0 -1
  203. package/dist/plugin/worker/rsc/production.js +0 -13
  204. package/dist/plugin/worker/rsc/production.js.map +0 -1
  205. package/plugin/helpers/createClientInputNormalizer.ts +0 -48
  206. package/plugin/helpers/createServerInputNormalizer.ts +0 -52
  207. package/plugin/helpers/createStaticInputNormalizer.ts +0 -26
  208. package/plugin/helpers/getModuleManifest.ts +0 -36
  209. package/plugin/helpers/inputNormalizerWorker.ts +0 -52
  210. package/plugin/helpers/normalizedRelativePath.ts +0 -59
  211. package/plugin/helpers/resolveFilePath.ts +0 -108
  212. package/plugin/helpers/resolveWorkerModule.ts +0 -41
  213. package/plugin/helpers/validateModuleBase.ts +0 -30
  214. package/plugin/helpers/validateResolvedConfig.ts +0 -21
  215. package/plugin/transformer/transformer-client-components.ts +0 -168
  216. package/plugin/transformer/transformer-server-actions.ts +0 -125
  217. package/plugin/worker/rsc/createRscStream.ts +0 -42
  218. package/plugin/worker/rsc/development.ts +0 -6
  219. package/plugin/worker/rsc/production.ts +0 -6
  220. package/scripts/react-server-dom-esm+0.0.1.patch +0 -24775
@@ -29,7 +29,7 @@ import { type StreamPluginOptions } from "../types.js";
29
29
  import { createWorker } from "../worker/createWorker.js";
30
30
  import { renderPages } from "../worker/html/renderPages.js";
31
31
  import { createHandler } from "./createHandler.js";
32
- import { mkdir, writeFile } from "node:fs/promises";
32
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
33
33
  import { getBundleManifest } from "../helpers/getBundleManifest.js";
34
34
  import type { ServerResponse } from "node:http";
35
35
 
@@ -39,6 +39,7 @@ let clientManifestPath: string | null = null;
39
39
  let outpuptBundle: any;
40
40
  let outputOptions: any;
41
41
  let loader: ((id: string) => Promise<Record<string, any>>) | null = null;
42
+ let worker: Worker;
42
43
  export function reactServerPlugin(
43
44
  options: StreamPluginOptions
44
45
  ): import("vite").Plugin<{
@@ -51,7 +52,6 @@ export function reactServerPlugin(
51
52
 
52
53
  let files: CheckFilesExistReturn;
53
54
  // let env: Awaited<ReturnType<typeof getEnv>>;
54
- let worker: Worker;
55
55
  let cssModules = new Set<string>();
56
56
  let clientComponents = new Map<string, string>();
57
57
  // let define: Record<string, string>;
@@ -166,6 +166,7 @@ export function reactServerPlugin(
166
166
  root = server.config.root;
167
167
  }
168
168
 
169
+
169
170
  const activeStreams = new Set<ServerResponse>();
170
171
 
171
172
  // Handle Vite server restarts
@@ -209,7 +210,7 @@ export function reactServerPlugin(
209
210
  projectRoot: root,
210
211
  },
211
212
  {
212
- cssFiles: Array.from(cssModules),
213
+ cssFiles: [],
213
214
  logger: createLogger(),
214
215
  loader,
215
216
  moduleGraph: server.moduleGraph,
@@ -260,7 +261,6 @@ export function reactServerPlugin(
260
261
  }
261
262
 
262
263
  userConfig = resolvedConfig.userConfig;
263
-
264
264
  return resolvedConfig.userConfig;
265
265
  },
266
266
  async buildStart() {
@@ -305,11 +305,18 @@ export function reactServerPlugin(
305
305
  nodeOptions: "--conditions=react-client",
306
306
  });
307
307
 
308
- // Use both manifests directly
308
+ // Create the loader
309
309
  if (typeof loader !== "function") {
310
310
  if (!Object.keys(serverManifest).length) {
311
- serverManifest = getBundleManifest(this, outpuptBundle, undefined);
311
+ console.warn("[vite-plugin-react-server] No server manifest found, the plugin will try to use the plugin context - it may differ from vite's manifest.");
312
+ serverManifest = getBundleManifest({
313
+ pluginContext: this,
314
+ bundle: outpuptBundle,
315
+ moduleBase: userOptions.moduleBase,
316
+ preserveModulesRoot: userOptions.build.preserveModulesRoot,
317
+ });
312
318
  if (!Object.keys(serverManifest).length) {
319
+ console.warn("[vite-plugin-react-server] That didn't work, retrying to read manifest.");
313
320
  const resolvedServerManifest = tryManifest({
314
321
  root: root,
315
322
  outDir: join(userOptions.build.outDir, userOptions.build.server),
@@ -317,6 +324,7 @@ export function reactServerPlugin(
317
324
  });
318
325
  if (resolvedServerManifest.type === "error") {
319
326
  // dont build the static files without a server manifest
327
+ console.error("[vite-plugin-react-server] Failed to read manifest, aborting build.");
320
328
  return;
321
329
  }
322
330
  serverManifest = resolvedServerManifest.manifest;
@@ -338,6 +346,7 @@ export function reactServerPlugin(
338
346
  const { failedRoutes, completedRoutes } = await renderPages(
339
347
  this,
340
348
  resolvedPages.pages,
349
+ files,
341
350
  {
342
351
  pipableStreamOptions: {},
343
352
  moduleBasePath: "",
@@ -353,10 +362,13 @@ export function reactServerPlugin(
353
362
  clientManifest: clientManifest,
354
363
  serverManifest: serverManifest,
355
364
  loader,
356
- onCssFile: (path: string) => {
357
- console.log("[vite-plugin-react-server] onCssFile", path);
365
+ onCssFile: async (path: string) => {
358
366
  if (buildCssFiles && path.endsWith(".css")) {
359
367
  buildCssFiles.add(path);
368
+ // copy the file to the client build dir
369
+ const clientPath = join(userOptions.build.outDir, userOptions.build.client, path);
370
+ await mkdir(dirname(clientPath), { recursive: true });
371
+ await writeFile(clientPath, await readFile(join(root, userOptions.build.outDir, userOptions.build.server, path)));
360
372
  }
361
373
  },
362
374
  }
@@ -421,7 +433,6 @@ export function reactServerPlugin(
421
433
 
422
434
  // Ensure worker is terminated
423
435
  if (worker) {
424
- console.log("[vite-plugin-react-server] Terminating worker...");
425
436
  await worker.terminate();
426
437
  worker = null as any;
427
438
  }
@@ -451,8 +462,12 @@ export function reactServerPlugin(
451
462
  outpuptBundle = bundle;
452
463
  outputOptions = options;
453
464
  // Create manifest entries for each chunk
454
- serverManifest = getBundleManifest(this, bundle, undefined);
455
- console.log("[vite:plugin-react-server] Server manifest", serverManifest);
465
+ serverManifest = getBundleManifest({
466
+ pluginContext: this,
467
+ bundle,
468
+ moduleBase: userOptions.moduleBase,
469
+ preserveModulesRoot: userOptions.build.preserveModulesRoot,
470
+ });
456
471
  if (serverManifestPath) {
457
472
  await mkdir(dirname(serverManifestPath), { recursive: true });
458
473
  await writeFile(
@@ -461,15 +476,5 @@ export function reactServerPlugin(
461
476
  );
462
477
  }
463
478
  },
464
- async renderChunk(code: string, chunk, options) {
465
- if (chunk.fileName.includes("html-worker")) {
466
- const workerPath = resolve(root, chunk.fileName);
467
- worker = await createWorker({
468
- projectRoot: userOptions.projectRoot,
469
- workerPath,
470
- });
471
- }
472
- return null;
473
- },
474
479
  };
475
480
  }
@@ -1,20 +1,11 @@
1
1
  import { resolveOptions } from "../config/resolveOptions.js";
2
- import type {
3
- ResolvedUserConfig,
4
- ResolvedUserOptions,
5
- StreamPluginOptions,
6
- } from "../types.js";
7
- import { createClientComponentTransformer } from "./transformer-client-components.js";
8
- import { createModuleIdGenerator } from "../config/createModuleIdGenerator.js";
9
- import { type ConfigEnv, type Plugin, type ResolvedConfig } from "vite";
2
+ import type { StreamPluginOptions } from "../types.js";
3
+ import { type Plugin } from "vite";
4
+ import { transformModuleIfNeeded } from "../loader/react-loader.js";
5
+ import { DEFAULT_CONFIG } from "../config/defaults.js";
10
6
  import { createInputNormalizer } from "../helpers/inputNormalizer.js";
11
- import { resolveUserConfig } from "../config/resolveUserConfig.js";
12
-
13
- let userOptions: ResolvedUserOptions;
14
- let userConfig: ResolvedUserConfig;
15
- let resolvedConfig: ResolvedConfig;
16
- let resolvedConfigEnv: ConfigEnv;
17
-
7
+ import { tryManifest } from "../helpers/tryManifest.js";
8
+ import { join } from "node:path";
18
9
  /**
19
10
  * Plugin for transforming React Client Components.
20
11
  *
@@ -41,76 +32,76 @@ let resolvedConfigEnv: ConfigEnv;
41
32
  */
42
33
 
43
34
  export function reactTransformPlugin(options: StreamPluginOptions): Plugin {
44
- const resolvedUserOptions = resolveOptions(options);
45
- if (resolvedUserOptions.type === "error") {
46
- throw resolvedUserOptions.error;
47
- }
48
- userOptions = resolvedUserOptions.userOptions;
35
+ const resolvedOptions = resolveOptions(options);
36
+ let isDev = false;
37
+ if (resolvedOptions.type === "error") throw resolvedOptions.error;
38
+ const normalizer = createInputNormalizer({
39
+ root: resolvedOptions.userOptions.projectRoot,
40
+ preserveModulesRoot: undefined,
41
+ removeExtension: false,
42
+ });
49
43
 
50
- let manifest: Record<string, { file: string }> = {};
51
- const pendingEmits = new Map<string, { referenceId: string }>();
44
+ // Get the client manifest
45
+ const clientManifestResult = tryManifest({
46
+ root: resolvedOptions.userOptions.projectRoot,
47
+ outDir: join(
48
+ resolvedOptions.userOptions.build.outDir,
49
+ resolvedOptions.userOptions.build.client
50
+ ),
51
+ ssrManifest: false,
52
+ });
52
53
 
53
54
  return {
54
55
  name: "vite:react-transform",
55
- enforce: "post",
56
-
56
+ enforce: "pre", // Run before Vite's transforms
57
57
  config(config, configEnv) {
58
- const resolvedUserConfig = resolveUserConfig({
59
- isClient: false,
60
- config,
61
- configEnv,
62
- userOptions,
63
- });
64
- if (resolvedUserConfig.type === "error") {
65
- throw resolvedUserConfig.error;
66
- }
67
- userConfig = resolvedUserConfig.userConfig;
68
- resolvedConfigEnv = configEnv;
58
+ isDev = configEnv.mode === "development" && configEnv.command === "serve";
69
59
  },
70
- configResolved(config) {
71
- resolvedConfig = config;
72
- },
73
-
74
- transform(code: string, id: string, opt: { ssr?: boolean } = {}) {
75
- const hasClientDirective = code.match(/^["']use client["'];?/);
76
- if (!hasClientDirective) return null;
77
-
78
- const moduleInfo = this.getModuleInfo(id);
79
- if (!moduleInfo) return null;
80
-
81
- // In dev mode, just transform the code without emitting
82
- if (resolvedConfigEnv.command === 'serve') {
83
- const transformer = createClientComponentTransformer(userOptions, userConfig, resolvedConfigEnv);
84
- return transformer.transform!.bind(this)(code, id, opt);
60
+ async transform(code, id, options) {
61
+ const ssr = options?.ssr ?? false;
62
+ if (!ssr) return null;
63
+ if (!id.match(DEFAULT_CONFIG.FILE_REGEX)) return null;
64
+ if (!code.match('"use client"'))
65
+ return null;
66
+ const [key, value] = normalizer(id);
67
+ const transformed = await transformModuleIfNeeded(
68
+ code,
69
+ id,
70
+ // Pass null for nextLoad since we don't need module loading in the plugin
71
+ null
72
+ );
73
+ if (!transformed) return null;
74
+ if (isDev) {
75
+ return {
76
+ code: transformed,
77
+ map: null,
78
+ };
85
79
  }
80
+ const moduleIdIndex = transformed.indexOf(value);
81
+ if (moduleIdIndex === -1) {
82
+ console.warn(
83
+ `[vite-plugin-react-server] Could not find module id in transformed code. Ignoring.`,
84
+ {
85
+ code,
86
+ id,
87
+ transformed,
88
+ }
89
+ );
90
+ return null
91
+ }
92
+ if (clientManifestResult.type === "error") {
93
+ throw clientManifestResult.error;
94
+ }
95
+ const clientPath = clientManifestResult.manifest[key]?.file;
86
96
 
87
- // Production build logic...
88
- const normalizer = createInputNormalizer({
89
- root: resolvedConfig.root,
90
- preserveModulesRoot: undefined,
91
- });
92
- const [normalizedId, normalizedPath] = normalizer(id);
93
-
94
- // Add to manifest immediately with a temporary path
95
- manifest[normalizedId] = { file: normalizedPath };
96
-
97
- const referenceId = this.emitFile({
98
- type: "chunk",
99
- id: normalizedPath,
100
- name: normalizedId,
101
- });
102
- pendingEmits.set(normalizedId, { referenceId });
103
-
104
- const transformer = createClientComponentTransformer(userOptions, userConfig, resolvedConfigEnv);
105
- return transformer.transform!.bind(this)(code, id, opt);
106
- },
107
-
108
- renderDynamicImport() {
109
- // Update manifest with real file names
110
- for (const [normalizedId, { referenceId }] of pendingEmits) {
111
- const fileName = this.getFileName(referenceId);
112
- manifest[normalizedId] = { file: fileName };
97
+ if (!clientPath) {
98
+ console.warn(`[vite-plugin-react-server] Could not find client path for ${value}. Ignoring.`)
99
+ return null
113
100
  }
101
+ return {
102
+ code: transformed.replace(key, join(resolvedOptions.userOptions.build.client, clientPath)),
103
+ map: null,
104
+ };
114
105
  },
115
106
  };
116
107
  }
@@ -0,0 +1,8 @@
1
+ import type { EventEmitter } from 'node:events';
2
+
3
+ declare global {
4
+ var __RSC_CSS_FILES__: Set<string>;
5
+ var __RSC_CSS_EVENTS__: EventEmitter;
6
+ }
7
+
8
+ export {};
package/plugin/types.ts CHANGED
@@ -337,6 +337,8 @@ export type CheckFilesExistReturn = {
337
337
  propsSet: Set<string>;
338
338
  pageMap: Map<string, string>;
339
339
  pageSet: Set<string>;
340
+ urlMap: Map<string, {props: string, page: string}>;
341
+ errors: string[];
340
342
  };
341
343
 
342
344
  // Add strict type checking for worker messages
@@ -0,0 +1,52 @@
1
+ import { createLogger as createViteLogger, type LogLevel } from 'vite';
2
+
3
+
4
+ const isPrimitive = (value: any) => {
5
+ return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'symbol';
6
+ }
7
+
8
+ const buildMessage = (prefix: string, msg: string, ...args: any[]) => {
9
+ let buildMsg = `[${prefix}] ${msg}`
10
+ for(const arg of args) {
11
+ if(isPrimitive(arg)) {
12
+ buildMsg += `\n[${prefix}] ${String(arg)}`;
13
+ } else if(arg instanceof Error) {
14
+ buildMsg += `\n[${prefix}] ${arg.name}`
15
+ buildMsg += `\n[${prefix}] ${arg.message}`
16
+ buildMsg += `\n[${prefix}] ${arg.stack}`
17
+ buildMsg += `\n[${prefix}] ${arg.cause}`
18
+ } else {
19
+ buildMsg += `\n[${prefix}] ${JSON.stringify(arg)}`;
20
+ }
21
+ }
22
+ return buildMsg;
23
+ }
24
+
25
+ export const createLogger = (process.env['NODE_ENV'] === 'development') ? (prefix: string, logLevel: LogLevel = 'info') => {
26
+ const logger = createViteLogger(logLevel, {
27
+ allowClearScreen: true
28
+ });
29
+ return {
30
+ clear: () => logger.clearScreen('info'),
31
+ info: (msg: string, ...args: any[]) => {
32
+ console.log(buildMessage(prefix, msg, ...args))
33
+ },
34
+ warn: (msg: string, ...args: any[]) => {
35
+ console.warn(buildMessage(prefix, msg, ...args))
36
+ },
37
+ error: (msg: string, ...args: any[]) => {
38
+ console.error(buildMessage(prefix, msg, ...args))
39
+ },
40
+ debug: (msg: string, ...args: any[]) => {
41
+ console.debug(buildMessage(prefix, msg, ...args))
42
+ }
43
+ };
44
+ } : () => {
45
+ return {
46
+ clear: () => {},
47
+ info: () => {},
48
+ warn: () => {},
49
+ error: () => {},
50
+ debug: () => {},
51
+ };
52
+ };
@@ -12,6 +12,7 @@ type CreateWorkerOptions = {
12
12
  maxListeners?: number;
13
13
  workerPath: string;
14
14
  resourceLimits?: ResourceLimits;
15
+ typescript?: boolean;
15
16
  };
16
17
 
17
18
  export async function createWorker(options: CreateWorkerOptions) {
@@ -26,59 +27,57 @@ export async function createWorker(options: CreateWorkerOptions) {
26
27
  resourceLimits = {
27
28
  maxOldGenerationSizeMb: 512,
28
29
  maxYoungGenerationSizeMb: 128,
29
- }
30
+ },
30
31
  } = options;
31
32
 
32
33
  // Ensure consistent NODE_ENV between main thread and worker
33
- const isTestEnv = process.env['VITEST'] || process.env['NODE_ENV'] === 'test';
34
- const nodeEnv = isTestEnv ? 'development' : mode;
34
+ const isTestEnv = process.env["VITEST"] || process.env["NODE_ENV"] === "test";
35
+ const nodeEnv = isTestEnv ? "development" : mode;
35
36
 
36
37
  const env = {
37
38
  ...process.env,
38
39
  NODE_ENV: nodeEnv,
39
40
  NODE_PATH: nodePath,
40
- // Clear any inherited conditions for worker
41
- NODE_OPTIONS: reverseCondition ?
42
- (condition === 'react-server' ? '--conditions=react-client' : '--conditions=react-server')
43
- : process.env['NODE_OPTIONS']
41
+ NODE_OPTIONS: `${
42
+ reverseCondition
43
+ ? condition === "react-server"
44
+ ? process.env["NODE_OPTIONS"]?.includes("react-server")
45
+ ? process.env["NODE_OPTIONS"]?.replace("react-server", "react-client")
46
+ : `${process.env["NODE_OPTIONS"] ?? ''} --conditions=react-client`
47
+ : process.env["NODE_OPTIONS"]?.includes("react-client")
48
+ ? process.env["NODE_OPTIONS"]?.replace("react-client", "react-server")
49
+ : `${process.env["NODE_OPTIONS"] ?? ''} --conditions=react-server`
50
+ : process.env["NODE_OPTIONS"]
51
+ }`,
44
52
  };
45
- const maxRetries = 3;
46
- for (let tries = 0; tries < maxRetries; tries++) {
47
- try {
48
- const worker = new Worker(workerPath.startsWith('/') ? workerPath : join(projectRoot, workerPath), {
49
- env,
50
- // Increase resource limits for stream handling
51
- resourceLimits: resourceLimits
52
- });
53
-
54
- worker.setMaxListeners(maxListeners);
55
53
 
56
- // Wait for worker to be ready and verify environment
57
- const ready = await Promise.race([
58
- new Promise((_, reject) => {
59
- setTimeout(() => reject(new Error(`Worker startup timeout: ${workerPath}`)), 5000);
60
- }),
61
- new Promise((resolve, reject) => {
62
- worker.once('message', (msg) => {
63
- if (msg.type === 'READY') {
64
- if(msg.env === nodeEnv) {
65
- resolve(true);
66
- } else {
67
- reject(new Error(`Worker environment mismatch: expected ${nodeEnv}, got ${msg.env}`));
68
- }
69
- } else if (msg.type === 'ERROR') {
70
- reject(new Error(msg.error));
71
- }
72
- });
73
- worker.once('error', reject);
74
- })
75
- ]);
76
-
77
- if (ready) return worker;
78
- } catch (error) {
79
- console.warn(`Worker startup attempt ${tries + 1} failed:`, error);
80
- if (tries === maxRetries - 1) throw error;
54
+ // Create worker with proper environment
55
+ const worker = new Worker(
56
+ workerPath.startsWith("/") ? workerPath : join(projectRoot, workerPath),
57
+ {
58
+ env,
59
+ resourceLimits,
81
60
  }
82
- }
83
- throw new Error('Failed to start worker after retries');
61
+ );
62
+
63
+ worker.setMaxListeners(maxListeners);
64
+
65
+ // Wait for worker to be ready
66
+ return await new Promise<Worker>((resolve, reject) => {
67
+ const timeout = setTimeout(() => {
68
+ reject(new Error('Worker ready timeout'));
69
+ }, 5000);
70
+
71
+ worker.once("message", (msg) => {
72
+ if (msg.type === "READY" && msg.env === nodeEnv) {
73
+ clearTimeout(timeout);
74
+ resolve(worker);
75
+ }
76
+ });
77
+
78
+ worker.once("error", (error) => {
79
+ clearTimeout(timeout);
80
+ reject(error);
81
+ });
82
+ });
84
83
  }
@@ -1,8 +1,13 @@
1
1
  import { messageHandler } from "./messageHandler.js";
2
2
  import { parentPort } from "node:worker_threads";
3
3
 
4
+ let ready = false;
4
5
  if (!parentPort) throw new Error("This module must be run as a worker");
5
- parentPort?.on("message", messageHandler);
6
6
 
7
7
  // Signal ready with environment
8
- parentPort?.postMessage({ type: "READY", env: process.env["NODE_ENV"] });
8
+ parentPort?.on("message", messageHandler);
9
+ parentPort?.postMessage({
10
+ type: "READY",
11
+ env: process.env["NODE_ENV"],
12
+ pid: process.pid
13
+ });
@@ -8,30 +8,19 @@ import {
8
8
  // @ts-ignore
9
9
  } from "react-server-dom-esm/client.node";
10
10
  import { join } from "path";
11
- import { readFileSync } from "node:fs";
12
- import { existsSync } from "node:fs";
13
11
 
14
12
  // Track active renders and streams
15
13
  const activeRenders = new Map<string, HtmlRenderState>();
16
14
  const htmlContent = new Map<string, string>();
17
15
  const htmlPromises = new Map<string, Promise<string>>();
18
16
 
17
+
19
18
  export const messageHandler = async (message: HtmlWorkerMessage) => {
20
19
  try {
21
20
  switch (message.type) {
22
21
  case "RSC_CHUNK": {
23
- const {
24
- id,
25
- chunk,
26
- moduleRootPath,
27
- moduleBaseURL,
28
- outDir,
29
- pipableStreamOptions,
30
- clientManifest = {},
31
- serverManifest = {},
32
- htmlOutputPath,
33
- } = message;
34
-
22
+ const { id, chunk, moduleRootPath, moduleBaseURL, htmlOutputPath, pipableStreamOptions } = message;
23
+
35
24
  const render = activeRenders.get(id);
36
25
  if (!render) {
37
26
  activeRenders.set(id, {
@@ -41,8 +30,8 @@ export const messageHandler = async (message: HtmlWorkerMessage) => {
41
30
  rendered: false,
42
31
  moduleRootPath,
43
32
  moduleBaseURL,
44
- outDir,
45
- htmlOutputPath: htmlOutputPath ?? join(outDir, 'index.html'),
33
+ outDir: '',
34
+ htmlOutputPath: htmlOutputPath ?? join(process.cwd(), 'index.html'),
46
35
  pipableStreamOptions: pipableStreamOptions,
47
36
  });
48
37
  } else {
@@ -120,12 +109,15 @@ export const messageHandler = async (message: HtmlWorkerMessage) => {
120
109
  htmlPromises.delete(id);
121
110
  break;
122
111
  }
112
+
113
+ case "SHUTDOWN": {
114
+ console.log('Received shutdown signal');
115
+ parentPort?.close();
116
+ break;
117
+ }
123
118
  }
124
119
  } catch (error) {
125
- parentPort?.postMessage({
126
- type: "ERROR",
127
- id: message.type === "RSC_CHUNK" || message.type === "RSC_END" ? message.id : "",
128
- error: error instanceof Error ? error.message : String(error),
129
- });
120
+ console.error('Error in messageHandler:', error);
121
+ throw error;
130
122
  }
131
123
  };