vite-plugin-react-server 0.3.17 → 0.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +119 -118
  2. package/bin/patch.mjs +8 -2
  3. package/dist/package.json +3 -3
  4. package/dist/plugin/checkFilesExist.d.ts.map +1 -1
  5. package/dist/plugin/checkFilesExist.js +6 -2
  6. package/dist/plugin/checkFilesExist.js.map +1 -1
  7. package/dist/plugin/collect-manifest-client-files.d.ts +23 -0
  8. package/dist/plugin/collect-manifest-client-files.d.ts.map +1 -0
  9. package/dist/plugin/collect-manifest-client-files.js +117 -0
  10. package/dist/plugin/collect-manifest-client-files.js.map +1 -0
  11. package/dist/plugin/components.d.ts +9 -9
  12. package/dist/plugin/components.d.ts.map +1 -1
  13. package/dist/plugin/components.js +50 -9
  14. package/dist/plugin/components.js.map +1 -0
  15. package/dist/plugin/config/defaults.d.ts +7 -6
  16. package/dist/plugin/config/defaults.d.ts.map +1 -1
  17. package/dist/plugin/config/defaults.js +8 -5
  18. package/dist/plugin/config/defaults.js.map +1 -1
  19. package/dist/plugin/config/getPaths.d.ts +0 -1
  20. package/dist/plugin/config/getPaths.d.ts.map +1 -1
  21. package/dist/plugin/config/getPaths.js +2 -7
  22. package/dist/plugin/config/getPaths.js.map +1 -1
  23. package/dist/plugin/config/mimeTypes.d.ts +2 -0
  24. package/dist/plugin/config/mimeTypes.d.ts.map +1 -0
  25. package/dist/plugin/config/mimeTypes.js +24 -0
  26. package/dist/plugin/config/mimeTypes.js.map +1 -0
  27. package/dist/plugin/config/resolveOptions.d.ts +1 -1
  28. package/dist/plugin/config/resolveOptions.d.ts.map +1 -1
  29. package/dist/plugin/config/resolveOptions.js +41 -28
  30. package/dist/plugin/config/resolveOptions.js.map +1 -1
  31. package/dist/plugin/config/resolvePages.d.ts +1 -0
  32. package/dist/plugin/config/resolvePages.d.ts.map +1 -1
  33. package/dist/plugin/config/resolvePages.js +9 -5
  34. package/dist/plugin/config/resolvePages.js.map +1 -1
  35. package/dist/plugin/config/resolveUserConfig.d.ts +2 -1
  36. package/dist/plugin/config/resolveUserConfig.d.ts.map +1 -1
  37. package/dist/plugin/config/resolveUserConfig.js +12 -7
  38. package/dist/plugin/config/resolveUserConfig.js.map +1 -1
  39. package/dist/plugin/copy-dir.js +23 -18
  40. package/dist/plugin/copy-dir.js.map +1 -0
  41. package/dist/plugin/helpers/createHandler.d.ts +22 -0
  42. package/dist/plugin/helpers/createHandler.d.ts.map +1 -0
  43. package/dist/plugin/{react-server → helpers}/createHandler.js +36 -48
  44. package/dist/plugin/helpers/createHandler.js.map +1 -0
  45. package/dist/plugin/{react-server → helpers}/createRscStream.d.ts +2 -1
  46. package/dist/plugin/helpers/createRscStream.d.ts.map +1 -0
  47. package/dist/plugin/helpers/createRscStream.js +71 -0
  48. package/dist/plugin/helpers/createRscStream.js.map +1 -0
  49. package/dist/plugin/helpers/getBundleManifest.d.ts.map +1 -1
  50. package/dist/plugin/helpers/getBundleManifest.js +12 -4
  51. package/dist/plugin/helpers/getBundleManifest.js.map +1 -1
  52. package/dist/plugin/loader/createBuildLoader.d.ts +1 -1
  53. package/dist/plugin/loader/createBuildLoader.d.ts.map +1 -1
  54. package/dist/plugin/loader/createBuildLoader.js +8 -5
  55. package/dist/plugin/loader/createBuildLoader.js.map +1 -1
  56. package/dist/plugin/loader/css-loader.d.ts.map +1 -1
  57. package/dist/plugin/loader/css-loader.js.map +1 -1
  58. package/dist/plugin/loader/react-loader.js +2 -2
  59. package/dist/plugin/loader/react-loader.js.map +1 -1
  60. package/dist/plugin/preserver/plugin.d.ts.map +1 -1
  61. package/dist/plugin/preserver/plugin.js +49 -14
  62. package/dist/plugin/preserver/plugin.js.map +1 -1
  63. package/dist/plugin/react-client/plugin.d.ts.map +1 -1
  64. package/dist/plugin/react-client/plugin.js +18 -60
  65. package/dist/plugin/react-client/plugin.js.map +1 -1
  66. package/dist/plugin/react-server/index.d.ts.map +1 -1
  67. package/dist/plugin/react-server/index.js +2 -0
  68. package/dist/plugin/react-server/index.js.map +1 -1
  69. package/dist/plugin/react-server/plugin.d.ts +2 -1
  70. package/dist/plugin/react-server/plugin.d.ts.map +1 -1
  71. package/dist/plugin/react-server/plugin.js +53 -219
  72. package/dist/plugin/react-server/plugin.js.map +1 -1
  73. package/dist/plugin/react-static/index.d.ts +2 -0
  74. package/dist/plugin/react-static/index.d.ts.map +1 -0
  75. package/dist/plugin/react-static/index.js +1 -0
  76. package/dist/plugin/react-static/plugin.d.ts +7 -0
  77. package/dist/plugin/react-static/plugin.d.ts.map +1 -0
  78. package/dist/plugin/react-static/plugin.js +199 -0
  79. package/dist/plugin/react-static/plugin.js.map +1 -0
  80. package/dist/plugin/resolvePage.d.ts.map +1 -1
  81. package/dist/plugin/resolvePage.js +9 -0
  82. package/dist/plugin/resolvePage.js.map +1 -1
  83. package/dist/plugin/root.d.ts +2 -0
  84. package/dist/plugin/root.d.ts.map +1 -0
  85. package/dist/plugin/root.js +12 -0
  86. package/dist/plugin/root.js.map +1 -0
  87. package/dist/plugin/transformer/plugin.d.ts.map +1 -1
  88. package/dist/plugin/transformer/plugin.js +32 -23
  89. package/dist/plugin/transformer/plugin.js.map +1 -1
  90. package/dist/plugin/transformer/types.d.ts +1 -18
  91. package/dist/plugin/transformer/types.d.ts.map +1 -1
  92. package/dist/plugin/types.d.ts +24 -6
  93. package/dist/plugin/types.d.ts.map +1 -1
  94. package/dist/plugin/worker/createWorker.js +0 -1
  95. package/dist/plugin/worker/createWorker.js.map +1 -1
  96. package/dist/plugin/worker/html/html-worker.development.d.ts +30 -0
  97. package/dist/plugin/worker/html/html-worker.development.d.ts.map +1 -1
  98. package/dist/plugin/worker/html/html-worker.development.js +30 -2
  99. package/dist/plugin/worker/html/html-worker.development.js.map +1 -1
  100. package/dist/plugin/worker/html/html-worker.production.js +3 -5
  101. package/dist/plugin/worker/html/html-worker.production.js.map +1 -1
  102. package/dist/plugin/worker/html/messageHandler.d.ts.map +1 -1
  103. package/dist/plugin/worker/html/messageHandler.js +8 -2
  104. package/dist/plugin/worker/html/messageHandler.js.map +1 -1
  105. package/dist/plugin/worker/html/plugin.d.ts.map +1 -1
  106. package/dist/plugin/worker/html/plugin.js +2 -3
  107. package/dist/plugin/worker/html/renderPages.d.ts +8 -4
  108. package/dist/plugin/worker/html/renderPages.d.ts.map +1 -1
  109. package/dist/plugin/worker/html/renderPages.js +118 -83
  110. package/dist/plugin/worker/html/renderPages.js.map +1 -1
  111. package/dist/plugin/worker/rsc/messageHandler.d.ts.map +1 -1
  112. package/dist/plugin/worker/rsc/messageHandler.js +91 -87
  113. package/dist/plugin/worker/rsc/messageHandler.js.map +1 -1
  114. package/dist/plugin/worker/rsc/plugin.d.ts.map +1 -1
  115. package/dist/plugin/worker/rsc/plugin.js +1 -2
  116. package/dist/plugin/worker/rsc/rsc-worker.development.js +13 -18
  117. package/dist/plugin/worker/rsc/rsc-worker.development.js.map +1 -1
  118. package/dist/plugin/worker/rsc/rsc-worker.production.js +4 -1
  119. package/dist/plugin/worker/rsc/rsc-worker.production.js.map +1 -1
  120. package/dist/plugin/worker/rsc/state.d.ts.map +1 -1
  121. package/dist/plugin/worker/rsc/state.js.map +1 -1
  122. package/dist/tsconfig.tsbuildinfo +1 -1
  123. package/package.json +3 -3
  124. package/plugin/checkFilesExist.ts +7 -3
  125. package/plugin/collect-manifest-client-files.ts +152 -0
  126. package/plugin/components.tsx +55 -10
  127. package/plugin/config/defaults.tsx +69 -0
  128. package/plugin/config/getPaths.ts +1 -7
  129. package/plugin/config/mimeTypes.ts +17 -0
  130. package/plugin/config/resolveOptions.ts +48 -40
  131. package/plugin/config/resolvePages.ts +8 -4
  132. package/plugin/config/resolveUserConfig.ts +14 -11
  133. package/plugin/{react-server → helpers}/createHandler.ts +46 -63
  134. package/plugin/helpers/createRscStream.ts +81 -0
  135. package/plugin/helpers/getBundleManifest.ts +14 -5
  136. package/plugin/loader/createBuildLoader.ts +9 -6
  137. package/plugin/loader/css-loader.ts +0 -2
  138. package/plugin/loader/react-loader.ts +2 -2
  139. package/plugin/preserver/plugin.ts +64 -17
  140. package/plugin/react-client/plugin.ts +20 -74
  141. package/plugin/react-server/index.ts +2 -0
  142. package/plugin/react-server/plugin.ts +66 -298
  143. package/plugin/react-static/index.ts +1 -0
  144. package/plugin/react-static/plugin.ts +247 -0
  145. package/plugin/resolvePage.ts +9 -0
  146. package/plugin/root.ts +4 -0
  147. package/plugin/transformer/plugin.ts +40 -31
  148. package/plugin/transformer/types.ts +0 -19
  149. package/plugin/types.ts +25 -6
  150. package/plugin/worker/createWorker.ts +1 -1
  151. package/plugin/worker/html/README.md +63 -0
  152. package/plugin/worker/html/html-worker.development.tsx +89 -2
  153. package/plugin/worker/html/html-worker.production.tsx +8 -10
  154. package/plugin/worker/html/messageHandler.ts +8 -2
  155. package/plugin/worker/html/plugin.ts +2 -3
  156. package/plugin/worker/html/renderPages.ts +150 -114
  157. package/plugin/worker/rsc/README.md +58 -0
  158. package/plugin/worker/rsc/messageHandler.tsx +98 -119
  159. package/plugin/worker/rsc/plugin.ts +1 -2
  160. package/plugin/worker/rsc/rsc-worker.development.ts +12 -22
  161. package/plugin/worker/rsc/rsc-worker.production.ts +5 -1
  162. package/plugin/worker/rsc/state.ts +0 -3
  163. package/scripts/react+0.0.0-experimental-eda36a1c-20250228.patch +114 -12
  164. package/scripts/react-dom+0.0.0-experimental-eda36a1c-20250228.patch +10571 -121
  165. package/tsconfig.json +2 -2
  166. package/dist/plugin/collect-css-manifest.d.ts +0 -4
  167. package/dist/plugin/collect-css-manifest.d.ts.map +0 -1
  168. package/dist/plugin/collect-css-manifest.js +0 -66
  169. package/dist/plugin/collect-css-manifest.js.map +0 -1
  170. package/dist/plugin/config/createModuleIdGenerator.d.ts +0 -11
  171. package/dist/plugin/config/createModuleIdGenerator.d.ts.map +0 -1
  172. package/dist/plugin/config/createModuleIdGenerator.js +0 -44
  173. package/dist/plugin/config/createModuleIdGenerator.js.map +0 -1
  174. package/dist/plugin/loader/createCssLoader.d.ts +0 -30
  175. package/dist/plugin/loader/createCssLoader.d.ts.map +0 -1
  176. package/dist/plugin/loader/createCssLoader.js +0 -35
  177. package/dist/plugin/loader/createPageLoader.d.ts +0 -24
  178. package/dist/plugin/loader/createPageLoader.d.ts.map +0 -1
  179. package/dist/plugin/loader/createPageLoader.js +0 -50
  180. package/dist/plugin/loader/rsc/messageHandler.d.ts +0 -2
  181. package/dist/plugin/loader/rsc/messageHandler.d.ts.map +0 -1
  182. package/dist/plugin/loader/rsc/messageHandler.js +0 -1
  183. package/dist/plugin/loader/rsc/rsc-worker.development.d.ts +0 -2
  184. package/dist/plugin/loader/rsc/rsc-worker.development.d.ts.map +0 -1
  185. package/dist/plugin/loader/rsc/rsc-worker.development.js +0 -1
  186. package/dist/plugin/react-server/createHandler.d.ts +0 -17
  187. package/dist/plugin/react-server/createHandler.d.ts.map +0 -1
  188. package/dist/plugin/react-server/createHandler.js.map +0 -1
  189. package/dist/plugin/react-server/createRscStream.d.ts.map +0 -1
  190. package/dist/plugin/react-server/createRscStream.js +0 -66
  191. package/dist/plugin/react-server/createRscStream.js.map +0 -1
  192. package/dist/plugin/react-server/createSsrHandler.d.ts +0 -4
  193. package/dist/plugin/react-server/createSsrHandler.d.ts.map +0 -1
  194. package/dist/plugin/react-server/createSsrHandler.js +0 -95
  195. package/dist/plugin/utils/logger.d.ts +0 -9
  196. package/dist/plugin/utils/logger.d.ts.map +0 -1
  197. package/dist/plugin/utils/logger.js +0 -68
  198. package/dist/plugin/utils/logger.js.map +0 -1
  199. package/plugin/collect-css-manifest.ts +0 -83
  200. package/plugin/config/createModuleIdGenerator.ts +0 -52
  201. package/plugin/config/defaults.ts +0 -51
  202. package/plugin/loader/createCssLoader.ts +0 -73
  203. package/plugin/loader/createPageLoader.ts +0 -103
  204. package/plugin/loader/rsc/messageHandler.tsx +0 -1
  205. package/plugin/loader/rsc/rsc-worker.development.ts +0 -1
  206. package/plugin/react-server/createRscStream.ts +0 -82
  207. package/plugin/react-server/createSsrHandler.ts +0 -125
  208. package/plugin/utils/logger.ts +0 -52
@@ -12,20 +12,18 @@ import { dirname, join } from "node:path";
12
12
  import { getBundleManifest } from "../helpers/getBundleManifest.js";
13
13
  import { checkFilesExist } from "../checkFilesExist.js";
14
14
  import { resolvePages } from "../config/resolvePages.js";
15
- import { tryManifest } from "../helpers/tryManifest.js";
16
15
  import { createInputNormalizer } from "../helpers/inputNormalizer.js";
17
16
  import { createWorker } from "../worker/createWorker.js";
18
17
  import type { Worker } from "node:worker_threads";
19
- import { getPluginRoot } from "../config/getPaths.js";
20
18
  import { DEFAULT_CONFIG } from "../config/defaults.js";
21
19
  import type {
22
20
  RscRenderMessage,
23
21
  RscWorkerMessage,
24
22
  RscWorkerResponse,
25
23
  } from "../worker/types.js";
26
- import { createLogger } from "../utils/logger.js";
24
+ import { MIME_TYPES } from "../config/mimeTypes.js";
25
+
27
26
 
28
- const log = createLogger("react-client");
29
27
  let userOptions: ResolvedUserOptions;
30
28
  let userConfig: ResolvedUserConfig;
31
29
  let clientManifest: Manifest = {};
@@ -43,9 +41,6 @@ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
43
41
  }
44
42
  userOptions = resolvedOptions.userOptions;
45
43
  root = userOptions.projectRoot;
46
- const rscWorkerPath = join(getPluginRoot(), DEFAULT_CONFIG.RSC_WORKER_PATH);
47
-
48
- log.info("RSC worker path:" + rscWorkerPath);
49
44
 
50
45
  return {
51
46
  name: "vite:react-client",
@@ -63,7 +58,7 @@ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
63
58
  if (configEnv.command === "serve" && !configEnv.isPreview && !worker) {
64
59
  worker = await createWorker({
65
60
  projectRoot: root,
66
- workerPath: rscWorkerPath,
61
+ workerPath: userOptions.rscWorkerPath,
67
62
  reverseCondition: true,
68
63
  });
69
64
  }
@@ -105,7 +100,7 @@ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
105
100
  resolvedConfig = config;
106
101
  },
107
102
 
108
- async generateBundle(options, bundle) {
103
+ async generateBundle(_options, bundle) {
109
104
  // Create manifest entries for each chunk
110
105
  clientManifest = getBundleManifest({
111
106
  pluginContext: this,
@@ -146,67 +141,22 @@ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
146
141
  const [key, value] = normalize(req.url);
147
142
  const fileRoot = key.startsWith("node_modules")
148
143
  ? root
149
- : join(root, userOptions.build.outDir, userOptions.build.client);
150
- if (value.endsWith(".js")) {
151
- try {
152
- const stats = await stat(join(fileRoot, value));
153
- if (stats.isFile()) {
154
- const content = await readFile(join(fileRoot, value), "utf-8");
155
- res.setHeader("Content-Type", "application/javascript");
156
- res.end(content);
157
- return;
158
- } else {
159
- next();
160
- }
161
- } catch (error) {
162
- const { manifest: clientManifest } = tryManifest({
163
- root,
164
- outDir: join(userOptions.build.outDir, userOptions.build.client),
165
- });
166
- const { manifest: serverManifest } = tryManifest({
167
- root,
168
- outDir: join(userOptions.build.outDir, userOptions.build.server),
169
- });
170
- if (clientManifest && value in clientManifest) {
171
- res.setHeader("Content-Type", "application/javascript");
172
- res.end(clientManifest[value]);
173
- return;
174
- } else if (serverManifest && value in serverManifest) {
175
- res.setHeader("Content-Type", "application/javascript");
176
- res.end(serverManifest[value]);
177
- return;
178
- }
179
- const foundClient =
180
- clientManifest &&
181
- Object.entries(clientManifest).find(
182
- ([key, value]) =>
183
- value === key ||
184
- value === value.file ||
185
- value === value.src ||
186
- value === value.name
187
- );
188
- if (foundClient) {
189
- res.setHeader("Content-Type", "application/javascript");
190
- res.end(foundClient);
191
- }
192
- const foundServer =
193
- serverManifest &&
194
- Object.entries(serverManifest).find(
195
- ([key, value]) =>
196
- value === key ||
197
- value === value.file ||
198
- value === value.src ||
199
- value === value.name
200
- );
201
-
202
- if (foundServer) {
203
- res.setHeader("Content-Type", "application/javascript");
204
- res.end(foundServer);
205
- return;
206
- }
207
- next();
144
+ : join(root, userOptions.build.outDir, userOptions.build.static);
145
+ try {
146
+ const filePath = join(fileRoot, value);
147
+ const stats = await stat(filePath);
148
+
149
+ if (stats.isFile()) {
150
+ const ext = value.slice(value.lastIndexOf('.'));
151
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
152
+ res.setHeader('Content-Type', contentType);
153
+ const content = await readFile(filePath);
154
+ res.end(content);
155
+ return;
208
156
  }
209
- } else {
157
+ next();
158
+ } catch (error) {
159
+ console.log("Error serving static file:", error);
210
160
  next();
211
161
  }
212
162
  });
@@ -217,13 +167,11 @@ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
217
167
  loader = server.ssrLoadModule;
218
168
  }
219
169
  if (!worker) {
220
- log.info("Creating RSC worker...");
221
170
  worker = await createWorker({
222
171
  projectRoot: root,
223
- workerPath: rscWorkerPath,
172
+ workerPath: userOptions.rscWorkerPath,
224
173
  condition: "react-client",
225
174
  });
226
- log.info("RSC worker created");
227
175
  }
228
176
  const normalize = createInputNormalizer({
229
177
  root,
@@ -306,7 +254,6 @@ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
306
254
 
307
255
  case "ERROR":
308
256
  clearTimeout(timeout);
309
- log.error("Render error", message);
310
257
  if (!hasError) {
311
258
  hasError = true;
312
259
  res.statusCode = 500;
@@ -360,7 +307,6 @@ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
360
307
  cssFiles: []
361
308
  } satisfies RscRenderMessage);
362
309
  } catch (error) {
363
- log.error("Middleware error:", error);
364
310
  res.statusCode = 500;
365
311
  res.end(error instanceof Error ? error.message : String(error));
366
312
  }
@@ -1,4 +1,5 @@
1
1
  import { reactPreservePlugin } from "../preserver/plugin.js";
2
+ import { reactStaticPlugin } from "../react-static/plugin.js";
2
3
  import { reactTransformPlugin } from "../transformer/plugin.js";
3
4
  import type { StreamPluginOptions } from "../types.js";
4
5
  import { reactServerPlugin } from "./plugin.js";
@@ -7,6 +8,7 @@ export function vitePluginReactServer(options = {} as StreamPluginOptions): impo
7
8
  return [
8
9
  reactTransformPlugin(options),
9
10
  reactServerPlugin(options),
11
+ reactStaticPlugin(options),
10
12
  reactPreservePlugin(options),
11
13
  ];
12
14
  }
@@ -1,6 +1,5 @@
1
- import { join, resolve, dirname } from "node:path";
1
+ import { join, dirname } from "node:path";
2
2
  import { performance } from "node:perf_hooks";
3
- import { Worker } from "node:worker_threads";
4
3
  import React from "react";
5
4
  import {
6
5
  createLogger,
@@ -8,42 +7,31 @@ import {
8
7
  type UserConfig,
9
8
  type ViteDevServer,
10
9
  type Manifest,
11
- build,
10
+ type Plugin as VitePlugin,
12
11
  } from "vite";
13
12
  import { checkFilesExist } from "../checkFilesExist.js";
14
- import { DEFAULT_CONFIG } from "../config/defaults.js";
15
- import { getPluginRoot } from "../config/getPaths.js";
16
13
  import { resolveOptions } from "../config/resolveOptions.js";
17
14
  import { resolvePages } from "../config/resolvePages.js";
18
15
  import { resolveUserConfig } from "../config/resolveUserConfig.js";
19
- import { tryManifest } from "../helpers/tryManifest.js";
20
- import { createBuildLoader } from "../loader/createBuildLoader.js";
21
16
  import type {
22
17
  BuildTiming,
23
18
  CheckFilesExistReturn,
24
19
  ReactStreamPluginMeta,
25
- ResolvedUserConfig,
26
20
  ResolvedUserOptions,
27
21
  } from "../types.js";
28
22
  import { type StreamPluginOptions } from "../types.js";
29
- import { createWorker } from "../worker/createWorker.js";
30
- import { renderPages } from "../worker/html/renderPages.js";
31
- import { createHandler } from "./createHandler.js";
32
- import { mkdir, readFile, writeFile } from "node:fs/promises";
23
+ import { createHandler } from "../helpers/createHandler.js";
24
+ import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
33
25
  import { getBundleManifest } from "../helpers/getBundleManifest.js";
34
26
  import type { ServerResponse } from "node:http";
35
- import { collectManifestCss } from "../collect-css-manifest.js";
27
+ import { createInputNormalizer } from "../helpers/inputNormalizer.js";
28
+ import { MIME_TYPES } from "../config/mimeTypes.js";
36
29
 
37
30
  let resolvedConfig: ResolvedConfig | null = null;
38
31
  let serverManifestPath: string | null = null;
39
- let clientManifestPath: string | null = null;
40
- let outpuptBundle: any;
41
- let outputOptions: any;
42
32
  let loader: ((id: string) => Promise<Record<string, any>>) | null = null;
43
- let worker: Worker;
44
- export function reactServerPlugin(
45
- options: StreamPluginOptions
46
- ): import("vite").Plugin<{
33
+
34
+ export function reactServerPlugin(options: StreamPluginOptions): VitePlugin<{
47
35
  meta: ReactStreamPluginMeta;
48
36
  addCssFile: (path: string) => void;
49
37
  }> {
@@ -54,39 +42,14 @@ export function reactServerPlugin(
54
42
  let files: CheckFilesExistReturn;
55
43
  // let env: Awaited<ReturnType<typeof getEnv>>;
56
44
  let cssModules = new Set<string>();
57
- let clientComponents = new Map<string, string>();
58
45
  // let define: Record<string, string>;
59
46
  let buildCssFiles = new Set<string>();
60
47
  let root: string = process.cwd();
61
- let userConfig: ResolvedUserConfig;
62
48
  let userOptions: ResolvedUserOptions;
63
- let moduleGraph: Record<
64
- string,
65
- {
66
- file: string;
67
- src: string;
68
- name: string;
69
- isEntry: boolean;
70
- imports: string[];
71
- dynamicImports: string[];
72
- }
73
- > = {};
49
+ let resolvedPages: string[];
74
50
  let serverManifest: Manifest = {};
75
51
 
76
- interface BuildStats {
77
- htmlFiles: number;
78
- clientComponents: number;
79
- cssFiles: number;
80
- totalRoutes: number;
81
- timing: {
82
- config: number;
83
- build: number;
84
- render: number;
85
- total: number;
86
- };
87
- }
88
-
89
- const resolvedOptions = resolveOptions(options);
52
+ const resolvedOptions = resolveOptions(options, false);
90
53
  if (resolvedOptions.type === "error") {
91
54
  throw resolvedOptions.error;
92
55
  }
@@ -104,6 +67,7 @@ export function reactServerPlugin(
104
67
  root
105
68
  );
106
69
  }
70
+
107
71
  return {
108
72
  name: "vite:react-stream-server",
109
73
  enforce: "post",
@@ -121,11 +85,6 @@ export function reactServerPlugin(
121
85
  userOptions.build.server,
122
86
  ".vite/manifest.json"
123
87
  );
124
- clientManifestPath = join(
125
- resolvedConfig.build.outDir,
126
- userOptions.build.client,
127
- ".vite/manifest.json"
128
- );
129
88
  timing.configResolved = performance.now();
130
89
 
131
90
  // Verify transformer runs first, preserver runs last
@@ -146,7 +105,45 @@ export function reactServerPlugin(
146
105
  );
147
106
  }
148
107
  },
149
- async configurePreviewServer(server) {},
108
+
109
+ async configurePreviewServer(server) {
110
+ if (root !== server.config.root) {
111
+ root = server.config.root;
112
+ }
113
+ if (typeof loader !== "function") {
114
+ loader = (id: string) => import(id);
115
+ }
116
+ const normalize = createInputNormalizer({
117
+ root,
118
+ removeExtension: false,
119
+ preserveModulesRoot: userOptions.build.preserveModulesRoot
120
+ ? userOptions.moduleBase
121
+ : undefined,
122
+ });
123
+ server.middlewares.use(async (req, res, next) => {
124
+ const [key, value] = normalize(req.url);
125
+ const fileRoot = key.startsWith("node_modules")
126
+ ? root
127
+ : join(root, userOptions.build.outDir, userOptions.build.static);
128
+ try {
129
+ const filePath = join(fileRoot, value);
130
+ const stats = await stat(filePath);
131
+
132
+ if (stats.isFile()) {
133
+ const ext = value.slice(value.lastIndexOf('.'));
134
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
135
+ res.setHeader('Content-Type', contentType);
136
+ const content = await readFile(filePath);
137
+ res.end(content);
138
+ return;
139
+ }
140
+ next();
141
+ } catch (error) {
142
+ console.log("Error serving static file:", error);
143
+ next();
144
+ }
145
+ });
146
+ },
150
147
  async configureServer(server: ViteDevServer) {
151
148
  if (typeof loader !== "function") {
152
149
  loader = server.ssrLoadModule;
@@ -185,35 +182,31 @@ export function reactServerPlugin(
185
182
  activeStreams.clear();
186
183
  });
187
184
 
188
- // server.ws.on("connection", (_socket, _req) => {
189
- // console.log("[vite-plugin-react-server] hooking up ws connection");
190
- // });
191
-
192
- // server.ws.on("listening", () => {
193
- // console.log("[vite-plugin-react-server] hooking up ws listening");
194
- // });
195
-
196
185
  server.middlewares.use(async (req, res, next) => {
197
186
  if (req.headers.accept !== "text/x-component") return next();
198
187
  if (typeof loader !== "function") {
199
188
  loader = server.ssrLoadModule;
200
189
  }
190
+ const route = req.url?.replace('/index.rsc', '');
201
191
  try {
202
- const handler = await createHandler(
203
- req.url ?? "",
204
- {
192
+ const handler = await createHandler({
193
+ url: !route || route === "" ? "/" : route,
194
+ urlMap: files.urlMap,
195
+ pluginOptions: {
205
196
  ...userOptions,
206
197
  // we'll leave the Html generation for later
207
198
  Html: React.Fragment,
208
199
  projectRoot: root,
209
200
  },
210
- {
201
+ streamOptions: {
211
202
  cssFiles: [],
212
203
  logger: createLogger(),
213
204
  loader,
214
205
  moduleGraph: server.moduleGraph,
206
+ moduleBasePath: '',
207
+ moduleBaseURL: '',
215
208
  }
216
- );
209
+ });
217
210
  if (handler.type === "success") {
218
211
  handler.stream?.pipe(res);
219
212
  }
@@ -239,12 +232,12 @@ export function reactServerPlugin(
239
232
  );
240
233
  root = config.root;
241
234
  }
242
- const resolvedPages = await resolvePages(userOptions.build.pages);
243
- if (resolvedPages.type === "error") {
244
- throw resolvedPages.error;
235
+ const resolvedPagesResult = await resolvePages(userOptions.build.pages);
236
+ if (resolvedPagesResult.type === "error") {
237
+ throw resolvedPagesResult.error;
245
238
  }
246
-
247
- files = await checkFilesExist(resolvedPages.pages, userOptions, root);
239
+ resolvedPages = resolvedPagesResult.pages;
240
+ files = await checkFilesExist(resolvedPages, userOptions, root);
248
241
 
249
242
  const resolvedConfig = resolveUserConfig({
250
243
  isClient: false,
@@ -258,7 +251,6 @@ export function reactServerPlugin(
258
251
  throw resolvedConfig.error;
259
252
  }
260
253
 
261
- userConfig = resolvedConfig.userConfig;
262
254
  return resolvedConfig.userConfig;
263
255
  },
264
256
  async buildStart() {
@@ -268,240 +260,16 @@ export function reactServerPlugin(
268
260
  console.log("Build already started");
269
261
  }
270
262
  },
271
- async closeBundle() {
272
- if (!userConfig || resolvedConfig?.command !== "build") return;
273
- try {
274
- timing.renderStart = performance.now();
275
-
276
- // Get the client manifest
277
- const clientManifestResult = tryManifest({
278
- root: root,
279
- outDir: join(userOptions.build.outDir, userOptions.build.client),
280
- ssrManifest: false,
281
- });
282
-
283
- if (clientManifestResult.type === "error") {
284
- throw clientManifestResult.error;
285
- }
286
-
287
- const clientManifest = clientManifestResult.manifest;
288
-
289
-
290
- worker = await createWorker({
291
- projectRoot: root,
292
- workerPath: userOptions.htmlWorkerPath,
293
- condition: 'react-server',
294
- reverseCondition: true,
295
- mode: (resolvedConfig?.mode ?? "production") as
296
- | "production"
297
- | "development",
298
- nodeOptions: "--conditions=react-client",
299
- });
300
-
301
- // Create the loader
302
- if (typeof loader !== "function") {
303
- if (!Object.keys(serverManifest).length) {
304
- console.warn(
305
- "[vite-plugin-react-server] No server manifest found, the plugin will try to use the plugin context - it may differ from vite's manifest."
306
- );
307
- serverManifest = getBundleManifest({
308
- pluginContext: this,
309
- bundle: outpuptBundle,
310
- moduleBase: userOptions.moduleBase,
311
- preserveModulesRoot: userOptions.build.preserveModulesRoot,
312
- });
313
- if (!Object.keys(serverManifest).length) {
314
- console.warn(
315
- "[vite-plugin-react-server] That didn't work, retrying to read manifest."
316
- );
317
- const resolvedServerManifest = tryManifest({
318
- root: root,
319
- outDir: join(
320
- userOptions.build.outDir,
321
- userOptions.build.server
322
- ),
323
- ssrManifest: false,
324
- });
325
- if (resolvedServerManifest.type === "error") {
326
- // dont build the static files without a server manifest
327
- console.error(
328
- "[vite-plugin-react-server] Failed to read manifest, aborting build."
329
- );
330
- return;
331
- }
332
- serverManifest = resolvedServerManifest.manifest;
333
- }
334
- }
335
- loader = createBuildLoader({
336
- root: root,
337
- userConfig,
338
- userOptions,
339
- pluginContext: this,
340
- serverManifest,
341
- clientManifest,
342
- });
343
- }
344
- const resolvedPages = await resolvePages(userOptions.build.pages);
345
- if (resolvedPages.type === "error") {
346
- throw resolvedPages.error;
347
- }
348
-
349
- const onCssFile = async (path: string, parentUrl: string) => {
350
- if (buildCssFiles && path.endsWith(".css")) {
351
- buildCssFiles.add(path);
352
- if (parentUrl.endsWith(userOptions.build.client)) {
353
- // copy the file to the client build dir
354
- const serverPath = join(
355
- userOptions.build.outDir,
356
- userOptions.build.server,
357
- path
358
- );
359
- await writeFile(
360
- serverPath,
361
- await readFile(
362
- join(
363
- root,
364
- userOptions.build.outDir,
365
- userOptions.build.client,
366
- path
367
- )
368
- )
369
- );
370
- } else {
371
- // copy the file to the client build dir, assume it's in server build dir
372
- const clientPath = join(
373
- userOptions.build.outDir,
374
- userOptions.build.client,
375
- path
376
- );
377
- await mkdir(dirname(clientPath), { recursive: true });
378
- await writeFile(
379
- clientPath,
380
- await readFile(
381
- join(
382
- root,
383
- userOptions.build.outDir,
384
- userOptions.build.server,
385
- path
386
- )
387
- )
388
- );
389
- }
390
- }
391
- };
392
-
393
- const { failedRoutes, completedRoutes } = await renderPages(
394
- this,
395
- resolvedPages.pages,
396
- files,
397
- {
398
- pipableStreamOptions: {
399
- bootstrapModules: clientManifest["index.html"]?.file
400
- ? [clientManifest["index.html"].file.startsWith('/') ? clientManifest["index.html"].file : '/' + clientManifest["index.html"].file]
401
- : [],
402
- },
403
- moduleBasePath: "",
404
- moduleBaseURL: "",
405
- clientCss: clientManifest["index.html"]?.css
406
- ? clientManifest["index.html"].css.map(css => css.startsWith('/') ? css : '/' + css)
407
- : [],
408
- userConfig,
409
- pluginOptions: userOptions,
410
- worker: worker,
411
- clientManifest: clientManifest,
412
- serverManifest: serverManifest,
413
- loader,
414
- onCssFile: onCssFile,
415
- }
416
- );
417
-
418
- if (failedRoutes.size) {
419
- console.error(
420
- "[vite-plugin-react-server] Failed to render routes:",
421
- failedRoutes
422
- );
423
- }
424
- if (worker) await worker.terminate();
425
-
426
- timing.renderEnd = performance.now();
427
- timing.total = (timing.renderEnd - timing.start) / 1000;
428
-
429
- // Update stats to include CSS and client components
430
- const stats: BuildStats = {
431
- htmlFiles: userOptions.build.pages.length,
432
- clientComponents: Object.keys(clientManifest).filter(
433
- userOptions.autoDiscover.clientComponents
434
- ).length,
435
- cssFiles: Object.keys(clientManifest)
436
- .flatMap(userOptions.autoDiscover.cssPattern)
437
- .filter(Boolean).length,
438
- totalRoutes: userOptions.build.pages.length,
439
- timing: {
440
- config: ((timing.configResolved ?? 0) - timing.start) / 1000,
441
- build:
442
- ((timing.buildStart ?? 0) - (timing.configResolved ?? 0)) / 1000,
443
- render:
444
- ((timing.renderEnd ?? 0) - (timing.renderStart ?? 0)) / 1000,
445
- total: (timing.renderEnd ?? 0 - timing.start) / 1000,
446
- },
447
- };
448
-
449
- // Format duration helper
450
- const formatDuration = (seconds: number) => {
451
- if (seconds < 0.001) {
452
- return `${(seconds * 1000000).toFixed(0)}μs`;
453
- }
454
- if (seconds < 1) {
455
- return `${(seconds * 1000).toFixed(0)}ms`;
456
- }
457
- return `${seconds.toFixed(2)}s`;
458
- };
459
-
460
- console.log("\n[vite-plugin-react-server] Build Summary:");
461
- console.log("─".repeat(50));
462
- console.log(`�� Generated ${stats.htmlFiles} HTML files`);
463
- console.log(`🎯 Processed ${stats.clientComponents} client components`);
464
- console.log(`🎨 Included ${stats.cssFiles} CSS files`);
465
- console.log(`🛣️ Total routes: ${stats.totalRoutes}`);
466
- console.log("─".repeat(50));
467
- console.log("⏱️ Timing:");
468
- console.log(` Config: ${formatDuration(stats.timing.config)}`);
469
- console.log(` Build: ${formatDuration(stats.timing.build)}`);
470
- console.log(` Render: ${formatDuration(stats.timing.render)}`);
471
- console.log(" ".repeat(12));
472
- console.log(` Total: ${formatDuration(stats.timing.total)}`);
473
- console.log("─".repeat(50));
474
-
475
- // Ensure worker is terminated
476
- if (worker) {
477
- await worker.terminate();
478
- worker = null as any;
479
- }
480
- } catch (error) {
481
- console.error("[vite-plugin-react-server] Build failed:", error);
482
- // Make sure to terminate worker even on error
483
- if (worker) await worker.terminate();
484
- worker = null as any;
485
- throw error;
486
- }
487
- },
488
- async buildEnd(error) {
489
- if (error) {
490
- console.error("[vite-plugin-react-server] Build error:", error);
491
- return;
492
- }
493
- },
494
263
  handleHotUpdate({ file }) {
495
264
  if (file.endsWith(".css")) {
496
265
  cssModules.add(file);
497
266
  }
498
267
  },
499
- async generateBundle(options, bundle) {
268
+ async generateBundle(_options, bundle) {
500
269
  if (!resolvedConfig) {
501
270
  throw new Error("Resolved config not found");
502
271
  }
503
- outpuptBundle = bundle;
504
- outputOptions = options;
272
+
505
273
  // Create manifest entries for each chunk
506
274
  serverManifest = getBundleManifest({
507
275
  pluginContext: this,
@@ -0,0 +1 @@
1
+ export { reactStaticPlugin } from "./plugin.js";