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
@@ -9,6 +9,11 @@ interface ModuleManifestEntry {
9
9
  dynamicImports?: string[];
10
10
  }
11
11
 
12
+ /**
13
+ * Get the module manifest from the plugin context, will only work during development
14
+ * @param this - The plugin context
15
+ * @returns The module manifest
16
+ */
12
17
  export function getModuleManifest(this: PluginContext): Record<string, ModuleManifestEntry> {
13
18
  const manifest: Record<string, ModuleManifestEntry> = {};
14
19
 
@@ -1,37 +1,186 @@
1
- import { join } from "path";
2
1
  import { normalizePath } from "vite";
3
- import { DEFAULT_CONFIG } from "../config/defaults.js";
4
2
  import type { InputNormalizer, NormalizerInput } from "../types.js";
3
+ import { join } from "path";
4
+ import { DEFAULT_CONFIG } from "../config/defaults.js";
5
5
 
6
- export function createInputNormalizer(root: string): InputNormalizer {
6
+ type CreateInputNormalizerProps = {
7
+ root: string;
8
+ preserveModulesRoot?: string | undefined;
9
+ removeExtension?: boolean | RegExp | string | ((path: string) => boolean);
10
+ moduleBasePath?: string;
11
+ };
7
12
 
8
- // Normalize a key by removing file extensions and leading slashes
9
- const normalizeKey = (key: string): string => {
10
- return key
11
- .replace(DEFAULT_CONFIG.FILE_REGEX, "") // Remove TypeScript/JavaScript extensions
12
- .replace(/^\/+/, ""); // Remove leading slashes
13
- };
13
+ const resolveExtensionOptions = (
14
+ removeExtension: CreateInputNormalizerProps["removeExtension"]
15
+ ) => {
16
+ if (typeof removeExtension === "boolean") {
17
+ if (removeExtension) {
18
+ return (path: string) => {
19
+ const extensionIndex = path.lastIndexOf(".");
20
+ return extensionIndex !== -1 ? path.slice(0, extensionIndex) : path;
21
+ };
22
+ }
23
+ return (path: string) => path;
24
+ }
25
+ if (typeof removeExtension === "string") {
26
+ return (path: string) => path.replace(removeExtension, "");
27
+ }
28
+ if (removeExtension instanceof RegExp) {
29
+ return (path: string) =>
30
+ removeExtension.test(path) ? path.replace(removeExtension, "") : path;
31
+ }
32
+ if (typeof removeExtension === "function") {
33
+ return (path: string) => {
34
+ const extIndex = path.lastIndexOf(".");
35
+ if (extIndex !== -1) {
36
+ const extension = path.slice(extIndex);
37
+ if (removeExtension(extension)) {
38
+ return path.slice(0, extIndex);
39
+ }
40
+ }
41
+ return path;
42
+ };
43
+ }
44
+ return (path: string) => path;
45
+ };
14
46
 
15
- // Main normalize function
16
- return (input: NormalizerInput): [string, string] => {
17
-
18
- // Handle tuple input [key, path]
19
- if (Array.isArray(input)) {
20
- const [key, path] = input;
21
- const normalized: [string, string] = [
22
- normalizeKey(key),
23
- normalizePath(join(root, path))
24
- ]
25
- return normalized;
47
+ const resolveRootOption = (
48
+ root: CreateInputNormalizerProps["root"],
49
+ preserveModulesRoot: CreateInputNormalizerProps["preserveModulesRoot"]
50
+ ) => {
51
+ if (typeof root !== "string" && typeof preserveModulesRoot !== "string") {
52
+ return "";
53
+ }
54
+ if (typeof preserveModulesRoot === "string" && typeof root === "string") {
55
+ const normalizedRoot = normalizePath(root);
56
+ const normalizedPreserveModulesRoot = normalizePath(preserveModulesRoot);
57
+ if (normalizedPreserveModulesRoot.startsWith(normalizedRoot)) {
58
+ return join(normalizedPreserveModulesRoot, "/");
26
59
  }
60
+ return join(normalizedRoot, normalizedPreserveModulesRoot, "/");
61
+ }
62
+ if (typeof preserveModulesRoot === "string" && typeof root !== "string") {
63
+ const normalizedRoot = normalizePath(root);
64
+ const normalizedPreserveModulesRoot = normalizePath(preserveModulesRoot);
65
+ if (normalizedRoot.startsWith(normalizedPreserveModulesRoot)) {
66
+ return join(normalizedPreserveModulesRoot, "/");
67
+ }
68
+ return join(normalizedRoot, normalizedPreserveModulesRoot, "/");
69
+ }
70
+ if (typeof preserveModulesRoot !== "string" && typeof root === "string") {
71
+ const normalizedRoot = normalizePath(root);
72
+ return join(normalizedRoot, "/");
73
+ }
74
+ return "/";
75
+ };
76
+ const createKeyNormalizer =
77
+ ({
78
+ normalizedRoot,
79
+ preserveModulesRoot,
80
+ handleExtension,
81
+ }: {
82
+ normalizedRoot: string;
83
+ preserveModulesRoot: string | undefined;
84
+ handleExtension: (path: string) => string;
85
+ }) =>
86
+ (key: string) => {
87
+ const normalPath = normalizePath(key);
88
+ const noRoot = normalPath.startsWith(normalizedRoot)
89
+ ? normalPath.slice(normalizedRoot.length)
90
+ : normalPath;
91
+ const noExtension = handleExtension(noRoot);
27
92
 
28
- // Handle string input
29
- if (typeof input === "string") {
30
- const key = normalizeKey(input);
31
- const path = normalizePath(join(root, input));
32
- return [key, path];
93
+ let noRelativeNorAbsolute = noExtension;
94
+ while (
95
+ noRelativeNorAbsolute.startsWith("/") ||
96
+ noRelativeNorAbsolute.startsWith(".")
97
+ ) {
98
+ noRelativeNorAbsolute = noRelativeNorAbsolute.slice(1);
99
+ }
100
+ if (preserveModulesRoot) {
101
+ const removedModulesRoot = noRelativeNorAbsolute.startsWith(
102
+ preserveModulesRoot
103
+ )
104
+ ? noRelativeNorAbsolute.slice(preserveModulesRoot.length)
105
+ : noRelativeNorAbsolute;
106
+ return removedModulesRoot.startsWith(normalizedRoot)
107
+ ? removedModulesRoot.slice(normalizedRoot.length)
108
+ : removedModulesRoot;
33
109
  }
110
+ return noRelativeNorAbsolute;
111
+ };
112
+
113
+ const createPathNormalizer =
114
+ ({ normalizedRoot, moduleBasePath }: { normalizedRoot: string, moduleBasePath: string }) =>
115
+ (path: string) => {
116
+ if(typeof path !== 'string') {
117
+ throw new Error(`Invalid path: ${JSON.stringify(path)}`);
118
+ }
119
+ const normalPath = normalizePath(path);
120
+ const noRoot = normalPath.startsWith(normalizedRoot)
121
+ ? normalPath.slice(normalizedRoot.length)
122
+ : normalPath;
123
+ // no leading slash when starting with module base
124
+ if(noRoot.startsWith(moduleBasePath)) {
125
+ return noRoot.slice(1);
126
+ }
127
+ return noRoot;
128
+ };
129
+ /**
130
+ * @description Create a function that normalizes the input
131
+ * @param root - The root of the project
132
+ * @param preserveModulesRoot - The root of the preserve modules
133
+ * @param removeExtension - Whether to remove the extension of the file
134
+ * @returns A function that normalizes the input
135
+ */
136
+ export function createInputNormalizer({
137
+ root,
138
+ preserveModulesRoot = undefined,
139
+ removeExtension = DEFAULT_CONFIG.FILE_REGEX,
140
+ moduleBasePath = "/",
141
+ }: CreateInputNormalizerProps): InputNormalizer {
142
+ const normalizedRoot = resolveRootOption(root, preserveModulesRoot);
143
+ const handleExtension = resolveExtensionOptions(removeExtension);
34
144
 
35
- throw new Error(`Invalid input type: ${typeof input}`);
145
+ const normalizeEntryKey = createKeyNormalizer({
146
+ normalizedRoot,
147
+ preserveModulesRoot,
148
+ handleExtension,
149
+ });
150
+
151
+ const normalizeEntryPath = createPathNormalizer({ normalizedRoot, moduleBasePath });
152
+ return function normalizeInput(id: NormalizerInput): [string, string] {
153
+ // Normalize both paths to use POSIX separators
154
+ if (Array.isArray(id)) {
155
+ const [key, path] = id;
156
+ if(typeof key === 'string' && Array.isArray(path) && path.length === 2) {
157
+ const isNumber = !isNaN(Number(key));
158
+ if(isNumber) {
159
+ // ignore it
160
+ return normalizeInput([path[0], path[1]]);
161
+ }
162
+ return normalizeInput([join(key, path[0]), path[1]]);
163
+ }
164
+ if(typeof key !== 'string' || typeof path !== 'string') {
165
+ throw new Error(`Invalid input: ${JSON.stringify(id)}`);
166
+ }
167
+ return [normalizeEntryKey(key), normalizeEntryPath(path)];
168
+ } else if (typeof id === "string") {
169
+ // Return both the normalized ID and original normalized path
170
+ return [normalizeEntryKey(id), normalizeEntryPath(id)];
171
+ } else if (
172
+ typeof id === "object" &&
173
+ id !== null &&
174
+ "$$typeof" in id &&
175
+ "$$id" in id &&
176
+ typeof id.$$id === "string"
177
+ ) {
178
+ const normalized: [string, string] = [
179
+ normalizeEntryKey(id.$$id),
180
+ normalizeEntryPath(id.$$id),
181
+ ];
182
+ return normalized;
183
+ }
184
+ throw new Error(`Invalid input type: ${typeof id}`);
36
185
  };
37
186
  }
@@ -7,14 +7,19 @@ interface WorkerNormalizerOptions {
7
7
  moduleBase: string;
8
8
  worker: Worker;
9
9
  moduleBaseExceptions?: string[];
10
+ preserveModulesRoot: boolean | undefined;
10
11
  }
11
12
 
12
13
  export function createInputNormalizerWorker({
13
14
  root,
15
+ moduleBase,
14
16
  worker,
17
+ preserveModulesRoot,
15
18
  }: WorkerNormalizerOptions): InputNormalizerWorker {
16
-
17
- const baseNormalizer = createInputNormalizer(root);
19
+ const baseNormalizer = createInputNormalizer({
20
+ root,
21
+ preserveModulesRoot: preserveModulesRoot === true ? moduleBase : undefined,
22
+ });
18
23
 
19
24
  return async (input: NormalizerInput): Promise<[string, string]> => {
20
25
  // Handle React components specially with worker
@@ -22,21 +27,21 @@ export function createInputNormalizerWorker({
22
27
  return new Promise((resolve, reject) => {
23
28
  const handler = (message: any) => {
24
29
  if (message.type === "CLIENT_REFERENCE") {
25
- worker.off('message', handler);
30
+ worker.off("message", handler);
26
31
  resolve([message.ref.$$id, message.ref.$$location]);
27
32
  }
28
33
  if (message.type === "ERROR") {
29
- worker.off('message', handler);
34
+ worker.off("message", handler);
30
35
  reject(new Error(message.error));
31
36
  }
32
37
  };
33
38
 
34
- worker.on('message', handler);
39
+ worker.on("message", handler);
35
40
  worker.postMessage({
36
41
  type: "CLIENT_REFERENCE",
37
- id: input.name || 'AnonymousComponent',
42
+ id: input.name || "AnonymousComponent",
38
43
  location: input.toString(),
39
- key: input.name
44
+ key: input.name,
40
45
  });
41
46
  });
42
47
  }
@@ -44,4 +49,4 @@ export function createInputNormalizerWorker({
44
49
  // For all other types, use the base normalizer
45
50
  return baseNormalizer(input);
46
51
  };
47
- }
52
+ }
@@ -11,9 +11,11 @@ type TryManifestOptions<SSR extends boolean> = {
11
11
  export function tryManifest<SSR extends boolean>(options: TryManifestOptions<SSR>): {
12
12
  type: "success";
13
13
  manifest: SSR extends true ? Record<string, string[]> : Manifest;
14
+ error?:never
14
15
  } | {
15
16
  type: "error";
16
17
  error: Error;
18
+ manifest?:never
17
19
  } {
18
20
  const manifestPath = resolve(
19
21
  options.root,
@@ -1,23 +1,67 @@
1
- import { join } from "path";
1
+ import { join, resolve } from "node:path";
2
2
  import type { PluginContext } from "rollup";
3
- import type { ResolvedUserConfig } from "../../server.js";
4
- import { DEFAULT_CONFIG } from "../config/defaults.js";
3
+ import type { ResolvedUserConfig, ResolvedUserOptions } from "../../server.js";
4
+ import type { Manifest } from "vite";
5
+ import { createInputNormalizer } from "../helpers/inputNormalizer.js";
5
6
 
6
7
  export interface BuildLoaderOptions {
7
8
  root: string;
8
9
  pluginContext: PluginContext;
9
10
  userConfig: ResolvedUserConfig;
11
+ userOptions: ResolvedUserOptions;
12
+ serverManifest: Manifest;
13
+ clientManifest: Manifest;
10
14
  }
11
15
 
12
16
  export function createBuildLoader({
13
- root,
14
17
  userConfig,
18
+ userOptions,
19
+ pluginContext,
20
+ clientManifest,
21
+ serverManifest,
15
22
  }: BuildLoaderOptions) {
16
- return async (id: string) => {
17
- return import(join(
18
- root,
19
- userConfig.build.outDir,
20
- id.replace(DEFAULT_CONFIG.FILE_REGEX, "") + ".js"
21
- ));
23
+ const root = pluginContext.environment.config.root ?? userConfig.root ?? userOptions.projectRoot ?? process.cwd();
24
+ const normalizer = createInputNormalizer({
25
+ root: userConfig.root,
26
+ preserveModulesRoot:
27
+ userOptions.build.preserveModulesRoot === true
28
+ ? userOptions.moduleBase
29
+ : undefined,
30
+ });
31
+
32
+ return async function buildLoader(id: string) {
33
+ // Normalize the requested ID - strip leading slash
34
+ const [normalizedId] = normalizer(id.replace(/^\//, ''));
35
+
36
+ // Try to find the module in either manifest
37
+ const clientEntry = Object.entries(clientManifest).find(([key]) => {
38
+ const [keyNormalized] = normalizer(key);
39
+ return keyNormalized === normalizedId;
40
+ });
41
+
42
+ if (clientEntry) {
43
+ console.log("[vite:plugin-react-server] Loading client entry", clientEntry[1].file);
44
+ const module = await import(
45
+ join(root, clientEntry[1].file)
46
+ );
47
+ return module;
48
+ }
49
+
50
+ const serverEntry = Object.entries(serverManifest).find(([key]) => {
51
+ const [keyNormalized] = normalizer(key);
52
+ return keyNormalized === normalizedId;
53
+ });
54
+
55
+ if (serverEntry) {
56
+ const module = await import(
57
+ join(root, serverEntry[1].file)
58
+ );
59
+ return module;
60
+ }
61
+ const availableModules = [...Object.keys(clientManifest), ...Object.keys(serverManifest)]
62
+
63
+ throw new Error(
64
+ `Module not found: ${id}, available modules: ${availableModules.join(", ")}`
65
+ );
22
66
  };
23
67
  }
@@ -76,13 +76,7 @@ export function createPageLoader({
76
76
  registerClient,
77
77
  }: CreatePageLoaderOptions) {
78
78
  return async function loader(id: string) {
79
- console.log("[pageLoader] Loading:", {
80
- id,
81
- manifest: Object.keys(manifest),
82
- outDir,
83
- moduleBase
84
- });
85
- console.log("[pageLoader] Manifest:", manifest);
79
+
86
80
  // Try to find the entry directly or by source file
87
81
  const manifestEntry = manifest[id] ||
88
82
  Object.values(manifest).find(entry => entry.src === id);
package/plugin/plugin.ts CHANGED
@@ -1,4 +1,4 @@
1
- import "./assertServerCondition.js";
1
+ import { assertServerCondition } from "./assertServerCondition.js";
2
2
  export { reactServerPlugin } from "./react-server/plugin.js";
3
3
  export { reactClientPlugin } from "./react-client/plugin.js";
4
4
  export { reactTransformPlugin } from "./transformer/plugin.js";
@@ -6,3 +6,4 @@ export { reactPreservePlugin } from "./preserver/plugin.js";
6
6
  export { vitePluginReactServer } from "./react-server/index.js";
7
7
  // the main plugin is version is the server version, if you want the client version, use the `vite-plugin-react-server/client` import
8
8
  // this is because the workflow assumes main thread = react server condition
9
+ assertServerCondition(process);
@@ -1,6 +1,7 @@
1
1
  import type { Node } from "estree";
2
2
  import MagicString from "magic-string";
3
3
  import type { StreamPluginOptions } from "../types.js";
4
+ import { DEFAULT_CONFIG } from "../config/defaults.js";
4
5
 
5
6
  const REACT_DIRECTIVES = new Set(["use client", "use server"]);
6
7
 
@@ -15,7 +16,7 @@ export function reactPreservePlugin(_options: StreamPluginOptions): import("vite
15
16
  order: "post", // Ensure this runs last in transform phase
16
17
  handler(code: string, id: string) {
17
18
  // Skip node_modules and vite files
18
- if (id.includes("node_modules") || id.includes("vite/dist")) {
19
+ if (id.includes("node_modules") || id.includes("vite/dist") || !id.match(DEFAULT_CONFIG.FILE_REGEX)) {
19
20
  return null;
20
21
  }
21
22
 
@@ -1 +1,12 @@
1
- export { reactClientPlugin } from "./plugin.js";
1
+ import { reactPreservePlugin } from "../plugin.js";
2
+ import { reactTransformPlugin } from "../transformer/plugin.js";
3
+ import type { StreamPluginOptions } from "../types.js";
4
+ import { reactClientPlugin } from "./plugin.js";
5
+
6
+ export function vitePluginReactClient(options = {} as StreamPluginOptions): import("vite").Plugin[] {
7
+ return [
8
+ reactPreservePlugin(options),
9
+ reactClientPlugin(options),
10
+ reactTransformPlugin(options),
11
+ ];
12
+ }
@@ -1,33 +1,148 @@
1
- import type { Plugin as VitePlugin, UserConfig } from "vite";
2
-
3
- import type { ResolvedUserOptions, StreamPluginOptions } from "../types.js";
1
+ import { type Manifest, type Plugin, type ResolvedConfig } from "vite";
2
+ import type {
3
+ ResolvedUserConfig,
4
+ ResolvedUserOptions,
5
+ StreamPluginOptions,
6
+ } from "../types.js";
4
7
  import { resolveOptions } from "../config/resolveOptions.js";
5
8
  import { resolveUserConfig } from "../config/resolveUserConfig.js";
6
-
9
+ import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
10
+ import { dirname, join, resolve } from "node:path";
11
+ import { getBundleManifest } from "../helpers/getBundleManifest.js";
12
+ import { checkFilesExist } from "../checkFilesExist.js";
13
+ import { resolvePages } from "../config/resolvePages.js";
7
14
  let userOptions: ResolvedUserOptions;
8
-
9
- export function reactClientPlugin(options: StreamPluginOptions): VitePlugin {
10
- const resolvedOptions = resolveOptions(options);
15
+ let userConfig: ResolvedUserConfig;
16
+ let clientManifest: Manifest = {};
17
+ let resolvedConfig: ResolvedConfig;
18
+ let root: string;
19
+ let loader: ((id: string) => Promise<Record<string, any>>) = (id: string) => import(id);
20
+ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
21
+ const resolvedOptions = resolveOptions(options, true);
11
22
  if (resolvedOptions.type === "error") {
12
23
  throw resolvedOptions.error;
13
24
  }
14
25
  userOptions = resolvedOptions.userOptions;
26
+ root = userOptions.projectRoot;
27
+
28
+ console.log("[vite:react-client] Initial setup:", {
29
+ projectRoot: userOptions.projectRoot,
30
+ root: root,
31
+ clientEntry: userOptions.clientEntry
32
+ });
15
33
 
16
34
  return {
17
- name: "vite:react-stream-client",
18
- async config(config): Promise<UserConfig> {
35
+ name: "vite:react-client",
36
+
37
+ async config(config, configEnv) {
38
+
39
+ if(typeof config.root === "string" &&
40
+ config.root !== root &&
41
+ config.root !== process.cwd() &&
42
+ config.root !== "") {
43
+ root = config.root;
44
+ console.log("[vite:react-client] Root updated:", root);
45
+ }
46
+
47
+ const pages = await resolvePages(userOptions.build.pages);
48
+ if(pages.type === "error") {
49
+ throw pages.error;
50
+ }
51
+
52
+ const files = await checkFilesExist(pages.pages, userOptions, root);
53
+
54
+
19
55
  const resolvedConfig = resolveUserConfig({
20
- condition: "react-client",
56
+ isClient: true,
21
57
  config,
22
- configEnv: { command: "build", mode: "production" },
58
+ configEnv,
23
59
  userOptions,
60
+ files
24
61
  });
25
62
 
26
63
  if (resolvedConfig.type === "error") {
27
64
  throw resolvedConfig.error;
28
65
  }
29
66
 
30
- return resolvedConfig.userConfig;
67
+ userConfig = resolvedConfig.userConfig;
68
+ return userConfig;
69
+ },
70
+
71
+ configResolved(config) {
72
+ resolvedConfig = config;
73
+ },
74
+
75
+ async generateBundle(options, bundle) {
76
+ // Create manifest entries for each chunk
77
+ clientManifest = getBundleManifest(this, bundle, undefined);
78
+
79
+ // Write manifest immediately after generation
80
+ const manifestPath = join(
81
+ root,
82
+ resolvedConfig.environments['client'].build.outDir as string,
83
+ resolvedConfig.environments['client'].build.manifest as string
84
+ );
85
+ await mkdir(dirname(manifestPath), { recursive: true });
86
+
87
+ return await writeFile(
88
+ manifestPath,
89
+ JSON.stringify(clientManifest, null, 2)
90
+ );
91
+ },
92
+
93
+ async configurePreviewServer(server) {
94
+ if (typeof loader !== "function") {
95
+ loader = (id: string) => import(id);
96
+ }
97
+ server.middlewares.use(async (req, res, next) => {
98
+ console.log('req.url', req.url);
99
+ if (req.url && req.url.endsWith('.js')) {
100
+ const nodeRoot = process.env['NODE_PATH'] ?? process.cwd();
101
+
102
+ try {
103
+ const stats = await stat(req.url);
104
+ if (stats.isFile()) {
105
+ const content = await readFile(req.url, 'utf-8');
106
+ res.setHeader('Content-Type', 'application/javascript');
107
+ res.end(content);
108
+ } else {
109
+ next();
110
+ }
111
+ } catch (error) {
112
+ console.error('error', error);
113
+ next();
114
+ }
115
+ } else {
116
+ next();
117
+ }
118
+ });
119
+ },
120
+ // setup dev server
121
+ async configureServer(server) {
122
+ if (typeof loader !== "function") {
123
+ loader = server.ssrLoadModule;
124
+ }
125
+ server.middlewares.use(async (req, res, next) => {
126
+ console.log('req.url', req.url);
127
+ if (req.url && req.url.endsWith('.js')) {
128
+ const filePath = join(root, req.url);
129
+ try {
130
+ const stats = await stat(filePath);
131
+ if (stats.isFile()) {
132
+ const content = await readFile(filePath, 'utf-8');
133
+ res.setHeader('Content-Type', 'application/javascript');
134
+ res.end(content);
135
+ } else {
136
+ next();
137
+ }
138
+ } catch (error) {
139
+ next();
140
+ }
141
+ } else if(req.url && req.url.endsWith('.rsc')) {
142
+ // stream the rsc stream
143
+ throw new Error('Not implemented');
144
+ }
145
+ });
31
146
  }
32
147
  };
33
148
  }
@@ -7,7 +7,7 @@ import {
7
7
  import { DEFAULT_CONFIG } from "../config/defaults.js";
8
8
  import { resolvePage } from "../resolvePage.js";
9
9
  import { resolveProps } from "../resolveProps.js";
10
- import type { CreateHandlerOptions, StreamPluginOptions } from "../types.js";
10
+ import type { CreateHandlerOptions, ResolvedUserOptions } from "../types.js";
11
11
  import { createRscStream } from "./createRscStream.js";
12
12
 
13
13
  type CreateHandlerResult =
@@ -22,13 +22,7 @@ interface HandlerAssets {
22
22
 
23
23
  export async function createHandler<T>(
24
24
  url: string,
25
- pluginOptions: Pick<
26
- StreamPluginOptions,
27
- "Page" | "props" | "build" | "Html" | "pageExportName" | "propsExportName"
28
- > &
29
- Required<
30
- Pick<StreamPluginOptions, "moduleBase" | "moduleBasePath" | "projectRoot">
31
- >,
25
+ pluginOptions: ResolvedUserOptions,
32
26
  streamOptions: CreateHandlerOptions<T>
33
27
  ): Promise<CreateHandlerResult> {
34
28
  const root = pluginOptions.projectRoot ?? process.cwd();
@@ -52,13 +46,13 @@ export async function createHandler<T>(
52
46
 
53
47
  const cssModules = new Set<string>();
54
48
 
55
- if (!(streamOptions.manifest || streamOptions.moduleGraph))
56
- throw new Error("Missing manifest or moduleGraph, pass it to options.");
49
+ if (!(streamOptions.serverManifest || streamOptions.moduleGraph))
50
+ throw new Error("Missing server manifest or moduleGraph, pass it to options.");
57
51
 
58
- const getCss = streamOptions.manifest
52
+ const getCss = streamOptions.serverManifest
59
53
  ? (id: string) =>
60
54
  collectManifestCss(
61
- streamOptions.manifest!,
55
+ streamOptions.serverManifest!,
62
56
  root,
63
57
  id,
64
58
  streamOptions.onCssFile
@@ -131,7 +125,7 @@ export async function createHandler<T>(
131
125
  Html: Html,
132
126
  Page: Page,
133
127
  props: props,
134
- moduleBasePath: pluginOptions.moduleBasePath,
128
+ moduleBasePath: '',
135
129
  logger: streamOptions.logger ?? createLogger(),
136
130
  cssFiles: Array.from(cssModules),
137
131
  route: url,