vite-plugin-react-server 0.3.9 → 0.3.11

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 (197) hide show
  1. package/dist/client.d.ts +1 -1
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +1 -1
  4. package/dist/index.d.ts +3 -6
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/package.json +2 -4
  9. package/dist/plugin/assertServerCondition.d.ts +5 -1
  10. package/dist/plugin/assertServerCondition.d.ts.map +1 -1
  11. package/dist/plugin/assertServerCondition.js +1 -3
  12. package/dist/plugin/checkFilesExist.js +10 -7
  13. package/dist/plugin/checkFilesExist.js.map +1 -1
  14. package/dist/plugin/components.js +1 -1
  15. package/dist/plugin/components.js.map +1 -1
  16. package/dist/plugin/config/createModuleIdGenerator.d.ts +11 -0
  17. package/dist/plugin/config/createModuleIdGenerator.d.ts.map +1 -0
  18. package/dist/plugin/config/createModuleIdGenerator.js +44 -0
  19. package/dist/plugin/config/createModuleIdGenerator.js.map +1 -0
  20. package/dist/plugin/config/defaults.d.ts +31 -19
  21. package/dist/plugin/config/defaults.d.ts.map +1 -1
  22. package/dist/plugin/config/defaults.js +22 -27
  23. package/dist/plugin/config/defaults.js.map +1 -1
  24. package/dist/plugin/config/resolveOptions.d.ts +1 -1
  25. package/dist/plugin/config/resolveOptions.d.ts.map +1 -1
  26. package/dist/plugin/config/resolveOptions.js +202 -16
  27. package/dist/plugin/config/resolveOptions.js.map +1 -1
  28. package/dist/plugin/config/resolvePages.d.ts +2 -0
  29. package/dist/plugin/config/resolvePages.d.ts.map +1 -1
  30. package/dist/plugin/config/resolvePages.js.map +1 -1
  31. package/dist/plugin/config/resolveUserConfig.d.ts +2 -2
  32. package/dist/plugin/config/resolveUserConfig.d.ts.map +1 -1
  33. package/dist/plugin/config/resolveUserConfig.js +161 -50
  34. package/dist/plugin/config/resolveUserConfig.js.map +1 -1
  35. package/dist/plugin/helpers/getBundleManifest.d.ts +20 -0
  36. package/dist/plugin/helpers/getBundleManifest.d.ts.map +1 -0
  37. package/dist/plugin/helpers/getBundleManifest.js +43 -0
  38. package/dist/plugin/helpers/getBundleManifest.js.map +1 -0
  39. package/dist/plugin/helpers/getModuleManifest.d.ts +5 -0
  40. package/dist/plugin/helpers/getModuleManifest.d.ts.map +1 -1
  41. package/dist/plugin/helpers/getModuleManifest.js +20 -21
  42. package/dist/plugin/helpers/inputNormalizer.d.ts +15 -1
  43. package/dist/plugin/helpers/inputNormalizer.d.ts.map +1 -1
  44. package/dist/plugin/helpers/inputNormalizer.js +122 -16
  45. package/dist/plugin/helpers/inputNormalizer.js.map +1 -1
  46. package/dist/plugin/helpers/inputNormalizerWorker.d.ts +2 -1
  47. package/dist/plugin/helpers/inputNormalizerWorker.d.ts.map +1 -1
  48. package/dist/plugin/helpers/inputNormalizerWorker.js +10 -7
  49. package/dist/plugin/helpers/tryManifest.d.ts +2 -0
  50. package/dist/plugin/helpers/tryManifest.d.ts.map +1 -1
  51. package/dist/plugin/helpers/tryManifest.js +1 -1
  52. package/dist/plugin/helpers/tryManifest.js.map +1 -1
  53. package/dist/plugin/loader/createBuildLoader.d.ts +6 -2
  54. package/dist/plugin/loader/createBuildLoader.d.ts.map +1 -1
  55. package/dist/plugin/loader/createBuildLoader.js +35 -10
  56. package/dist/plugin/loader/createBuildLoader.js.map +1 -1
  57. package/dist/plugin/loader/createPageLoader.d.ts.map +1 -1
  58. package/dist/plugin/loader/createPageLoader.js +0 -7
  59. package/dist/plugin/plugin.d.ts +0 -1
  60. package/dist/plugin/plugin.d.ts.map +1 -1
  61. package/dist/plugin/plugin.js +2 -1
  62. package/dist/plugin/preserver/plugin.d.ts.map +1 -1
  63. package/dist/plugin/preserver/plugin.js +3 -2
  64. package/dist/plugin/preserver/plugin.js.map +1 -1
  65. package/dist/plugin/react-client/index.d.ts +2 -1
  66. package/dist/plugin/react-client/index.d.ts.map +1 -1
  67. package/dist/plugin/react-client/index.js +19 -1
  68. package/dist/plugin/react-client/index.js.map +1 -0
  69. package/dist/plugin/react-client/plugin.d.ts +2 -2
  70. package/dist/plugin/react-client/plugin.d.ts.map +1 -1
  71. package/dist/plugin/react-client/plugin.js +106 -10
  72. package/dist/plugin/react-client/plugin.js.map +1 -1
  73. package/dist/plugin/react-server/createHandler.d.ts +2 -2
  74. package/dist/plugin/react-server/createHandler.d.ts.map +1 -1
  75. package/dist/plugin/react-server/createHandler.js +5 -5
  76. package/dist/plugin/react-server/createHandler.js.map +1 -1
  77. package/dist/plugin/react-server/createRscStream.d.ts.map +1 -1
  78. package/dist/plugin/react-server/createRscStream.js +15 -1
  79. package/dist/plugin/react-server/createRscStream.js.map +1 -1
  80. package/dist/plugin/react-server/createSsrHandler.d.ts +2 -2
  81. package/dist/plugin/react-server/createSsrHandler.d.ts.map +1 -1
  82. package/dist/plugin/react-server/createSsrHandler.js +5 -12
  83. package/dist/plugin/react-server/index.js +18 -9
  84. package/dist/plugin/react-server/index.js.map +1 -0
  85. package/dist/plugin/react-server/plugin.d.ts.map +1 -1
  86. package/dist/plugin/react-server/plugin.js +133 -127
  87. package/dist/plugin/react-server/plugin.js.map +1 -1
  88. package/dist/plugin/transformer/plugin.d.ts +2 -1
  89. package/dist/plugin/transformer/plugin.d.ts.map +1 -1
  90. package/dist/plugin/transformer/plugin.js +52 -72
  91. package/dist/plugin/transformer/plugin.js.map +1 -1
  92. package/dist/plugin/transformer/transformer-client-components.d.ts +12 -3
  93. package/dist/plugin/transformer/transformer-client-components.d.ts.map +1 -1
  94. package/dist/plugin/transformer/transformer-client-components.js +71 -10
  95. package/dist/plugin/transformer/transformer-client-components.js.map +1 -1
  96. package/dist/plugin/transformer/transformer-server-actions.d.ts +3 -3
  97. package/dist/plugin/transformer/transformer-server-actions.d.ts.map +1 -1
  98. package/dist/plugin/transformer/transformer-server-actions.js +80 -66
  99. package/dist/plugin/transformer/types.d.ts +4 -0
  100. package/dist/plugin/transformer/types.d.ts.map +1 -1
  101. package/dist/plugin/types.d.ts +51 -20
  102. package/dist/plugin/types.d.ts.map +1 -1
  103. package/dist/plugin/worker/html/messageHandler.d.ts.map +1 -1
  104. package/dist/plugin/worker/html/messageHandler.js +37 -23
  105. package/dist/plugin/worker/html/messageHandler.js.map +1 -1
  106. package/dist/plugin/worker/html/plugin.d.ts.map +1 -1
  107. package/dist/plugin/worker/html/plugin.js +10 -5
  108. package/dist/plugin/worker/html/renderPages.d.ts +7 -6
  109. package/dist/plugin/worker/html/renderPages.d.ts.map +1 -1
  110. package/dist/plugin/worker/html/renderPages.js +112 -57
  111. package/dist/plugin/worker/html/renderPages.js.map +1 -1
  112. package/dist/plugin/worker/loader.d.ts +1 -11
  113. package/dist/plugin/worker/loader.d.ts.map +1 -1
  114. package/dist/plugin/worker/loader.js +2 -2
  115. package/dist/plugin/worker/loader.js.map +1 -1
  116. package/dist/plugin/worker/plugin.d.ts +10 -1
  117. package/dist/plugin/worker/plugin.d.ts.map +1 -1
  118. package/dist/plugin/worker/plugin.js +10 -1
  119. package/dist/plugin/worker/types.d.ts +17 -4
  120. package/dist/plugin/worker/types.d.ts.map +1 -1
  121. package/dist/server.d.ts +1 -3
  122. package/dist/server.d.ts.map +1 -1
  123. package/dist/server.js +1 -3
  124. package/dist/server.js.map +1 -1
  125. package/dist/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +2 -4
  127. package/plugin/assertServerCondition.ts +2 -3
  128. package/plugin/checkFilesExist.ts +10 -10
  129. package/plugin/components.tsx +1 -1
  130. package/plugin/config/createModuleIdGenerator.ts +52 -0
  131. package/plugin/config/defaults.ts +24 -15
  132. package/plugin/config/resolveOptions.ts +253 -25
  133. package/plugin/config/resolvePages.ts +1 -1
  134. package/plugin/config/resolveUserConfig.ts +197 -62
  135. package/plugin/helpers/getBundleManifest.ts +75 -0
  136. package/plugin/helpers/getModuleManifest.ts +5 -0
  137. package/plugin/helpers/inputNormalizer.ts +175 -26
  138. package/plugin/helpers/inputNormalizerWorker.ts +13 -8
  139. package/plugin/helpers/tryManifest.ts +2 -0
  140. package/plugin/loader/createBuildLoader.ts +54 -10
  141. package/plugin/loader/createPageLoader.ts +1 -7
  142. package/plugin/plugin.ts +2 -1
  143. package/plugin/preserver/plugin.ts +2 -1
  144. package/plugin/react-client/index.ts +12 -1
  145. package/plugin/react-client/plugin.ts +127 -12
  146. package/plugin/react-server/createHandler.ts +7 -13
  147. package/plugin/react-server/createRscStream.ts +14 -2
  148. package/plugin/react-server/createSsrHandler.ts +7 -26
  149. package/plugin/react-server/plugin.ts +176 -144
  150. package/plugin/transformer/plugin.ts +69 -94
  151. package/plugin/transformer/transformer-client-components.ts +98 -24
  152. package/plugin/transformer/transformer-server-actions.ts +22 -7
  153. package/plugin/transformer/types.ts +4 -0
  154. package/plugin/types.ts +118 -64
  155. package/plugin/worker/html/messageHandler.ts +46 -31
  156. package/plugin/worker/html/plugin.ts +15 -11
  157. package/plugin/worker/html/renderPages.ts +175 -88
  158. package/plugin/worker/loader.ts +4 -13
  159. package/plugin/worker/plugin.ts +10 -1
  160. package/plugin/worker/types.ts +24 -3
  161. package/dist/node_modules/magic-string/dist/magic-string.es.js +0 -1283
  162. package/dist/node_modules/magic-string/dist/magic-string.es.js.map +0 -1
  163. package/dist/plugin/build/createClientBuildConfig.d.ts +0 -3
  164. package/dist/plugin/build/createClientBuildConfig.d.ts.map +0 -1
  165. package/dist/plugin/build/createClientBuildConfig.js +0 -14
  166. package/dist/plugin/build/createServerBuildConfig.d.ts +0 -12
  167. package/dist/plugin/build/createServerBuildConfig.d.ts.map +0 -1
  168. package/dist/plugin/build/createServerBuildConfig.js +0 -40
  169. package/dist/plugin/build/createSharedBuildConfig.d.ts +0 -5
  170. package/dist/plugin/build/createSharedBuildConfig.d.ts.map +0 -1
  171. package/dist/plugin/build/createSharedBuildConfig.js +0 -28
  172. package/dist/plugin/build/mergeInputs.d.ts +0 -9
  173. package/dist/plugin/build/mergeInputs.d.ts.map +0 -1
  174. package/dist/plugin/build/mergeInputs.js +0 -56
  175. package/dist/plugin/config/moduleIdDefault.d.ts +0 -8
  176. package/dist/plugin/config/moduleIdDefault.d.ts.map +0 -1
  177. package/dist/plugin/config/moduleIdDefault.js +0 -23
  178. package/dist/plugin/config/moduleIdDefault.js.map +0 -1
  179. package/dist/plugin/helpers/getModuleManifest.js.map +0 -1
  180. package/dist/plugin/react-server/createDevMiddleware.d.ts +0 -8
  181. package/dist/plugin/react-server/createDevMiddleware.d.ts.map +0 -1
  182. package/dist/plugin/react-server/createDevMiddleware.js +0 -68
  183. package/dist/plugin/react-server/createDevServer.d.ts +0 -4
  184. package/dist/plugin/react-server/createDevServer.d.ts.map +0 -1
  185. package/dist/plugin/react-server/createDevServer.js +0 -4
  186. package/dist/plugin/react-server/createReactNodeStreamer.d.ts +0 -10
  187. package/dist/plugin/react-server/createReactNodeStreamer.d.ts.map +0 -1
  188. package/dist/plugin/react-server/createReactNodeStreamer.js +0 -7
  189. package/dist/plugin/transformer/transformer-server-actions.js.map +0 -1
  190. package/plugin/build/createClientBuildConfig.ts +0 -21
  191. package/plugin/build/createServerBuildConfig.ts +0 -66
  192. package/plugin/build/createSharedBuildConfig.ts +0 -35
  193. package/plugin/build/mergeInputs.ts +0 -58
  194. package/plugin/config/moduleIdDefault.ts +0 -23
  195. package/plugin/react-server/createDevMiddleware.ts +0 -91
  196. package/plugin/react-server/createDevServer.ts +0 -9
  197. package/plugin/react-server/createReactNodeStreamer.ts +0 -26
@@ -18,7 +18,6 @@ export function createRscStream(
18
18
  pipableStreamOptions,
19
19
  htmlProps,
20
20
  } = streamOptions;
21
-
22
21
  const css = Array.isArray(cssFiles)
23
22
  ? cssFiles.map((css, index) =>
24
23
  React.createElement(CssCollector, {
@@ -28,12 +27,18 @@ export function createRscStream(
28
27
  })
29
28
  )
30
29
  : [];
30
+ const htmlIsFragment = Html == React.Fragment;
31
+ console.log("[vite:plugin-react-server] Creating RSC stream with options:", {
32
+ moduleBasePath,
33
+ importMap: pipableStreamOptions?.importMap,
34
+ moduleRootPath: moduleBasePath // Make sure this matches client component paths
35
+ });
31
36
  return renderToPipeableStream(
32
37
  React.createElement(
33
38
  Html,
34
39
  {
35
40
  key: "html",
36
- ...htmlProps
41
+ ...(htmlIsFragment ? {} : htmlProps)
37
42
  },
38
43
  React.createElement(Page, { key: "page", ...props }),
39
44
  ...css
@@ -43,6 +48,13 @@ export function createRscStream(
43
48
  onError: logger?.error ?? console.error,
44
49
  onPostpone: logger?.info ?? console.info,
45
50
  environmentName: "Server",
51
+ importMap: {
52
+ imports: {
53
+ ...pipableStreamOptions?.importMap?.imports,
54
+ // Make sure paths are absolute and match module resolution
55
+ '/': moduleBasePath
56
+ }
57
+ },
46
58
  ...pipableStreamOptions
47
59
  }
48
60
  );
@@ -1,28 +1,16 @@
1
1
  import { join, resolve } from "node:path";
2
2
  import { Writable } from "node:stream";
3
3
  import { Worker } from "node:worker_threads";
4
- import { type ViteDevServer } from "vite";
4
+ import { type Manifest, type ViteDevServer } from "vite";
5
5
  import { DEFAULT_CONFIG } from "../config/defaults.js";
6
- import type { RequestHandler, StreamPluginOptions } from "../types.js";
6
+ import type { RequestHandler, ResolvedUserOptions } from "../types.js";
7
7
  import type { WorkerRscChunkMessage } from "../worker/types.js";
8
8
  import { createHandler } from "./createHandler.js";
9
9
 
10
10
 
11
11
  export function createSsrHandler(
12
- options: Required<
13
- Pick<
14
- StreamPluginOptions,
15
- "Page" | "props" | "build" | "Html" | "pageExportName" | "propsExportName"
16
- >
17
- > &
18
- Required<
19
- Pick<
20
- StreamPluginOptions,
21
- "moduleBase" | "moduleBasePath" | "moduleBaseURL" | "projectRoot" | "htmlWorkerPath"
22
- >
23
- >,
12
+ options: ResolvedUserOptions,
24
13
  server: ViteDevServer,
25
- _clientComponents: Map<string, string>
26
14
  ): RequestHandler {
27
15
  const worker = new Worker(
28
16
  options?.htmlWorkerPath
@@ -52,14 +40,7 @@ export function createSsrHandler(
52
40
  const result = await createHandler(
53
41
  req.url ?? "",
54
42
  {
55
- Page: options.Page,
56
- props: options.props,
57
- build: options.build,
58
- Html: options.Html,
59
- pageExportName: options.pageExportName,
60
- propsExportName: options.propsExportName,
61
- moduleBase: options.moduleBase,
62
- moduleBasePath: options.moduleBasePath,
43
+ ...options,
63
44
  projectRoot: server.config.root,
64
45
  },
65
46
  {
@@ -116,9 +97,9 @@ export function createSsrHandler(
116
97
  // Don't need file paths in dev mode
117
98
  outDir: "",
118
99
  htmlOutputPath: "",
119
- pipableStreamOptions: {
120
- bootstrapModules: ["/dist/client.js"],
121
- },
100
+ pipableStreamOptions: options.pipableStreamOptions ?? {},
101
+ clientManifest: {},
102
+ serverManifest: {},
122
103
  } satisfies WorkerRscChunkMessage);
123
104
 
124
105
  worker.once("message", (msg) => {
@@ -1,6 +1,4 @@
1
- import { readdirSync } from "fs";
2
- import type { ServerResponse } from "node:http";
3
- import { join, resolve } from "node:path";
1
+ import { join, resolve, dirname } from "node:path";
4
2
  import { performance } from "node:perf_hooks";
5
3
  import { Worker } from "node:worker_threads";
6
4
  import React from "react";
@@ -9,6 +7,8 @@ import {
9
7
  type ResolvedConfig,
10
8
  type UserConfig,
11
9
  type ViteDevServer,
10
+ type Manifest,
11
+ build,
12
12
  } from "vite";
13
13
  import { checkFilesExist } from "../checkFilesExist.js";
14
14
  import { DEFAULT_CONFIG } from "../config/defaults.js";
@@ -16,7 +16,6 @@ import { getPluginRoot } from "../config/getPaths.js";
16
16
  import { resolveOptions } from "../config/resolveOptions.js";
17
17
  import { resolvePages } from "../config/resolvePages.js";
18
18
  import { resolveUserConfig } from "../config/resolveUserConfig.js";
19
- import { getModuleManifest } from "../helpers/getModuleManifest.js";
20
19
  import { tryManifest } from "../helpers/tryManifest.js";
21
20
  import { createBuildLoader } from "../loader/createBuildLoader.js";
22
21
  import type {
@@ -30,7 +29,16 @@ import { type StreamPluginOptions } from "../types.js";
30
29
  import { createWorker } from "../worker/createWorker.js";
31
30
  import { renderPages } from "../worker/html/renderPages.js";
32
31
  import { createHandler } from "./createHandler.js";
32
+ import { mkdir, writeFile } from "node:fs/promises";
33
+ import { getBundleManifest } from "../helpers/getBundleManifest.js";
34
+ import type { ServerResponse } from "node:http";
33
35
 
36
+ let resolvedConfig: ResolvedConfig | null = null;
37
+ let serverManifestPath: string | null = null;
38
+ let clientManifestPath: string | null = null;
39
+ let outpuptBundle: any;
40
+ let outputOptions: any;
41
+ let loader: ((id: string) => Promise<Record<string, any>>) | null = null;
34
42
  export function reactServerPlugin(
35
43
  options: StreamPluginOptions
36
44
  ): import("vite").Plugin<{
@@ -44,7 +52,6 @@ export function reactServerPlugin(
44
52
  let files: CheckFilesExistReturn;
45
53
  // let env: Awaited<ReturnType<typeof getEnv>>;
46
54
  let worker: Worker;
47
- let finalConfig: ResolvedConfig;
48
55
  let cssModules = new Set<string>();
49
56
  let clientComponents = new Map<string, string>();
50
57
  // let define: Record<string, string>;
@@ -63,6 +70,7 @@ export function reactServerPlugin(
63
70
  dynamicImports: string[];
64
71
  }
65
72
  > = {};
73
+ let serverManifest: Manifest = {};
66
74
 
67
75
  interface BuildStats {
68
76
  htmlFiles: number;
@@ -82,7 +90,19 @@ export function reactServerPlugin(
82
90
  throw resolvedOptions.error;
83
91
  }
84
92
  userOptions = resolvedOptions.userOptions;
85
- root = userOptions.projectRoot;
93
+ if (
94
+ userOptions.projectRoot != root &&
95
+ typeof userOptions.projectRoot === "string" &&
96
+ userOptions.projectRoot !== process.cwd() &&
97
+ userOptions.projectRoot !== ""
98
+ ) {
99
+ root = userOptions.projectRoot;
100
+ console.log(
101
+ "[vite:plugin-react-server] Root dir changed in plugin",
102
+ userOptions.projectRoot,
103
+ root
104
+ );
105
+ }
86
106
  return {
87
107
  name: "vite:react-stream-server",
88
108
  enforce: "post",
@@ -92,20 +112,25 @@ export function reactServerPlugin(
92
112
  buildCssFiles.add(path);
93
113
  },
94
114
  },
95
- configResolved(resolvedConfig) {
96
- finalConfig = resolvedConfig;
115
+ configResolved(_resolvedConfig) {
116
+ resolvedConfig = _resolvedConfig;
117
+
118
+ serverManifestPath = join(
119
+ userOptions.build.outDir,
120
+ userOptions.build.server,
121
+ ".vite/manifest.json"
122
+ );
123
+ clientManifestPath = join(
124
+ resolvedConfig.build.outDir,
125
+ userOptions.build.client,
126
+ ".vite/manifest.json"
127
+ );
97
128
  timing.configResolved = performance.now();
98
- if (finalConfig.command === "build") {
99
- finalConfig = {
100
- ...finalConfig,
101
- mode: "production",
102
- };
103
- }
104
129
 
105
130
  // Verify transformer runs first, preserver runs last
106
- const plugins = finalConfig.plugins;
131
+ const plugins = resolvedConfig.plugins;
107
132
  const transformerIndex = plugins.findIndex(
108
- (p) => p.name === "vite:react-stream-transformer"
133
+ (p) => p.name === "vite:react-transform"
109
134
  );
110
135
  const preserverIndex = plugins.findIndex(
111
136
  (p) => p.name === "vite-plugin-react-server:preserve-directives"
@@ -119,11 +144,22 @@ export function reactServerPlugin(
119
144
  "Transformer plugin isn't installed or isn't running before preserver"
120
145
  );
121
146
  }
147
+ },
148
+ async configurePreviewServer(server) {
149
+
122
150
  },
123
151
  async configureServer(server: ViteDevServer) {
124
- if (server.config.root !== root) {
152
+ if (typeof loader !== "function") {
153
+ loader = server.ssrLoadModule;
154
+ }
155
+ if (
156
+ server.config.root !== root &&
157
+ typeof server.config.root === "string" &&
158
+ server.config.root !== process.cwd() &&
159
+ server.config.root !== ""
160
+ ) {
125
161
  console.log(
126
- "[vite-plugin-react-server] Root dir changed",
162
+ "[vite:plugin-react-server] Root dir changed in configureServer hook",
127
163
  server.config.root,
128
164
  root
129
165
  );
@@ -150,35 +186,32 @@ export function reactServerPlugin(
150
186
  activeStreams.clear();
151
187
  });
152
188
 
153
- server.ws.on("connection", (_socket, _req) => {
154
- console.log("[vite-plugin-react-server] hooking up ws connection");
155
- });
189
+ // server.ws.on("connection", (_socket, _req) => {
190
+ // console.log("[vite-plugin-react-server] hooking up ws connection");
191
+ // });
156
192
 
157
- server.ws.on("listening", () => {
158
- console.log("[vite-plugin-react-server] hooking up ws listening");
159
- });
193
+ // server.ws.on("listening", () => {
194
+ // console.log("[vite-plugin-react-server] hooking up ws listening");
195
+ // });
160
196
 
161
197
  server.middlewares.use(async (req, res, next) => {
162
198
  if (req.headers.accept !== "text/x-component") return next();
163
- console.log("[vite-plugin-react-server] middleware called");
199
+ if (typeof loader !== "function") {
200
+ loader = server.ssrLoadModule;
201
+ }
164
202
  try {
165
203
  const handler = await createHandler(
166
204
  req.url ?? "",
167
205
  {
168
- Page: userOptions.Page,
169
- props: userOptions.props,
170
- build: userOptions.build,
206
+ ...userOptions,
207
+ // we'll leave the Html generation for later
171
208
  Html: React.Fragment,
172
- pageExportName: userOptions.pageExportName,
173
- propsExportName: userOptions.propsExportName,
174
- moduleBase: userOptions.moduleBase,
175
- moduleBasePath: userOptions.moduleBasePath,
176
209
  projectRoot: root,
177
210
  },
178
211
  {
179
212
  cssFiles: Array.from(cssModules),
180
213
  logger: createLogger(),
181
- loader: server.ssrLoadModule,
214
+ loader,
182
215
  moduleGraph: server.moduleGraph,
183
216
  }
184
217
  );
@@ -188,17 +221,23 @@ export function reactServerPlugin(
188
221
  activeStreams.add(res);
189
222
  } finally {
190
223
  res.on("close", () => {
191
- console.log(
192
- "[vite-plugin-react-server] ➖ Stream closed for:",
193
- req.url
194
- );
195
224
  activeStreams.delete(res);
196
225
  });
197
226
  }
198
227
  });
199
228
  },
200
229
  async config(config, configEnv): Promise<UserConfig> {
201
- if (typeof config.root === "string" && config.root !== root && config.root !== process.cwd() && config.root !== "") {
230
+ if (
231
+ typeof config.root === "string" &&
232
+ config.root !== root &&
233
+ config.root !== process.cwd() &&
234
+ config.root !== ""
235
+ ) {
236
+ console.log(
237
+ "[vite:plugin-react-server] Root dir changed in config hook",
238
+ config.root,
239
+ root
240
+ );
202
241
  root = config.root;
203
242
  }
204
243
  const resolvedPages = await resolvePages(userOptions.build.pages);
@@ -209,7 +248,7 @@ export function reactServerPlugin(
209
248
  files = await checkFilesExist(resolvedPages.pages, userOptions, root);
210
249
 
211
250
  const resolvedConfig = resolveUserConfig({
212
- condition: "react-server",
251
+ isClient: false,
213
252
  config,
214
253
  configEnv,
215
254
  userOptions,
@@ -232,82 +271,96 @@ export function reactServerPlugin(
232
271
  }
233
272
  },
234
273
  async closeBundle() {
235
- if (!userConfig || finalConfig.command !== "build") return;
274
+ if (!userConfig || resolvedConfig?.command !== "build") return;
236
275
  try {
237
276
  timing.renderStart = performance.now();
238
277
 
239
- const resolvedServerManifest = tryManifest({
240
- root,
241
- outDir: userOptions.build.server,
278
+ // Get the client manifest
279
+ const clientManifestResult = tryManifest({
280
+ root: root,
281
+ outDir: join(userOptions.build.outDir, userOptions.build.client),
242
282
  ssrManifest: false,
243
283
  });
244
284
 
245
- const serverManifest =
246
- resolvedServerManifest.type === "error"
247
- ? getModuleManifest.bind(this)()
248
- : resolvedServerManifest.manifest;
249
- // Get worker path from manifest
250
- // Look for the html-worker entry directly
251
- let htmlWorkerPath = serverManifest["html-worker"]?.file;
252
-
253
- if (options.htmlWorkerPath) {
254
- htmlWorkerPath = options.htmlWorkerPath;
255
- } else {
256
- htmlWorkerPath = join(
257
- getPluginRoot(),
258
- DEFAULT_CONFIG.HTML_WORKER_PATH
259
- );
285
+ if (clientManifestResult.type === "error") {
286
+ throw clientManifestResult.error;
260
287
  }
261
288
 
289
+ const clientManifest = clientManifestResult.manifest;
290
+
291
+ // Initialize worker
292
+ const htmlWorkerPath = join(
293
+ getPluginRoot(),
294
+ DEFAULT_CONFIG.HTML_WORKER_PATH
295
+ );
296
+
262
297
  worker = await createWorker({
263
298
  projectRoot: root,
264
299
  workerPath: htmlWorkerPath,
265
300
  condition: "react-server",
266
301
  reverseCondition: true,
267
- mode: finalConfig.mode as "production" | "development",
302
+ mode: (resolvedConfig?.mode ?? "production") as
303
+ | "production"
304
+ | "development",
268
305
  nodeOptions: "--conditions=react-client",
269
306
  });
270
307
 
271
- // Get routes directly from pages
308
+ // Use both manifests directly
309
+ if (typeof loader !== "function") {
310
+ if (!Object.keys(serverManifest).length) {
311
+ serverManifest = getBundleManifest(this, outpuptBundle, undefined);
312
+ if (!Object.keys(serverManifest).length) {
313
+ const resolvedServerManifest = tryManifest({
314
+ root: root,
315
+ outDir: join(userOptions.build.outDir, userOptions.build.server),
316
+ ssrManifest: false,
317
+ });
318
+ if (resolvedServerManifest.type === "error") {
319
+ // dont build the static files without a server manifest
320
+ return;
321
+ }
322
+ serverManifest = resolvedServerManifest.manifest;
323
+ }
324
+ }
325
+ loader = createBuildLoader({
326
+ root: root,
327
+ userConfig,
328
+ userOptions,
329
+ pluginContext: this,
330
+ serverManifest,
331
+ clientManifest,
332
+ });
333
+ }
272
334
  const resolvedPages = await resolvePages(userOptions.build.pages);
273
335
  if (resolvedPages.type === "error") {
274
336
  throw resolvedPages.error;
275
337
  }
276
- const routes = resolvedPages.pages;
277
-
278
- const entries = Object.values(serverManifest).filter(
279
- (entry) => entry.isEntry
338
+ const { failedRoutes, completedRoutes } = await renderPages(
339
+ this,
340
+ resolvedPages.pages,
341
+ {
342
+ pipableStreamOptions: {},
343
+ moduleBasePath: "",
344
+ moduleBaseURL: "",
345
+ clientCss:
346
+ Object.values(clientManifest)
347
+ .flatMap((entry) => entry.css)
348
+ .filter((css) => typeof css === "string")
349
+ .map((css) => "/" + css) ?? [],
350
+ userConfig,
351
+ pluginOptions: userOptions,
352
+ worker: worker,
353
+ clientManifest: clientManifest,
354
+ serverManifest: serverManifest,
355
+ loader,
356
+ onCssFile: (path: string) => {
357
+ console.log("[vite-plugin-react-server] onCssFile", path);
358
+ if (buildCssFiles && path.endsWith(".css")) {
359
+ buildCssFiles.add(path);
360
+ }
361
+ },
362
+ }
280
363
  );
281
- const css = entries.flatMap((entry) => entry.css);
282
- const loader = createBuildLoader({
283
- root,
284
- userConfig,
285
- pluginContext: this,
286
- });
287
-
288
- const { failedRoutes, completedRoutes } = await renderPages(routes, {
289
- pipableStreamOptions: {
290
- bootstrapModules: entries
291
- .filter((entry) =>
292
- userOptions.autoDiscover.clientComponents.test(entry.file)
293
- )
294
- .filter((t)=> typeof t === "object" && t != null && "file" in t)
295
- .map((entry) => "/" + entry.file),
296
- },
297
- moduleBasePath: userOptions.moduleBasePath,
298
- moduleBaseURL: userOptions.moduleBaseURL,
299
- clientCss: css?.filter((css) => typeof css === "string").map((css) => "/" + css) ?? [],
300
- userConfig,
301
- pluginOptions: userOptions,
302
- worker: worker,
303
- manifest: serverManifest,
304
- loader,
305
- onCssFile: (path: string) => {
306
- if (buildCssFiles && path.endsWith(".css")) {
307
- buildCssFiles.add(path);
308
- }
309
- },
310
- });
311
364
 
312
365
  if (failedRoutes.size) {
313
366
  console.error(
@@ -320,12 +373,16 @@ export function reactServerPlugin(
320
373
  timing.renderEnd = performance.now();
321
374
  timing.total = (timing.renderEnd - timing.start) / 1000;
322
375
 
323
- // Collect stats
376
+ // Update stats to include CSS and client components
324
377
  const stats: BuildStats = {
325
- htmlFiles: routes.length,
326
- clientComponents: clientComponents.size,
327
- cssFiles: cssModules.size,
328
- totalRoutes: routes.length,
378
+ htmlFiles: userOptions.build.pages.length,
379
+ clientComponents: Object.keys(clientManifest).filter(
380
+ userOptions.autoDiscover.clientComponents
381
+ ).length,
382
+ cssFiles: Object.keys(clientManifest)
383
+ .flatMap(userOptions.autoDiscover.cssPattern)
384
+ .filter(Boolean).length,
385
+ totalRoutes: userOptions.build.pages.length,
329
386
  timing: {
330
387
  config: ((timing.configResolved ?? 0) - timing.start) / 1000,
331
388
  build:
@@ -372,66 +429,41 @@ export function reactServerPlugin(
372
429
  console.error("[vite-plugin-react-server] Build failed:", error);
373
430
  // Make sure to terminate worker even on error
374
431
  if (worker) await worker.terminate();
432
+ worker = null as any;
375
433
  throw error;
376
434
  }
377
435
  },
378
436
  async buildEnd(error) {
379
437
  if (error) {
380
438
  console.error("[vite-plugin-react-server] Build error:", error);
439
+ return;
381
440
  }
382
- if (worker) await worker.terminate();
383
441
  },
384
442
  handleHotUpdate({ file }) {
385
443
  if (file.endsWith(".css")) {
386
444
  cssModules.add(file);
387
445
  }
388
446
  },
389
- async renderChunk(_code: string, chunk: any, _options: any) {
390
- const moduleIds = this.getModuleIds();
391
- const fallbackManifestEntries = Object.fromEntries(
392
- Array.from(moduleIds)
393
- .map((module) => {
394
- const moduleInfo = this.getModuleInfo(module);
395
- if (!moduleInfo) return [module, null];
396
- const {
397
- code,
398
- id,
399
- isEntry,
400
- importedIds,
401
- dynamicallyImportedIds,
402
- ...rest
403
- } = moduleInfo;
404
- return [
405
- chunk.name ?? id,
406
- {
407
- file: chunk.fileName,
408
- src: module,
409
- name: chunk.name ?? id,
410
- isEntry: chunk.isEntry ?? isEntry,
411
- imports: chunk.imports ?? importedIds,
412
- dynamicImports: chunk.dynamicImports ?? dynamicallyImportedIds,
413
- directive: rest.meta["directive"],
414
- css: chunk.viteMetadata?.importedCss ?? [],
415
- assets: chunk.viteMetadata?.importedAssets ?? [],
416
- },
417
- ];
418
- })
419
- .filter(Boolean)
420
- );
421
-
422
- moduleGraph = {
423
- ...moduleGraph,
424
- ...fallbackManifestEntries,
425
- };
426
-
447
+ async generateBundle(options, bundle) {
448
+ if (!resolvedConfig) {
449
+ throw new Error("Resolved config not found");
450
+ }
451
+ outpuptBundle = bundle;
452
+ outputOptions = options;
453
+ // Create manifest entries for each chunk
454
+ serverManifest = getBundleManifest(this, bundle, undefined);
455
+ console.log("[vite:plugin-react-server] Server manifest", serverManifest);
456
+ if (serverManifestPath) {
457
+ await mkdir(dirname(serverManifestPath), { recursive: true });
458
+ await writeFile(
459
+ serverManifestPath,
460
+ JSON.stringify(serverManifest, null, 2)
461
+ );
462
+ }
463
+ },
464
+ async renderChunk(code: string, chunk, options) {
427
465
  if (chunk.fileName.includes("html-worker")) {
428
466
  const workerPath = resolve(root, chunk.fileName);
429
-
430
- // Don't initialize worker during build phase
431
- if (finalConfig.command === "build") {
432
- return null;
433
- }
434
-
435
467
  worker = await createWorker({
436
468
  projectRoot: userOptions.projectRoot,
437
469
  workerPath,