vite-plugin-react-server 0.3.19 → 1.0.0
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 +219 -141
- package/dist/package.json +13 -6
- package/dist/plugin/collect-manifest-client-files.d.ts.map +1 -1
- package/dist/plugin/collect-manifest-client-files.js +25 -11
- package/dist/plugin/collect-manifest-client-files.js.map +1 -1
- package/dist/plugin/components.d.ts +3 -13
- package/dist/plugin/components.d.ts.map +1 -1
- package/dist/plugin/components.js +3 -54
- package/dist/plugin/config/defaults.d.ts +9 -2
- package/dist/plugin/config/defaults.d.ts.map +1 -1
- package/dist/plugin/config/defaults.js +3 -2
- package/dist/plugin/config/defaults.js.map +1 -1
- package/dist/plugin/config/resolveOptions.d.ts +2 -2
- package/dist/plugin/config/resolveOptions.d.ts.map +1 -1
- package/dist/plugin/config/resolveOptions.js +6 -0
- package/dist/plugin/config/resolveOptions.js.map +1 -1
- package/dist/plugin/config/resolveUserConfig.d.ts.map +1 -1
- package/dist/plugin/config/resolveUserConfig.js +178 -149
- package/dist/plugin/config/resolveUserConfig.js.map +1 -1
- package/dist/plugin/css-collector-inline.d.ts +10 -0
- package/dist/plugin/css-collector-inline.d.ts.map +1 -0
- package/dist/plugin/css-collector-inline.js +55 -0
- package/dist/plugin/css-collector-inline.js.map +1 -0
- package/dist/plugin/css-collector.d.ts +14 -0
- package/dist/plugin/css-collector.d.ts.map +1 -0
- package/dist/plugin/css-collector.js +49 -0
- package/dist/plugin/css-collector.js.map +1 -0
- package/dist/plugin/helpers/createHandler.d.ts +3 -8
- package/dist/plugin/helpers/createHandler.d.ts.map +1 -1
- package/dist/plugin/helpers/createHandler.js +52 -55
- package/dist/plugin/helpers/createHandler.js.map +1 -1
- package/dist/plugin/helpers/createRscStream.d.ts +14 -4
- package/dist/plugin/helpers/createRscStream.d.ts.map +1 -1
- package/dist/plugin/helpers/createRscStream.js +25 -16
- package/dist/plugin/helpers/createRscStream.js.map +1 -1
- package/dist/plugin/html.d.ts +5 -0
- package/dist/plugin/html.d.ts.map +1 -0
- package/dist/plugin/html.js +11 -0
- package/dist/plugin/html.js.map +1 -0
- package/dist/plugin/react-client/plugin.d.ts.map +1 -1
- package/dist/plugin/react-client/plugin.js +3 -2
- package/dist/plugin/react-client/plugin.js.map +1 -1
- package/dist/plugin/react-server/plugin.d.ts.map +1 -1
- package/dist/plugin/react-server/plugin.js +47 -16
- package/dist/plugin/react-server/plugin.js.map +1 -1
- package/dist/plugin/react-static/plugin.d.ts.map +1 -1
- package/dist/plugin/react-static/plugin.js +20 -12
- package/dist/plugin/react-static/plugin.js.map +1 -1
- package/dist/plugin/react-static/types.d.ts +2 -0
- package/dist/plugin/react-static/types.d.ts.map +1 -0
- package/dist/plugin/react-static/types.js +1 -0
- package/dist/plugin/types.d.ts +48 -11
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/plugin/worker/html/messageHandler.d.ts.map +1 -1
- package/dist/plugin/worker/html/messageHandler.js +4 -1
- package/dist/plugin/worker/html/messageHandler.js.map +1 -1
- package/dist/plugin/worker/html/renderPages.d.ts +8 -25
- package/dist/plugin/worker/html/renderPages.d.ts.map +1 -1
- package/dist/plugin/worker/html/renderPages.js +61 -44
- package/dist/plugin/worker/html/renderPages.js.map +1 -1
- package/dist/plugin/worker/rsc/messageHandler.d.ts.map +1 -1
- package/dist/plugin/worker/rsc/messageHandler.js +37 -22
- package/dist/plugin/worker/rsc/messageHandler.js.map +1 -1
- package/dist/plugin/worker/types.d.ts +3 -0
- package/dist/plugin/worker/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -4
- package/plugin/collect-manifest-client-files.ts +25 -10
- package/plugin/components.ts +3 -0
- package/plugin/config/defaults.tsx +10 -9
- package/plugin/config/resolveOptions.ts +10 -5
- package/plugin/config/resolveUserConfig.ts +218 -177
- package/plugin/css-collector-inline.tsx +60 -0
- package/plugin/css-collector.tsx +62 -0
- package/plugin/helpers/createHandler.ts +73 -83
- package/plugin/helpers/createRscStream.ts +49 -21
- package/plugin/html.tsx +9 -0
- package/plugin/react-client/plugin.ts +3 -2
- package/plugin/react-server/plugin.ts +58 -22
- package/plugin/react-static/plugin.ts +20 -11
- package/plugin/react-static/types.ts +3 -0
- package/plugin/types.ts +53 -11
- package/plugin/worker/html/messageHandler.ts +5 -2
- package/plugin/worker/html/renderPages.ts +82 -78
- package/plugin/worker/rsc/messageHandler.tsx +41 -26
- package/plugin/worker/types.ts +3 -0
- package/dist/plugin/components.js.map +0 -1
- package/dist/plugin/getEnv.d.ts +0 -19
- package/dist/plugin/getEnv.d.ts.map +0 -1
- package/dist/plugin/getEnv.js +0 -107
- package/dist/plugin/module-graph.d.ts +0 -10
- package/dist/plugin/module-graph.d.ts.map +0 -1
- package/dist/plugin/module-graph.js +0 -35
- package/dist/plugin/worker/html/plugin.d.ts +0 -4
- package/dist/plugin/worker/html/plugin.d.ts.map +0 -1
- package/dist/plugin/worker/html/plugin.js +0 -93
- package/dist/plugin/worker/plugin.d.ts +0 -19
- package/dist/plugin/worker/plugin.d.ts.map +0 -1
- package/dist/plugin/worker/plugin.js +0 -23
- package/dist/plugin/worker/rsc/plugin.d.ts +0 -4
- package/dist/plugin/worker/rsc/plugin.d.ts.map +0 -1
- package/dist/plugin/worker/rsc/plugin.js +0 -75
- package/plugin/components.tsx +0 -59
- package/plugin/getEnv.ts +0 -135
- package/plugin/module-graph.ts +0 -48
- package/plugin/worker/html/plugin.ts +0 -100
- package/plugin/worker/plugin.ts +0 -26
- package/plugin/worker/rsc/plugin.ts +0 -83
|
@@ -1,79 +1,58 @@
|
|
|
1
1
|
import type { PipeableStream } from "react-dom/server";
|
|
2
|
-
import { createLogger } from "vite";
|
|
3
|
-
import {
|
|
4
|
-
collectManifestClientFiles,
|
|
5
|
-
collectModuleGraphCss,
|
|
6
|
-
} from "../collect-manifest-client-files.js";
|
|
7
|
-
import { DEFAULT_CONFIG } from "../config/defaults.js";
|
|
8
2
|
import { resolvePage } from "../resolvePage.js";
|
|
9
3
|
import { resolveProps } from "../resolveProps.js";
|
|
10
|
-
import type {
|
|
4
|
+
import type { CreateHandlerOptions, CssContent } from "../types.js";
|
|
11
5
|
import { createRscStream } from "./createRscStream.js";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
type CreateHandlerResult =
|
|
7
|
+
| {
|
|
8
|
+
type: "success";
|
|
9
|
+
controller: AbortController;
|
|
10
|
+
stream: PipeableStream;
|
|
11
|
+
assets: any;
|
|
12
|
+
route: string;
|
|
13
|
+
}
|
|
15
14
|
| { type: "error"; error: Error }
|
|
16
15
|
| { type: "skip" };
|
|
17
16
|
|
|
18
17
|
interface HandlerAssets {
|
|
19
|
-
css: string[];
|
|
18
|
+
css: (string | CssContent)[];
|
|
20
19
|
bootstrapModules: string[];
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
export async function createHandler<T>({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
23
|
+
getCss,
|
|
24
|
+
root,
|
|
25
|
+
cssFiles = [],
|
|
26
|
+
cssModules = new Map<string, string | CssContent>(),
|
|
27
|
+
onCssFile,
|
|
28
|
+
logger,
|
|
29
|
+
loader,
|
|
30
|
+
Html,
|
|
31
|
+
CssCollector,
|
|
32
|
+
pagePath,
|
|
33
|
+
propsPath,
|
|
34
|
+
pageExportName,
|
|
35
|
+
propsExportName,
|
|
36
|
+
inlineCss,
|
|
37
|
+
moduleBase,
|
|
38
|
+
preserveModulesRoot: _preserveModulesRoot,
|
|
39
|
+
moduleBasePath,
|
|
40
|
+
moduleRootPath,
|
|
41
|
+
moduleBaseURL,
|
|
42
|
+
route,
|
|
43
|
+
pipableStreamOptions,
|
|
44
|
+
}: CreateHandlerOptions<T>): Promise<CreateHandlerResult> {
|
|
41
45
|
const controller = new AbortController();
|
|
42
46
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const cssModules = streamOptions.cssModules ?? new Set<string>();
|
|
47
|
-
|
|
48
|
-
if (!(streamOptions.serverManifest || streamOptions.moduleGraph))
|
|
49
|
-
throw new Error("Missing server manifest or moduleGraph, pass it to options.");
|
|
50
|
-
|
|
51
|
-
const getCss = streamOptions.serverManifest
|
|
52
|
-
? (id: string) =>
|
|
53
|
-
collectManifestClientFiles({
|
|
54
|
-
manifest: streamOptions.serverManifest!,
|
|
55
|
-
root: root,
|
|
56
|
-
pagePath: id,
|
|
57
|
-
onCss: streamOptions.onCssFile,
|
|
58
|
-
moduleBase: pluginOptions.moduleBase,
|
|
59
|
-
preserveModulesRoot: pluginOptions.build.preserveModulesRoot,
|
|
60
|
-
}).cssFiles
|
|
61
|
-
: (id: string) =>
|
|
62
|
-
collectModuleGraphCss({
|
|
63
|
-
moduleGraph: streamOptions.moduleGraph!,
|
|
64
|
-
pagePath: id,
|
|
65
|
-
onCss: streamOptions.onCssFile,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const loadWithCss = async (id: string, parentUrl: string) => {
|
|
47
|
+
const loadWithCss = async (id: string) => {
|
|
69
48
|
try {
|
|
70
|
-
const mod = await
|
|
49
|
+
const mod = await loader(id);
|
|
71
50
|
const pageCss = await Promise.resolve(getCss(id));
|
|
72
|
-
Array.from(pageCss.
|
|
73
|
-
cssModules.
|
|
51
|
+
Array.from(pageCss.entries()).forEach(([css, linkOrContent]) => {
|
|
52
|
+
cssModules.set(css, linkOrContent);
|
|
74
53
|
// Notify about new CSS file if callback exists
|
|
75
|
-
if (
|
|
76
|
-
|
|
54
|
+
if (typeof onCssFile === "function") {
|
|
55
|
+
onCssFile(css, id);
|
|
77
56
|
}
|
|
78
57
|
});
|
|
79
58
|
return mod as Record<string, any>;
|
|
@@ -87,44 +66,55 @@ export async function createHandler<T>({
|
|
|
87
66
|
};
|
|
88
67
|
|
|
89
68
|
const PropsModule = await resolveProps({
|
|
90
|
-
propsModule:
|
|
91
|
-
|
|
69
|
+
propsModule: propsPath
|
|
70
|
+
? await loadWithCss(propsPath)
|
|
71
|
+
: { [propsExportName]: (url: string) => ({url}) },
|
|
72
|
+
path: String(propsPath),
|
|
92
73
|
exportName: propsExportName,
|
|
93
|
-
url,
|
|
74
|
+
url: route,
|
|
94
75
|
});
|
|
95
76
|
if (PropsModule.type !== "success") {
|
|
96
|
-
return PropsModule
|
|
77
|
+
return PropsModule;
|
|
97
78
|
}
|
|
98
79
|
const PageModule = await resolvePage({
|
|
99
|
-
pageModule:
|
|
100
|
-
|
|
80
|
+
pageModule: pagePath
|
|
81
|
+
? await loadWithCss(pagePath)
|
|
82
|
+
: { [pageExportName]: () => null },
|
|
83
|
+
path: String(pagePath),
|
|
101
84
|
exportName: pageExportName,
|
|
102
|
-
url,
|
|
85
|
+
url: route,
|
|
103
86
|
});
|
|
104
87
|
if (PageModule.type !== "success") {
|
|
105
|
-
return PageModule
|
|
88
|
+
return PageModule;
|
|
106
89
|
}
|
|
107
90
|
|
|
108
91
|
// Add any additional CSS files
|
|
109
|
-
if (
|
|
110
|
-
|
|
92
|
+
if (cssFiles) {
|
|
93
|
+
cssFiles.forEach((css) => cssModules.set(typeof css === "string" ? css : css.path, css));
|
|
94
|
+
cssFiles = Array.from(cssModules.values());
|
|
111
95
|
}
|
|
96
|
+
const url =
|
|
97
|
+
typeof moduleBaseURL === "string" && moduleBaseURL !== ""
|
|
98
|
+
? new URL(route, moduleBaseURL).href
|
|
99
|
+
: route;
|
|
112
100
|
const stream = createRscStream({
|
|
113
101
|
Html: Html,
|
|
102
|
+
CssCollector: CssCollector,
|
|
114
103
|
Page: PageModule[pageExportName as keyof typeof PageModule],
|
|
115
104
|
props: PropsModule[propsExportName as keyof typeof PropsModule],
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
105
|
+
moduleBase: moduleBase,
|
|
106
|
+
moduleRootPath: moduleRootPath,
|
|
107
|
+
moduleBasePath: moduleBasePath,
|
|
108
|
+
moduleBaseURL: moduleBaseURL,
|
|
109
|
+
logger: logger,
|
|
110
|
+
cssFiles: Array.from(cssModules.values()),
|
|
111
|
+
route,
|
|
121
112
|
url,
|
|
122
|
-
pipableStreamOptions:
|
|
123
|
-
htmlProps: {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
},
|
|
113
|
+
pipableStreamOptions: pipableStreamOptions,
|
|
114
|
+
htmlProps: {},
|
|
115
|
+
root: root,
|
|
116
|
+
loader: loader,
|
|
117
|
+
inlineCss: inlineCss,
|
|
128
118
|
});
|
|
129
119
|
|
|
130
120
|
if (!stream) {
|
|
@@ -132,14 +122,14 @@ export async function createHandler<T>({
|
|
|
132
122
|
}
|
|
133
123
|
|
|
134
124
|
const assets: HandlerAssets = {
|
|
135
|
-
css:
|
|
136
|
-
bootstrapModules:
|
|
125
|
+
css: cssFiles,
|
|
126
|
+
bootstrapModules: pipableStreamOptions?.bootstrapModules ?? [],
|
|
137
127
|
};
|
|
138
128
|
return {
|
|
139
129
|
type: "success",
|
|
140
130
|
controller,
|
|
141
131
|
stream,
|
|
142
132
|
assets,
|
|
143
|
-
|
|
133
|
+
route: route,
|
|
144
134
|
};
|
|
145
135
|
}
|
|
@@ -3,12 +3,19 @@ import * as React from "react";
|
|
|
3
3
|
import { renderToPipeableStream } from "react-server-dom-esm/server.node";
|
|
4
4
|
import type { PipeableStreamOptions } from "../worker/types.js";
|
|
5
5
|
import type { Logger } from "vite";
|
|
6
|
-
import {
|
|
6
|
+
import type {
|
|
7
|
+
CreateHandlerOptions,
|
|
8
|
+
CssCollectorProps,
|
|
9
|
+
CssContent,
|
|
10
|
+
InlineCssCollectorProps,
|
|
11
|
+
} from "../types.js";
|
|
7
12
|
|
|
8
|
-
export function createRscStream({
|
|
13
|
+
export function createRscStream<InlineCSS extends boolean = true>({
|
|
9
14
|
Html,
|
|
10
15
|
Page,
|
|
11
16
|
props,
|
|
17
|
+
loader = (id) => import(id).then((m) => m.default),
|
|
18
|
+
moduleRootPath,
|
|
12
19
|
moduleBasePath,
|
|
13
20
|
moduleBaseURL,
|
|
14
21
|
logger,
|
|
@@ -17,30 +24,47 @@ export function createRscStream({
|
|
|
17
24
|
url,
|
|
18
25
|
pipableStreamOptions,
|
|
19
26
|
htmlProps,
|
|
27
|
+
inlineCss = true as InlineCSS,
|
|
28
|
+
CssCollector,
|
|
29
|
+
root,
|
|
20
30
|
}: {
|
|
21
|
-
Html:
|
|
31
|
+
Html: CreateHandlerOptions["Html"];
|
|
22
32
|
Page: React.ComponentType<any>;
|
|
33
|
+
loader: (id: string) => Promise<any>;
|
|
23
34
|
props: any;
|
|
35
|
+
moduleBase: string;
|
|
36
|
+
moduleRootPath: string;
|
|
24
37
|
moduleBasePath: string;
|
|
25
38
|
moduleBaseURL: string;
|
|
26
39
|
logger: Logger;
|
|
27
|
-
cssFiles?: string[];
|
|
28
40
|
route: string;
|
|
29
41
|
url: string;
|
|
30
42
|
pipableStreamOptions?: PipeableStreamOptions;
|
|
31
43
|
htmlProps?: any;
|
|
32
|
-
|
|
44
|
+
root: string;
|
|
45
|
+
inlineCss?: InlineCSS;
|
|
46
|
+
cssFiles?: (string | CssContent)[];
|
|
47
|
+
} & (InlineCSS extends true
|
|
48
|
+
? {
|
|
49
|
+
CssCollector: React.FC<InlineCssCollectorProps>;
|
|
50
|
+
}
|
|
51
|
+
: {
|
|
52
|
+
CssCollector: React.FC<CssCollectorProps>;
|
|
53
|
+
})) {
|
|
33
54
|
const htmlIsFragment = Html == React.Fragment;
|
|
34
55
|
if (!htmlIsFragment) {
|
|
35
56
|
if (!htmlProps) {
|
|
36
57
|
htmlProps = {};
|
|
37
58
|
}
|
|
38
|
-
if(!("
|
|
39
|
-
htmlProps["
|
|
59
|
+
if (!("moduleBaseURL" in htmlProps)) {
|
|
60
|
+
htmlProps["moduleBaseURL"] = moduleBaseURL;
|
|
40
61
|
}
|
|
41
|
-
if(!("moduleBasePath" in htmlProps)) {
|
|
62
|
+
if (!("moduleBasePath" in htmlProps)) {
|
|
42
63
|
htmlProps["moduleBasePath"] = moduleBasePath;
|
|
43
64
|
}
|
|
65
|
+
if (!("moduleRootPath" in htmlProps)) {
|
|
66
|
+
htmlProps["moduleRootPath"] = moduleRootPath;
|
|
67
|
+
}
|
|
44
68
|
if (!("url" in htmlProps)) {
|
|
45
69
|
htmlProps["url"] = url;
|
|
46
70
|
}
|
|
@@ -52,8 +76,18 @@ export function createRscStream({
|
|
|
52
76
|
}
|
|
53
77
|
}
|
|
54
78
|
const withCss = React.createElement(
|
|
55
|
-
CssCollector,
|
|
56
|
-
|
|
79
|
+
CssCollector as any,
|
|
80
|
+
(inlineCss === true
|
|
81
|
+
? {
|
|
82
|
+
cssFiles: cssFiles,
|
|
83
|
+
route,
|
|
84
|
+
moduleBaseURL,
|
|
85
|
+
moduleBasePath,
|
|
86
|
+
moduleRootPath,
|
|
87
|
+
root,
|
|
88
|
+
loader,
|
|
89
|
+
}
|
|
90
|
+
: { cssFiles: cssFiles, route, moduleBaseURL }) as any,
|
|
57
91
|
React.createElement(Page, props)
|
|
58
92
|
);
|
|
59
93
|
// Otherwise wrap with Html component
|
|
@@ -61,17 +95,11 @@ export function createRscStream({
|
|
|
61
95
|
? withCss
|
|
62
96
|
: React.createElement(Html, htmlProps, withCss);
|
|
63
97
|
try {
|
|
64
|
-
return renderToPipeableStream(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
logger.error(`Stream error at ${route}.`, { error });
|
|
70
|
-
},
|
|
71
|
-
onPostpone: logger.info ?? console.info,
|
|
72
|
-
environmentName: "Server",
|
|
73
|
-
...pipableStreamOptions,
|
|
74
|
-
});
|
|
98
|
+
return renderToPipeableStream(
|
|
99
|
+
content,
|
|
100
|
+
moduleBasePath,
|
|
101
|
+
pipableStreamOptions
|
|
102
|
+
);
|
|
75
103
|
} catch (error) {
|
|
76
104
|
logger.error(`Failed to create stream for ${route}.`, {
|
|
77
105
|
error: error as Error,
|
package/plugin/html.tsx
ADDED
|
@@ -301,8 +301,9 @@ export function reactClientPlugin(options: StreamPluginOptions): Plugin {
|
|
|
301
301
|
userOptions.build.preserveModulesRoot === true
|
|
302
302
|
? userOptions.moduleBase
|
|
303
303
|
: "",
|
|
304
|
-
moduleBaseURL:
|
|
305
|
-
moduleBasePath:
|
|
304
|
+
moduleBaseURL: userOptions.moduleBaseURL,
|
|
305
|
+
moduleBasePath: userOptions.moduleBasePath,
|
|
306
|
+
moduleBase: userOptions.moduleBase,
|
|
306
307
|
pipableStreamOptions: userOptions.pipableStreamOptions,
|
|
307
308
|
cssFiles: []
|
|
308
309
|
} satisfies RscRenderMessage);
|
|
@@ -16,16 +16,20 @@ import { resolveUserConfig } from "../config/resolveUserConfig.js";
|
|
|
16
16
|
import type {
|
|
17
17
|
BuildTiming,
|
|
18
18
|
CheckFilesExistReturn,
|
|
19
|
+
CssContent,
|
|
19
20
|
ReactStreamPluginMeta,
|
|
20
21
|
ResolvedUserOptions,
|
|
21
22
|
} from "../types.js";
|
|
22
23
|
import { type StreamPluginOptions } from "../types.js";
|
|
23
24
|
import { createHandler } from "../helpers/createHandler.js";
|
|
24
|
-
import { mkdir,
|
|
25
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
25
26
|
import { getBundleManifest } from "../helpers/getBundleManifest.js";
|
|
26
27
|
import type { ServerResponse } from "node:http";
|
|
27
28
|
import { createInputNormalizer } from "../helpers/inputNormalizer.js";
|
|
28
29
|
import { MIME_TYPES } from "../config/mimeTypes.js";
|
|
30
|
+
import { InlineCssCollector } from "../css-collector-inline.js";
|
|
31
|
+
import { CssCollector } from "../css-collector.js";
|
|
32
|
+
import { collectModuleGraphCss } from "../collect-manifest-client-files.js";
|
|
29
33
|
|
|
30
34
|
let resolvedConfig: ResolvedConfig | null = null;
|
|
31
35
|
let serverManifestPath: string | null = null;
|
|
@@ -105,7 +109,7 @@ export function reactServerPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
105
109
|
);
|
|
106
110
|
}
|
|
107
111
|
},
|
|
108
|
-
|
|
112
|
+
|
|
109
113
|
async configurePreviewServer(server) {
|
|
110
114
|
if (root !== server.config.root) {
|
|
111
115
|
root = server.config.root;
|
|
@@ -128,11 +132,11 @@ export function reactServerPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
128
132
|
try {
|
|
129
133
|
const filePath = join(fileRoot, value);
|
|
130
134
|
const stats = await stat(filePath);
|
|
131
|
-
|
|
135
|
+
|
|
132
136
|
if (stats.isFile()) {
|
|
133
|
-
const ext = value.slice(value.lastIndexOf(
|
|
134
|
-
const contentType = MIME_TYPES[ext] ||
|
|
135
|
-
res.setHeader(
|
|
137
|
+
const ext = value.slice(value.lastIndexOf("."));
|
|
138
|
+
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
139
|
+
res.setHeader("Content-Type", contentType);
|
|
136
140
|
const content = await readFile(filePath);
|
|
137
141
|
res.end(content);
|
|
138
142
|
return;
|
|
@@ -187,25 +191,57 @@ export function reactServerPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
187
191
|
if (typeof loader !== "function") {
|
|
188
192
|
loader = server.ssrLoadModule;
|
|
189
193
|
}
|
|
190
|
-
|
|
194
|
+
let route = req.url?.replace("/index.rsc", "");
|
|
195
|
+
if (!route || route === "") {
|
|
196
|
+
route = "/";
|
|
197
|
+
}
|
|
191
198
|
try {
|
|
192
199
|
const handler = await createHandler({
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
+
root: root,
|
|
201
|
+
url:
|
|
202
|
+
typeof userOptions.moduleBaseURL === "string" &&
|
|
203
|
+
userOptions.moduleBaseURL !== ""
|
|
204
|
+
? new URL(route, userOptions.moduleBaseURL).href
|
|
205
|
+
: route,
|
|
206
|
+
route: route,
|
|
207
|
+
getCss: async (id) => {
|
|
208
|
+
const cssFiles = await collectModuleGraphCss({
|
|
209
|
+
moduleGraph: server.moduleGraph,
|
|
210
|
+
pagePath: id,
|
|
211
|
+
onCss: undefined,
|
|
212
|
+
})
|
|
213
|
+
if (userOptions.inlineCss) {
|
|
214
|
+
const InlineMap = new Map<string, CssContent>();
|
|
215
|
+
await Promise.all(Array.from(cssFiles.entries()).map(async ([file, fileUrl]) => {
|
|
216
|
+
const content = await server.ssrLoadModule(fileUrl + "?inline");
|
|
217
|
+
if (content) {
|
|
218
|
+
InlineMap.set(file, {
|
|
219
|
+
content: content['default'],
|
|
220
|
+
path: file,
|
|
221
|
+
type: "text/css",
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}));
|
|
225
|
+
return InlineMap;
|
|
226
|
+
}
|
|
227
|
+
return cssFiles;
|
|
200
228
|
},
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
229
|
+
cssFiles: [],
|
|
230
|
+
logger: createLogger(),
|
|
231
|
+
loader,
|
|
232
|
+
moduleBase: userOptions.moduleBase,
|
|
233
|
+
moduleBasePath: userOptions.moduleBasePath,
|
|
234
|
+
moduleBaseURL: userOptions.moduleBaseURL,
|
|
235
|
+
moduleRootPath: root,
|
|
236
|
+
pipableStreamOptions: userOptions.pipableStreamOptions,
|
|
237
|
+
Html: React.Fragment,
|
|
238
|
+
CssCollector: userOptions.inlineCss ? InlineCssCollector as any : CssCollector as any,
|
|
239
|
+
onCssFile: undefined,
|
|
240
|
+
inlineCss: userOptions.inlineCss,
|
|
241
|
+
propsPath: files.urlMap.get(route)?.props ?? route,
|
|
242
|
+
pagePath: files.urlMap.get(route)?.page ?? route,
|
|
243
|
+
pageExportName: userOptions.pageExportName,
|
|
244
|
+
propsExportName: userOptions.propsExportName,
|
|
209
245
|
});
|
|
210
246
|
if (handler.type === "success") {
|
|
211
247
|
handler.stream?.pipe(res);
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type Manifest,
|
|
7
7
|
type IndexHtmlTransformHook,
|
|
8
8
|
type Plugin as VitePlugin,
|
|
9
|
+
createLogger,
|
|
9
10
|
} from "vite";
|
|
10
11
|
import { checkFilesExist } from "../checkFilesExist.js";
|
|
11
12
|
import { resolveOptions } from "../config/resolveOptions.js";
|
|
@@ -45,7 +46,7 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
45
46
|
let root: string = process.cwd();
|
|
46
47
|
let userConfig: ResolvedUserConfig;
|
|
47
48
|
let userOptions: ResolvedUserOptions;
|
|
48
|
-
let
|
|
49
|
+
let pages: string[];
|
|
49
50
|
let serverManifest: Manifest = {};
|
|
50
51
|
let clientManifest: Manifest = {};
|
|
51
52
|
|
|
@@ -83,12 +84,12 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
83
84
|
) {
|
|
84
85
|
root = config.root;
|
|
85
86
|
}
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
throw
|
|
87
|
+
const resolvePagesResult = await resolvePages(userOptions.build.pages);
|
|
88
|
+
if (resolvePagesResult.type === "error") {
|
|
89
|
+
throw resolvePagesResult.error;
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
-
files = await checkFilesExist(
|
|
91
|
+
pages = resolvePagesResult.pages;
|
|
92
|
+
files = await checkFilesExist(pages, userOptions, root);
|
|
92
93
|
|
|
93
94
|
const resolvedConfig = resolveUserConfig({
|
|
94
95
|
isStatic: true,
|
|
@@ -176,7 +177,7 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
176
177
|
indexCss.forEach((css) => globalCss.add(css));
|
|
177
178
|
|
|
178
179
|
// Add CSS for each route's page component - use server manifest
|
|
179
|
-
for (const route of
|
|
180
|
+
for (const route of pages) {
|
|
180
181
|
const routeFiles = files.urlMap.get(route);
|
|
181
182
|
if (routeFiles) {
|
|
182
183
|
const pageCss = collectManifestClientFiles({
|
|
@@ -205,18 +206,26 @@ export function reactStaticPlugin(options: StreamPluginOptions): VitePlugin<{
|
|
|
205
206
|
: [];
|
|
206
207
|
|
|
207
208
|
const { failedRoutes, completedRoutes} = await renderPages(
|
|
208
|
-
|
|
209
|
+
pages,
|
|
209
210
|
files,
|
|
210
211
|
{
|
|
212
|
+
root: root,
|
|
211
213
|
outDir: userOptions.build.outDir,
|
|
212
214
|
htmlOutputPath: join( userOptions.build.outDir, userOptions.build.static, "index.html"),
|
|
213
215
|
pipableStreamOptions: {
|
|
214
216
|
bootstrapModules: bootstrapModules,
|
|
215
217
|
},
|
|
216
|
-
|
|
218
|
+
moduleRootPath: join(root, userOptions.build.outDir, userOptions.build.static, userOptions.moduleBasePath),
|
|
219
|
+
moduleBasePath: userOptions.moduleBasePath,
|
|
217
220
|
moduleBaseURL: userOptions.moduleBaseURL,
|
|
218
|
-
|
|
219
|
-
|
|
221
|
+
inlineCss: userOptions.inlineCss,
|
|
222
|
+
pageExportName: userOptions.pageExportName,
|
|
223
|
+
propsExportName: userOptions.propsExportName,
|
|
224
|
+
Html: userOptions.Html,
|
|
225
|
+
CssCollector: userOptions.CssCollector,
|
|
226
|
+
cssFiles: [],
|
|
227
|
+
logger: createLogger(),
|
|
228
|
+
moduleBase: userOptions.moduleBase,
|
|
220
229
|
worker,
|
|
221
230
|
clientManifest,
|
|
222
231
|
serverManifest,
|
package/plugin/types.ts
CHANGED
|
@@ -65,7 +65,7 @@ export interface StreamPluginOptionsClient {
|
|
|
65
65
|
cssFiles?: AliasOptions;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
export type ResolvedUserOptions = Required<
|
|
68
|
+
export type ResolvedUserOptions<InlineCSS extends boolean = boolean> = Required<
|
|
69
69
|
Pick<
|
|
70
70
|
StreamPluginOptions,
|
|
71
71
|
| "moduleBase"
|
|
@@ -76,10 +76,12 @@ export type ResolvedUserOptions = Required<
|
|
|
76
76
|
| "Page"
|
|
77
77
|
| "props"
|
|
78
78
|
| "Html"
|
|
79
|
+
| "CssCollector"
|
|
79
80
|
| "pageExportName"
|
|
80
81
|
| "propsExportName"
|
|
81
82
|
| "collectCss"
|
|
82
83
|
| "collectAssets"
|
|
84
|
+
| "inlineCss"
|
|
83
85
|
| "htmlWorkerPath"
|
|
84
86
|
| "rscWorkerPath"
|
|
85
87
|
| "loaderPath"
|
|
@@ -89,7 +91,7 @@ export type ResolvedUserOptions = Required<
|
|
|
89
91
|
| "pipableStreamOptions"
|
|
90
92
|
>
|
|
91
93
|
> & {
|
|
92
|
-
build: NonNullable<Required<StreamPluginOptions["build"]>>;
|
|
94
|
+
build: NonNullable<Required<StreamPluginOptions<InlineCSS>["build"]>>;
|
|
93
95
|
autoDiscover: {
|
|
94
96
|
modulePattern: (path: string) => boolean;
|
|
95
97
|
cssPattern: (path: string) => boolean;
|
|
@@ -116,7 +118,7 @@ export type createBuildConfigFn<C extends "react-client" | "react-server"> =
|
|
|
116
118
|
? Promise<InlineConfig>
|
|
117
119
|
: Promise<InlineConfig>;
|
|
118
120
|
|
|
119
|
-
export interface StreamPluginOptions {
|
|
121
|
+
export interface StreamPluginOptions<InlineCSS extends boolean = boolean> {
|
|
120
122
|
projectRoot?: string;
|
|
121
123
|
moduleBase: string;
|
|
122
124
|
moduleBasePath?: string;
|
|
@@ -164,25 +166,38 @@ export interface StreamPluginOptions {
|
|
|
164
166
|
url: string;
|
|
165
167
|
children: React.ReactNode;
|
|
166
168
|
}>;
|
|
169
|
+
CssCollector?: InlineCSS extends true ? React.FC<React.PropsWithChildren<InlineCssCollectorProps>> : React.FC<React.PropsWithChildren<CssCollectorProps>>;
|
|
167
170
|
collectCss?: boolean;
|
|
168
171
|
collectAssets?: boolean;
|
|
172
|
+
inlineCss?: InlineCSS;
|
|
169
173
|
build?: BuildConfig;
|
|
170
174
|
moduleBaseExceptions?: string[];
|
|
171
175
|
pipableStreamOptions?: PipeableStreamOptions;
|
|
172
176
|
}
|
|
173
177
|
|
|
174
|
-
export interface CreateHandlerOptions<T = any> {
|
|
178
|
+
export interface CreateHandlerOptions<T = any, InlineCSS extends boolean = boolean> {
|
|
179
|
+
root: string;
|
|
180
|
+
url: string;
|
|
181
|
+
route: string;
|
|
182
|
+
getCss: (id: string) => Promise<Map<string, string | CssContent>> | Map<string, string | CssContent>;
|
|
175
183
|
loader: (id: string) => Promise<T>;
|
|
176
|
-
|
|
177
|
-
|
|
184
|
+
Html: NonNullable<StreamPluginOptions['Html']>
|
|
185
|
+
CssCollector: InlineCSS extends true ? React.FC<React.PropsWithChildren<InlineCssCollectorProps>> : React.FC<React.PropsWithChildren<CssCollectorProps>>;
|
|
186
|
+
inlineCss: InlineCSS;
|
|
187
|
+
propsPath?: string;
|
|
188
|
+
pagePath?: string;
|
|
189
|
+
pageExportName: string
|
|
190
|
+
propsExportName: string
|
|
191
|
+
moduleBase: string
|
|
192
|
+
preserveModulesRoot?: boolean | undefined
|
|
178
193
|
moduleBasePath: string;
|
|
194
|
+
moduleRootPath: string;
|
|
179
195
|
moduleBaseURL: string;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
cssModules?: Set<string>;
|
|
196
|
+
cssFiles: (string | CssContent)[];
|
|
197
|
+
cssModules?: Map<string, string | CssContent> | undefined;
|
|
183
198
|
onCssFile?: (path: string, parentUrl: string) => void;
|
|
184
|
-
logger
|
|
185
|
-
pipableStreamOptions
|
|
199
|
+
logger: import("vite").Logger;
|
|
200
|
+
pipableStreamOptions: PipeableStreamOptions;
|
|
186
201
|
}
|
|
187
202
|
|
|
188
203
|
export type ModuleLoader = (
|
|
@@ -378,3 +393,30 @@ export interface PageData {
|
|
|
378
393
|
modules: Array<[string, string]>; // [modulePath, exportName]
|
|
379
394
|
};
|
|
380
395
|
}
|
|
396
|
+
|
|
397
|
+
export interface CssContent {
|
|
398
|
+
type?: string;
|
|
399
|
+
content: string;
|
|
400
|
+
key?: string;
|
|
401
|
+
path: string;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export interface InlineCssCollectorProps {
|
|
405
|
+
cssFiles: CssContent[];
|
|
406
|
+
root: string;
|
|
407
|
+
moduleBaseURL: string;
|
|
408
|
+
moduleBasePath: string;
|
|
409
|
+
moduleRootPath: string;
|
|
410
|
+
route: string;
|
|
411
|
+
children?: React.ReactNode;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export interface CssCollectorProps {
|
|
415
|
+
cssFiles: CssContent[];
|
|
416
|
+
root: string;
|
|
417
|
+
moduleBaseURL: string;
|
|
418
|
+
moduleBasePath: string;
|
|
419
|
+
moduleRootPath: string;
|
|
420
|
+
route: string;
|
|
421
|
+
children?: React.ReactNode;
|
|
422
|
+
}
|