vite-plugin-react-server 0.3.0 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -40
- package/dist/assertServerCondition.d.ts +2 -0
- package/dist/assertServerCondition.d.ts.map +1 -0
- package/dist/bin/patch.js +51 -0
- package/dist/bin/patch.js.map +1 -0
- package/dist/build/createBuildConfig.d.ts +7 -6
- package/dist/build/createBuildConfig.d.ts.map +1 -1
- package/dist/build/mergeInputs.d.ts +5 -0
- package/dist/build/mergeInputs.d.ts.map +1 -0
- package/dist/helpers/inputNormalizer.d.ts +6 -0
- package/dist/helpers/inputNormalizer.d.ts.map +1 -0
- package/dist/helpers/normalizedRelativePath.d.ts +3 -1
- package/dist/helpers/normalizedRelativePath.d.ts.map +1 -1
- package/dist/helpers/tryManifest.d.ts +10 -3
- package/dist/helpers/tryManifest.d.ts.map +1 -1
- package/dist/html/createPageLoader.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/options.d.ts +13 -8
- package/dist/options.d.ts.map +1 -1
- package/dist/plugin.d.ts +2 -7
- package/dist/plugin.d.ts.map +1 -1
- package/dist/react-client/plugin.js +1 -1
- package/dist/react-server/plugin.d.ts.map +1 -1
- package/dist/react-server/plugin.js +108 -61
- package/dist/react-server/plugin.js.map +1 -1
- package/dist/scripts/check-react-version.js +34 -0
- package/dist/scripts/check-react-version.js.map +1 -0
- package/dist/src/build/createBuildConfig.js +44 -0
- package/dist/src/build/createBuildConfig.js.map +1 -0
- package/dist/src/build/mergeInputs.js +16 -0
- package/dist/src/build/mergeInputs.js.map +1 -0
- package/dist/src/checkFilesExist.js.map +1 -0
- package/dist/src/collect-css-manifest.js.map +1 -0
- package/dist/src/components.js.map +1 -0
- package/dist/src/getEnv.js.map +1 -0
- package/dist/src/helpers/inputNormalizer.js +11 -0
- package/dist/src/helpers/inputNormalizer.js.map +1 -0
- package/dist/src/helpers/normalizedRelativePath.js +34 -0
- package/dist/src/helpers/normalizedRelativePath.js.map +1 -0
- package/dist/src/helpers/tryManifest.js +27 -0
- package/dist/src/helpers/tryManifest.js.map +1 -0
- package/dist/{html → src/html}/createPageLoader.js +3 -1
- package/dist/src/html/createPageLoader.js.map +1 -0
- package/dist/{options.js → src/options.js} +80 -24
- package/dist/src/options.js.map +1 -0
- package/dist/src/react-server/createHandler.js.map +1 -0
- package/dist/src/react-server/createRscStream.js.map +1 -0
- package/dist/src/resolvePage.js.map +1 -0
- package/dist/src/resolveProps.js.map +1 -0
- package/dist/src/worker/createHtmlStream.js +62 -0
- package/dist/src/worker/createHtmlStream.js.map +1 -0
- package/dist/{worker → src/worker}/createWorker.js +9 -8
- package/dist/src/worker/createWorker.js.map +1 -0
- package/dist/src/worker/renderPages.js.map +1 -0
- package/dist/types.d.ts +7 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/worker/createWorker.d.ts +8 -1
- package/dist/worker/createWorker.d.ts.map +1 -1
- package/dist/worker/loader.js +7 -0
- package/dist/worker/loader.js.map +1 -0
- package/dist/worker/worker.js +112 -0
- package/dist/worker/worker.js.map +1 -0
- package/package.json +109 -111
- package/patches/react-server-dom-esm+0.0.1.patch +13424 -0
- package/scripts/bump-version.mjs +68 -0
- package/scripts/check-react-version.mjs +48 -0
- package/src/assertServerCondition.ts +13 -0
- package/src/build/createBuildConfig.ts +27 -44
- package/src/build/mergeInputs.ts +42 -0
- package/src/helpers/inputNormalizer.ts +22 -0
- package/src/helpers/normalizedRelativePath.ts +25 -25
- package/src/helpers/tryManifest.ts +19 -5
- package/src/html/createPageLoader.ts +2 -0
- package/src/options.ts +119 -47
- package/src/plugin.ts +4 -30
- package/src/react-server/createSsrHandler.ts +1 -1
- package/src/react-server/plugin.ts +116 -56
- package/src/types.ts +19 -1
- package/src/worker/createWorker.ts +12 -7
- package/tsconfig.json +2 -0
- package/dist/build/createBuildConfig.js +0 -55
- package/dist/build/createBuildConfig.js.map +0 -1
- package/dist/checkFilesExist.js.map +0 -1
- package/dist/collect-css-manifest.js.map +0 -1
- package/dist/components.js.map +0 -1
- package/dist/getEnv.js.map +0 -1
- package/dist/helpers/normalizedRelativePath.js +0 -31
- package/dist/helpers/normalizedRelativePath.js.map +0 -1
- package/dist/html/createPageLoader.js.map +0 -1
- package/dist/options.js.map +0 -1
- package/dist/plugin.js +0 -31
- package/dist/plugin.js.map +0 -1
- package/dist/react-server/createHandler.js.map +0 -1
- package/dist/react-server/createRscStream.js.map +0 -1
- package/dist/resolvePage.js.map +0 -1
- package/dist/resolveProps.js.map +0 -1
- package/dist/transformer/index.js +0 -54
- package/dist/transformer/index.js.map +0 -1
- package/dist/transformer/preserveDirectives.js +0 -72
- package/dist/transformer/preserveDirectives.js.map +0 -1
- package/dist/transformer/transformer.js +0 -80
- package/dist/transformer/transformer.js.map +0 -1
- package/dist/worker/createWorker.js.map +0 -1
- package/dist/worker/renderPages.js.map +0 -1
- /package/dist/{checkFilesExist.js → src/checkFilesExist.js} +0 -0
- /package/dist/{collect-css-manifest.js → src/collect-css-manifest.js} +0 -0
- /package/dist/{components.js → src/components.js} +0 -0
- /package/dist/{getEnv.js → src/getEnv.js} +0 -0
- /package/dist/{react-server → src/react-server}/createHandler.js +0 -0
- /package/dist/{react-server → src/react-server}/createRscStream.js +0 -0
- /package/dist/{resolvePage.js → src/resolvePage.js} +0 -0
- /package/dist/{resolveProps.js → src/resolveProps.js} +0 -0
- /package/dist/{worker → src/worker}/renderPages.js +0 -0
package/src/options.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import type { ConfigEnv, ResolvedConfig, UserConfig } from "vite";
|
|
3
|
-
import type { ResolvedUserOptions, StreamPluginOptions } from "./types.js";
|
|
3
|
+
import type { ResolvedUserConfig, ResolvedUserOptions, StreamPluginOptions } from "./types.js";
|
|
4
|
+
import type { InputOption } from "rollup";
|
|
4
5
|
// Default configuration values
|
|
5
6
|
export const DEFAULT_CONFIG = {
|
|
6
7
|
FILE_REGEX: /\.(m|c)?(j|t)sx?$/,
|
|
@@ -14,9 +15,9 @@ export const DEFAULT_CONFIG = {
|
|
|
14
15
|
CLIENT_ENTRY: "/src/client.tsx",
|
|
15
16
|
PAGE_EXPORT: "Page",
|
|
16
17
|
PROPS_EXPORT: "props",
|
|
17
|
-
//
|
|
18
|
-
WORKER_PATH: "
|
|
19
|
-
LOADER_PATH: "
|
|
18
|
+
// Use package name paths instead of relative paths
|
|
19
|
+
WORKER_PATH: "vite-plugin-react-server/worker",
|
|
20
|
+
LOADER_PATH: "vite-plugin-react-server/loader",
|
|
20
21
|
RSC_EXTENSION: ".rsc",
|
|
21
22
|
HTML: ({ children }: { children: any }) => children,
|
|
22
23
|
COLLECT_CSS: true,
|
|
@@ -33,6 +34,10 @@ export const DEFAULT_CONFIG = {
|
|
|
33
34
|
client: "dist/client",
|
|
34
35
|
server: "dist/server",
|
|
35
36
|
},
|
|
37
|
+
AUTO_DISCOVER: {
|
|
38
|
+
pagePattern: "**/*.page.tsx",
|
|
39
|
+
propsPattern: "**/*.props.ts",
|
|
40
|
+
},
|
|
36
41
|
} as const;
|
|
37
42
|
|
|
38
43
|
export const resolveConfig = <T extends ResolvedConfig>(
|
|
@@ -51,7 +56,7 @@ export const resolveConfig = <T extends ResolvedConfig>(
|
|
|
51
56
|
|
|
52
57
|
export const resolveUserConfig = (
|
|
53
58
|
condition: "react-client" | "react-server",
|
|
54
|
-
input:
|
|
59
|
+
input: InputOption,
|
|
55
60
|
config: UserConfig,
|
|
56
61
|
configEnv: ConfigEnv,
|
|
57
62
|
userOptions: ResolvedUserOptions
|
|
@@ -59,8 +64,7 @@ export const resolveUserConfig = (
|
|
|
59
64
|
| { type: "error"; error: Error }
|
|
60
65
|
| {
|
|
61
66
|
type: "success";
|
|
62
|
-
userConfig:
|
|
63
|
-
Omit<UserConfig, "root" | "build" | "mode">;
|
|
67
|
+
userConfig: ResolvedUserConfig;
|
|
64
68
|
} => {
|
|
65
69
|
const isReactServer = condition === "react-server";
|
|
66
70
|
const isViteServer = configEnv.command === "serve";
|
|
@@ -74,14 +78,17 @@ export const resolveUserConfig = (
|
|
|
74
78
|
...config.build,
|
|
75
79
|
rollupOptions: {
|
|
76
80
|
...config.build?.rollupOptions,
|
|
77
|
-
input: input
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
+
input: input,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
};
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
if (
|
|
88
|
+
if (
|
|
89
|
+
typeof config.build?.assetsDir === "string" &&
|
|
90
|
+
userOptions.assetsDir !== config.build?.assetsDir
|
|
91
|
+
) {
|
|
85
92
|
return {
|
|
86
93
|
type: "error",
|
|
87
94
|
error: new Error(
|
|
@@ -111,7 +118,7 @@ export const resolveUserConfig = (
|
|
|
111
118
|
: "react-server condition was not set. Please use `NODE_OPTIONS='--conditions react-server' vite build --ssr`"
|
|
112
119
|
),
|
|
113
120
|
};
|
|
114
|
-
} else if (!configEnv.isSsrBuild && configEnv.command !==
|
|
121
|
+
} else if (!configEnv.isSsrBuild && configEnv.command !== "serve") {
|
|
115
122
|
return {
|
|
116
123
|
type: "error",
|
|
117
124
|
error: new Error(
|
|
@@ -122,7 +129,16 @@ export const resolveUserConfig = (
|
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
const { root: configRoot, mode: configMode, ...configRest } = config;
|
|
125
|
-
const {
|
|
132
|
+
const {
|
|
133
|
+
outDir: configOutDir,
|
|
134
|
+
assetsDir: configAssetsDir,
|
|
135
|
+
ssr: configSsr,
|
|
136
|
+
manifest: configManifest,
|
|
137
|
+
ssrManifest: configSsrManifest,
|
|
138
|
+
ssrEmitAssets: configSsrEmitAssets,
|
|
139
|
+
target: configTarget,
|
|
140
|
+
...configBuildRest
|
|
141
|
+
} = config.build ?? {};
|
|
126
142
|
|
|
127
143
|
return {
|
|
128
144
|
type: "success",
|
|
@@ -135,6 +151,7 @@ export const resolveUserConfig = (
|
|
|
135
151
|
ssr: configSsr ?? isReactServer,
|
|
136
152
|
manifest: configManifest ?? true,
|
|
137
153
|
ssrManifest: configSsrManifest ?? true,
|
|
154
|
+
ssrEmitAssets: configSsrEmitAssets ?? true,
|
|
138
155
|
target: configTarget ?? "es2020",
|
|
139
156
|
outDir:
|
|
140
157
|
typeof configOutDir === "string"
|
|
@@ -146,7 +163,7 @@ export const resolveUserConfig = (
|
|
|
146
163
|
typeof configAssetsDir === "string"
|
|
147
164
|
? configAssetsDir
|
|
148
165
|
: isReactServer
|
|
149
|
-
?
|
|
166
|
+
? ""
|
|
150
167
|
: DEFAULT_CONFIG.CLIENT_ASSETS_DIR,
|
|
151
168
|
},
|
|
152
169
|
},
|
|
@@ -156,37 +173,63 @@ export const resolveUserConfig = (
|
|
|
156
173
|
export const resolveOptions = (
|
|
157
174
|
options: StreamPluginOptions
|
|
158
175
|
):
|
|
159
|
-
| { type: "error"; error: Error }
|
|
160
176
|
| {
|
|
161
177
|
type: "success";
|
|
162
178
|
userOptions: ResolvedUserOptions;
|
|
179
|
+
}
|
|
180
|
+
| {
|
|
181
|
+
type: "error";
|
|
182
|
+
error: Error;
|
|
163
183
|
} => {
|
|
164
|
-
const
|
|
184
|
+
const {
|
|
185
|
+
workerPath: optionsWorkerPath,
|
|
186
|
+
loaderPath: optionsLoaderPath,
|
|
187
|
+
projectRoot: optionsProjectRoot,
|
|
188
|
+
moduleBase: optionsModuleBase,
|
|
189
|
+
moduleBasePath: optionsModuleBasePath,
|
|
190
|
+
moduleBaseURL: optionsModuleBaseURL,
|
|
191
|
+
build: optionsBuild,
|
|
192
|
+
Page: optionsPage,
|
|
193
|
+
props: optionsProps,
|
|
194
|
+
Html: optionsHtml,
|
|
195
|
+
pageExportName: optionsPageExportName,
|
|
196
|
+
propsExportName: optionsPropsExportName,
|
|
197
|
+
collectCss: optionsCollectCss,
|
|
198
|
+
collectAssets: optionsCollectAssets,
|
|
199
|
+
assetsDir: optionsAssetsDir,
|
|
200
|
+
clientEntry: optionsClientEntry,
|
|
201
|
+
serverOutDir: optionsServerOutDir,
|
|
202
|
+
clientOutDir: optionsClientOutDir,
|
|
203
|
+
autoDiscover: optionsAutoDiscover,
|
|
204
|
+
moduleBaseExceptions: optionsModuleBaseExceptions,
|
|
205
|
+
...restOptions
|
|
206
|
+
} = options;
|
|
207
|
+
const projectRoot = optionsProjectRoot ?? process.cwd();
|
|
165
208
|
/** the module base can be assumed to not have a leading slash */
|
|
166
209
|
const moduleBase =
|
|
167
|
-
typeof
|
|
168
|
-
?
|
|
169
|
-
?
|
|
170
|
-
:
|
|
210
|
+
typeof optionsModuleBase === "string"
|
|
211
|
+
? optionsModuleBase.startsWith(path.sep)
|
|
212
|
+
? optionsModuleBase.slice(path.sep.length)
|
|
213
|
+
: optionsModuleBase
|
|
171
214
|
: DEFAULT_CONFIG.MODULE_BASE;
|
|
172
215
|
|
|
173
216
|
if (
|
|
174
|
-
typeof
|
|
175
|
-
|
|
217
|
+
typeof optionsModuleBase === "string" &&
|
|
218
|
+
optionsModuleBase !== moduleBase
|
|
176
219
|
) {
|
|
177
220
|
return {
|
|
178
221
|
type: "error",
|
|
179
222
|
error: new Error(
|
|
180
|
-
`moduleBase ${
|
|
223
|
+
`moduleBase ${optionsModuleBase} is invalid, should be like ${moduleBase}`
|
|
181
224
|
),
|
|
182
225
|
};
|
|
183
226
|
}
|
|
184
227
|
|
|
185
228
|
const moduleBasePath =
|
|
186
|
-
typeof
|
|
187
|
-
? !
|
|
188
|
-
? `${path.sep}${
|
|
189
|
-
:
|
|
229
|
+
typeof optionsModuleBasePath === "string"
|
|
230
|
+
? !optionsModuleBasePath.startsWith(path.sep)
|
|
231
|
+
? `${path.sep}${optionsModuleBasePath}`
|
|
232
|
+
: optionsModuleBasePath
|
|
190
233
|
: `${path.sep}${moduleBase}`;
|
|
191
234
|
|
|
192
235
|
if (!moduleBasePath.includes(moduleBase)) {
|
|
@@ -199,10 +242,10 @@ export const resolveOptions = (
|
|
|
199
242
|
}
|
|
200
243
|
|
|
201
244
|
const moduleBaseURL =
|
|
202
|
-
typeof
|
|
203
|
-
? !
|
|
204
|
-
? path.join(
|
|
205
|
-
:
|
|
245
|
+
typeof optionsModuleBaseURL === "string"
|
|
246
|
+
? !optionsModuleBaseURL.endsWith(moduleBasePath)
|
|
247
|
+
? path.join(optionsModuleBaseURL, moduleBasePath)
|
|
248
|
+
: optionsModuleBaseURL
|
|
206
249
|
: moduleBasePath;
|
|
207
250
|
|
|
208
251
|
if (!moduleBaseURL.includes(moduleBasePath)) {
|
|
@@ -215,41 +258,70 @@ export const resolveOptions = (
|
|
|
215
258
|
}
|
|
216
259
|
|
|
217
260
|
if (
|
|
218
|
-
typeof
|
|
219
|
-
|
|
261
|
+
typeof optionsModuleBaseURL === "string" &&
|
|
262
|
+
optionsModuleBaseURL !== moduleBaseURL
|
|
220
263
|
) {
|
|
221
264
|
return {
|
|
222
265
|
type: "error",
|
|
223
266
|
error: new Error(
|
|
224
|
-
`moduleBaseURL ${
|
|
267
|
+
`moduleBaseURL ${optionsModuleBaseURL} is invalid, should be like ${moduleBaseURL}`
|
|
225
268
|
),
|
|
226
269
|
};
|
|
227
270
|
}
|
|
228
271
|
|
|
229
|
-
const build =
|
|
272
|
+
const build = optionsBuild
|
|
230
273
|
? {
|
|
231
|
-
client:
|
|
232
|
-
pages:
|
|
233
|
-
server:
|
|
274
|
+
client: optionsBuild.client ?? DEFAULT_CONFIG.BUILD.client,
|
|
275
|
+
pages: optionsBuild.pages ?? DEFAULT_CONFIG.BUILD.pages,
|
|
276
|
+
server: optionsBuild.server ?? DEFAULT_CONFIG.BUILD.server,
|
|
234
277
|
}
|
|
235
278
|
: DEFAULT_CONFIG.BUILD;
|
|
236
279
|
|
|
280
|
+
const autoDiscover =
|
|
281
|
+
typeof optionsAutoDiscover === "object"
|
|
282
|
+
? {
|
|
283
|
+
pagePattern:
|
|
284
|
+
typeof optionsAutoDiscover.pagePattern === "string"
|
|
285
|
+
? optionsAutoDiscover.pagePattern
|
|
286
|
+
: DEFAULT_CONFIG.AUTO_DISCOVER.pagePattern,
|
|
287
|
+
propsPattern:
|
|
288
|
+
typeof optionsAutoDiscover.propsPattern === "string"
|
|
289
|
+
? optionsAutoDiscover.propsPattern
|
|
290
|
+
: DEFAULT_CONFIG.AUTO_DISCOVER.propsPattern,
|
|
291
|
+
}
|
|
292
|
+
: DEFAULT_CONFIG.AUTO_DISCOVER;
|
|
293
|
+
|
|
294
|
+
const workerPath = typeof optionsWorkerPath === "string" ? optionsWorkerPath : DEFAULT_CONFIG.WORKER_PATH;
|
|
295
|
+
const loaderPath = typeof optionsLoaderPath === "string" ? optionsLoaderPath : DEFAULT_CONFIG.LOADER_PATH;
|
|
237
296
|
return {
|
|
238
297
|
type: "success",
|
|
239
298
|
userOptions: {
|
|
299
|
+
...DEFAULT_CONFIG,
|
|
300
|
+
...restOptions,
|
|
240
301
|
moduleBase,
|
|
241
302
|
moduleBasePath,
|
|
242
303
|
moduleBaseURL,
|
|
243
304
|
build,
|
|
244
|
-
Page:
|
|
245
|
-
props:
|
|
246
|
-
Html:
|
|
247
|
-
pageExportName:
|
|
248
|
-
propsExportName:
|
|
249
|
-
collectCss:
|
|
250
|
-
collectAssets:
|
|
305
|
+
Page: optionsPage ?? DEFAULT_CONFIG.PAGE,
|
|
306
|
+
props: optionsProps ?? DEFAULT_CONFIG.PROPS,
|
|
307
|
+
Html: optionsHtml ?? DEFAULT_CONFIG.HTML,
|
|
308
|
+
pageExportName: optionsPageExportName ?? DEFAULT_CONFIG.PAGE_EXPORT,
|
|
309
|
+
propsExportName: optionsPropsExportName ?? DEFAULT_CONFIG.PROPS_EXPORT,
|
|
310
|
+
collectCss: optionsCollectCss ?? DEFAULT_CONFIG.COLLECT_CSS,
|
|
311
|
+
collectAssets: optionsCollectAssets ?? DEFAULT_CONFIG.COLLECT_ASSETS,
|
|
251
312
|
projectRoot: projectRoot,
|
|
252
|
-
assetsDir:
|
|
313
|
+
assetsDir: optionsAssetsDir ?? DEFAULT_CONFIG.CLIENT_ASSETS_DIR,
|
|
314
|
+
workerPath: workerPath,
|
|
315
|
+
loaderPath: loaderPath,
|
|
316
|
+
clientEntry: optionsClientEntry ?? DEFAULT_CONFIG.CLIENT_ENTRY,
|
|
317
|
+
serverOutDir: optionsServerOutDir ?? DEFAULT_CONFIG.BUILD.server,
|
|
318
|
+
clientOutDir: optionsClientOutDir ?? DEFAULT_CONFIG.BUILD.client,
|
|
319
|
+
autoDiscover: autoDiscover,
|
|
320
|
+
moduleBaseExceptions: [
|
|
321
|
+
workerPath,
|
|
322
|
+
loaderPath,
|
|
323
|
+
...(optionsModuleBaseExceptions ?? []),
|
|
324
|
+
],
|
|
253
325
|
} satisfies ResolvedUserOptions,
|
|
254
326
|
};
|
|
255
327
|
};
|
package/src/plugin.ts
CHANGED
|
@@ -1,31 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { preserveDirectives } from "./transformer/preserveDirectives.js";
|
|
4
|
-
import type { StreamPluginOptions } from "./types.js";
|
|
1
|
+
import "./assertServerCondition.js";
|
|
2
|
+
export { reactStreamPlugin } from "./react-server/plugin.js";
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return nodeOptions?.match(/--conditions=react-server/) ? "server" : "client";
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const reactStreamPlugin = async (options: StreamPluginOptions) => {
|
|
12
|
-
const condition = getCondition();
|
|
13
|
-
try {
|
|
14
|
-
const resolvedOptions = resolveOptions(options);
|
|
15
|
-
if (resolvedOptions.type === "error") {
|
|
16
|
-
throw resolvedOptions.error;
|
|
17
|
-
}
|
|
18
|
-
options = resolvedOptions.userOptions;
|
|
19
|
-
} catch (error) {
|
|
20
|
-
throw new Error(
|
|
21
|
-
`[vite:react-stream:${condition}] ${(error as Error).message}`
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
return condition === "server"
|
|
25
|
-
? [
|
|
26
|
-
(await import(`./react-server/plugin.js`)).reactStreamPlugin(options),
|
|
27
|
-
viteReactClientTransformPlugin(),
|
|
28
|
-
preserveDirectives(),
|
|
29
|
-
]
|
|
30
|
-
: [(await import(`./react-client/plugin.js`)).reactStreamPlugin(options)];
|
|
31
|
-
};
|
|
4
|
+
// the main plugin is version is the server version, if you want the client version, use the `vite-plugin-react-server/client` import
|
|
5
|
+
// this is because the workflow assumes main thread = react server condition
|
|
@@ -30,7 +30,7 @@ export function createSsrHandler(
|
|
|
30
30
|
const worker = new Worker(
|
|
31
31
|
options?.workerPath
|
|
32
32
|
? resolve(server.config.root, options?.workerPath)
|
|
33
|
-
:
|
|
33
|
+
: DEFAULT_CONFIG.WORKER_PATH,
|
|
34
34
|
{
|
|
35
35
|
env: {
|
|
36
36
|
NODE_OPTIONS: "--conditions ''",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import type { ServerResponse } from "node:http";
|
|
3
|
-
import { resolve as resolvePath } from "node:path";
|
|
3
|
+
import { join, relative, resolve, resolve as resolvePath } from "node:path";
|
|
4
4
|
import { performance } from "node:perf_hooks";
|
|
5
5
|
import { Worker } from "node:worker_threads";
|
|
6
6
|
import type { Plugin as RollupPlugin } from "rollup";
|
|
@@ -21,15 +21,18 @@ import type { BuildTiming, ReactStreamPluginMeta } from "../types.js";
|
|
|
21
21
|
import { type StreamPluginOptions } from "../types.js";
|
|
22
22
|
import { createWorker } from "../worker/createWorker.js";
|
|
23
23
|
import { createHandler } from "./createHandler.js";
|
|
24
|
+
import { tryManifest } from "../helpers/tryManifest.js";
|
|
25
|
+
import { createNormalizedRelativePath } from "../helpers/normalizedRelativePath.js";
|
|
24
26
|
|
|
25
|
-
let
|
|
26
|
-
let
|
|
27
|
+
let files: Awaited<ReturnType<typeof checkFilesExist>>;
|
|
28
|
+
let env: Awaited<ReturnType<typeof getEnv>>;
|
|
27
29
|
let worker: Worker;
|
|
28
30
|
let config: ResolvedConfig;
|
|
29
31
|
let cssModules = new Set<string>();
|
|
30
32
|
let clientComponents = new Map<string, string>();
|
|
31
33
|
let define: Record<string, string>;
|
|
32
34
|
let buildCssFiles = new Set<string>();
|
|
35
|
+
let root: string = process.cwd();
|
|
33
36
|
|
|
34
37
|
interface BuildStats {
|
|
35
38
|
htmlFiles: number;
|
|
@@ -127,7 +130,7 @@ export async function reactStreamPlugin(
|
|
|
127
130
|
propsExportName: userOptions.propsExportName,
|
|
128
131
|
moduleBase: userOptions.moduleBase,
|
|
129
132
|
moduleBasePath: userOptions.moduleBasePath,
|
|
130
|
-
projectRoot: server.config.root,
|
|
133
|
+
projectRoot: server.config.root ?? userOptions.projectRoot,
|
|
131
134
|
},
|
|
132
135
|
{
|
|
133
136
|
cssFiles: Array.from(cssModules),
|
|
@@ -148,39 +151,70 @@ export async function reactStreamPlugin(
|
|
|
148
151
|
|
|
149
152
|
async config(config, configEnv): Promise<UserConfig> {
|
|
150
153
|
const resolvedPages = await resolvePages(userOptions.build.pages);
|
|
151
|
-
if(resolvedPages.type ===
|
|
154
|
+
if (resolvedPages.type === "error") {
|
|
152
155
|
throw resolvedPages.error;
|
|
153
156
|
}
|
|
154
157
|
const { pages } = resolvedPages;
|
|
158
|
+
env = getEnv(config, configEnv);
|
|
159
|
+
define = env.define;
|
|
160
|
+
files = await checkFilesExist(
|
|
161
|
+
pages,
|
|
162
|
+
userOptions,
|
|
163
|
+
config.root ?? userOptions.projectRoot
|
|
164
|
+
);
|
|
165
|
+
root = config.root ?? userOptions.projectRoot;
|
|
155
166
|
const resolvedConfig = resolveUserConfig(
|
|
156
167
|
"react-server",
|
|
157
|
-
pages,
|
|
168
|
+
[...pages, userOptions.workerPath, userOptions.loaderPath],
|
|
158
169
|
config,
|
|
159
170
|
configEnv,
|
|
160
171
|
userOptions
|
|
161
172
|
);
|
|
162
|
-
if(resolvedConfig.type === "error") {
|
|
173
|
+
if (resolvedConfig.type === "error") {
|
|
163
174
|
throw resolvedConfig.error;
|
|
164
175
|
}
|
|
165
176
|
const { userConfig } = resolvedConfig;
|
|
177
|
+
console.log({
|
|
178
|
+
worker: userOptions.workerPath,
|
|
179
|
+
loader: userOptions.loaderPath,
|
|
180
|
+
});
|
|
181
|
+
const entriesClient = Object.fromEntries([
|
|
182
|
+
...Array.from(files.pageMap.entries()).map(([key, value]) => [
|
|
183
|
+
key,
|
|
184
|
+
relative(root, value),
|
|
185
|
+
]),
|
|
186
|
+
...Array.from(files.propsMap.entries()).map(([key, value]) => [
|
|
187
|
+
key,
|
|
188
|
+
relative(root, value),
|
|
189
|
+
]),
|
|
190
|
+
]);
|
|
191
|
+
const entriesResolved = Object.fromEntries(
|
|
192
|
+
(Object.entries(entriesClient) as [string, string][]).map(
|
|
193
|
+
([key, entry]) => {
|
|
194
|
+
if (typeof entry !== "string") {
|
|
195
|
+
return [key, entry];
|
|
196
|
+
}
|
|
166
197
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
pageMap = files.pageMap;
|
|
171
|
-
define = envResult.define;
|
|
172
|
-
const entries = Array.from(
|
|
173
|
-
new Set([
|
|
174
|
-
...Array.from(files.pageSet.values()),
|
|
175
|
-
...Array.from(files.propsSet.values()),
|
|
176
|
-
]).values()
|
|
198
|
+
return [key, entry];
|
|
199
|
+
}
|
|
200
|
+
)
|
|
177
201
|
);
|
|
202
|
+
const serverEntries = {
|
|
203
|
+
...entriesResolved,
|
|
204
|
+
["worker/worker"]: userOptions.workerPath,
|
|
205
|
+
["worker/loader"]: userOptions.loaderPath,
|
|
206
|
+
};
|
|
178
207
|
|
|
179
208
|
const buildConfig = createBuildConfig({
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
209
|
+
input: serverEntries,
|
|
210
|
+
userConfig: userConfig,
|
|
211
|
+
userOptions: userOptions,
|
|
212
|
+
root,
|
|
213
|
+
moduleBaseExceptions: [
|
|
214
|
+
userOptions.workerPath,
|
|
215
|
+
userOptions.loaderPath,
|
|
216
|
+
...userOptions.moduleBaseExceptions,
|
|
217
|
+
],
|
|
184
218
|
});
|
|
185
219
|
return {
|
|
186
220
|
...buildConfig,
|
|
@@ -192,44 +226,70 @@ export async function reactStreamPlugin(
|
|
|
192
226
|
timing.buildStart = performance.now();
|
|
193
227
|
},
|
|
194
228
|
async closeBundle() {
|
|
195
|
-
if(!config) return;
|
|
229
|
+
if (!config) return;
|
|
196
230
|
console.log("RSC CLOSE BUNDLE CALLED");
|
|
197
|
-
if (!pageSet
|
|
231
|
+
if (!files.pageSet.size) return;
|
|
198
232
|
timing.renderStart = performance.now();
|
|
199
233
|
|
|
200
234
|
try {
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
235
|
+
const resolvedServerManifest = tryManifest({
|
|
236
|
+
root,
|
|
237
|
+
outDir: userOptions.build.server,
|
|
238
|
+
ssrManifest: false,
|
|
239
|
+
});
|
|
240
|
+
if (resolvedServerManifest.type === "error") {
|
|
241
|
+
console.error(
|
|
242
|
+
"[vite-react-stream] Server Build failed, can not build without a server manifest. Please set `manifest: true` in your vite config.",
|
|
243
|
+
resolvedServerManifest.error
|
|
244
|
+
);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const { manifest: serverManifest } = resolvedServerManifest;
|
|
248
|
+
|
|
249
|
+
// get worker path from server manifest
|
|
250
|
+
const workerPath =
|
|
251
|
+
serverManifest[userOptions.workerPath]?.file ??
|
|
252
|
+
serverManifest[relative(root, userOptions.workerPath)]?.file ??
|
|
253
|
+
serverManifest[
|
|
254
|
+
relative(
|
|
255
|
+
join(root, userOptions.build.server),
|
|
256
|
+
userOptions.workerPath
|
|
257
|
+
)
|
|
258
|
+
]?.file;
|
|
259
|
+
if (!workerPath) {
|
|
260
|
+
console.log(serverManifest, userOptions.build.server);
|
|
261
|
+
throw new Error(
|
|
262
|
+
`Worker path not found in server manifest, tried: ${userOptions.workerPath}, ${relative(root, userOptions.workerPath)}, ${join(root, userOptions.build.server, userOptions.workerPath)}`
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
console.log("workerPath", workerPath);
|
|
266
|
+
// client
|
|
267
|
+
const resolvedClientManifest = tryManifest({
|
|
268
|
+
root,
|
|
269
|
+
outDir: userOptions.build.client,
|
|
270
|
+
ssrManifest: false,
|
|
271
|
+
});
|
|
272
|
+
if (resolvedClientManifest.type === "error") {
|
|
273
|
+
console.error(
|
|
274
|
+
"[vite-react-stream] Server Build failed, can not build without a client manifest. Make sure to run the client build before the server build and set `manifest: true` in your vite config.",
|
|
275
|
+
resolvedClientManifest.error
|
|
276
|
+
);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const { manifest: clientManifest } = resolvedClientManifest;
|
|
280
|
+
|
|
223
281
|
// Create a single worker for all routes
|
|
224
282
|
if (!worker)
|
|
225
|
-
worker = await createWorker(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
283
|
+
worker = await createWorker({
|
|
284
|
+
workerPath: join(root, userOptions.build.server, workerPath),
|
|
285
|
+
nodePath: process.env["NODE_PATH"] ?? resolve(root, "node_modules"),
|
|
286
|
+
mode:
|
|
287
|
+
process.env["NODE_ENV"] === "development"
|
|
288
|
+
? "development"
|
|
289
|
+
: "production",
|
|
290
|
+
});
|
|
231
291
|
// this is based on the user config - the routes should lead to a page and props but the rendering is agnostic of that
|
|
232
|
-
const routes = Array.from(pageMap.keys());
|
|
292
|
+
const routes = Array.from(files.pageMap.keys());
|
|
233
293
|
const indexEntry = clientManifest["index.html"];
|
|
234
294
|
if (!indexEntry) {
|
|
235
295
|
throw new Error("root /index.html not found");
|
|
@@ -250,19 +310,19 @@ export async function reactStreamPlugin(
|
|
|
250
310
|
moduleBase: userOptions.moduleBase,
|
|
251
311
|
moduleBasePath: userOptions.moduleBasePath,
|
|
252
312
|
moduleBaseURL: userOptions.moduleBaseURL,
|
|
253
|
-
projectRoot:
|
|
313
|
+
projectRoot: root,
|
|
254
314
|
},
|
|
255
315
|
worker: worker,
|
|
256
|
-
manifest: clientManifest
|
|
316
|
+
manifest: clientManifest,
|
|
257
317
|
loader: createPageLoader({
|
|
258
|
-
manifest,
|
|
318
|
+
manifest: clientManifest,
|
|
259
319
|
root: config.root,
|
|
260
320
|
outDir: config.build.outDir,
|
|
261
321
|
moduleBase: userOptions.moduleBase,
|
|
262
322
|
alwaysRegisterServer: false,
|
|
263
323
|
alwaysRegisterClient: false,
|
|
264
324
|
registerServer: [],
|
|
265
|
-
registerClient: Object.keys(
|
|
325
|
+
registerClient: Object.keys(resolvedClientManifest).filter(
|
|
266
326
|
(key) =>
|
|
267
327
|
key.endsWith(".client.tsx") && clientManifest[key].isEntry
|
|
268
328
|
),
|
package/src/types.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AliasOptions,
|
|
3
|
+
BuildOptions,
|
|
3
4
|
Connect,
|
|
4
5
|
Logger,
|
|
5
6
|
Manifest,
|
|
6
7
|
ModuleGraph,
|
|
8
|
+
UserConfig,
|
|
7
9
|
ViteDevServer,
|
|
8
10
|
} from "vite";
|
|
9
11
|
|
|
@@ -35,8 +37,23 @@ export type ResolvedUserOptions = Required<
|
|
|
35
37
|
| "collectCss"
|
|
36
38
|
| "collectAssets"
|
|
37
39
|
| "assetsDir"
|
|
40
|
+
| "workerPath"
|
|
41
|
+
| "loaderPath"
|
|
42
|
+
| "clientEntry"
|
|
43
|
+
| "serverOutDir"
|
|
44
|
+
| "clientOutDir"
|
|
45
|
+
| "moduleBaseExceptions"
|
|
38
46
|
>
|
|
39
|
-
> & {
|
|
47
|
+
> & {
|
|
48
|
+
build: NonNullable<Required<StreamPluginOptions["build"]>>;
|
|
49
|
+
autoDiscover: NonNullable<Required<StreamPluginOptions["autoDiscover"]>>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type ResolvedUserConfig = Required<Pick<UserConfig, "root" | "mode">> &
|
|
53
|
+
Omit<UserConfig, "root" | "mode" | "build"> & {
|
|
54
|
+
build: Required<Pick<BuildOptions, "target" | "outDir" | "assetsDir" | "ssr" | "ssrEmitAssets" | "ssrManifest" | "manifest">> &
|
|
55
|
+
Partial<Omit<BuildOptions, "target" | "outDir" | "assetsDir" | "ssr" | "ssrEmitAssets" | "ssrManifest" | "manifest">>;
|
|
56
|
+
};
|
|
40
57
|
|
|
41
58
|
export interface StreamPluginOptions {
|
|
42
59
|
projectRoot?: string;
|
|
@@ -70,6 +87,7 @@ export interface StreamPluginOptions {
|
|
|
70
87
|
collectCss?: boolean;
|
|
71
88
|
collectAssets?: boolean;
|
|
72
89
|
build?: BuildConfig;
|
|
90
|
+
moduleBaseExceptions?: string[];
|
|
73
91
|
}
|
|
74
92
|
|
|
75
93
|
export interface CreateHandlerOptions<T = any> {
|
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { join } from "node:path";
|
|
2
2
|
import { Worker } from "node:worker_threads";
|
|
3
3
|
|
|
4
|
+
type CreateWorkerOptions = {
|
|
5
|
+
workerPath: string;
|
|
6
|
+
nodePath: string;
|
|
7
|
+
mode: "production" | "development";
|
|
8
|
+
workerOptions?: WorkerOptions;
|
|
9
|
+
};
|
|
10
|
+
|
|
4
11
|
export async function createWorker(
|
|
5
|
-
|
|
6
|
-
outDir: string,
|
|
7
|
-
fileName: string,
|
|
8
|
-
mode: "production" | "development"
|
|
12
|
+
options: CreateWorkerOptions
|
|
9
13
|
) {
|
|
14
|
+
const { workerPath, nodePath, mode, workerOptions } = options;
|
|
10
15
|
console.log("[Worker] Creating worker...");
|
|
11
|
-
const workerPath = resolve(projectRoot, outDir, fileName);
|
|
12
16
|
console.log("[Worker] Worker path:", workerPath);
|
|
13
17
|
|
|
14
18
|
try {
|
|
15
19
|
const worker = new Worker(workerPath, {
|
|
16
20
|
env: {
|
|
17
21
|
NODE_OPTIONS: "",
|
|
18
|
-
NODE_PATH: resolve(projectRoot, "node_modules"),
|
|
19
22
|
NODE_ENV: mode,
|
|
23
|
+
NODE_PATH: nodePath,
|
|
20
24
|
},
|
|
25
|
+
...workerOptions,
|
|
21
26
|
});
|
|
22
27
|
worker.setMaxListeners(1000);
|
|
23
28
|
|