@cedarjs/vite 3.0.0 → 4.0.0-canary.13650
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/dist/bundled/react-server-dom-webpack.server.js +1224 -28468
- package/dist/cjs/devFeServer.js +269 -15
- package/dist/cjs/lib/registerFwGlobalsAndShims.js +9 -0
- package/dist/cjs/plugins/vite-plugin-rsc-ssr-router-import.js +2 -2
- package/dist/cjs/plugins/vite-plugin-rsc-transform-server.js +4 -0
- package/dist/cjs/rsc/rscRenderer.js +23 -9
- package/dist/cjs/rsc/rscRequestHandler.js +6 -6
- package/dist/cjs/rsc/rscWebSocketServer.js +56 -0
- package/dist/cjs/runFeServer.js +3 -22
- package/dist/cjs/streaming/createReactStreamingHandler.js +13 -10
- package/dist/cjs/streaming/streamHelpers.js +49 -32
- package/dist/cjs/streaming/triggerRouteHooks.js +3 -3
- package/dist/devFeServer.js +269 -16
- package/dist/lib/registerFwGlobalsAndShims.js +9 -0
- package/dist/plugins/vite-plugin-rsc-ssr-router-import.d.ts.map +1 -1
- package/dist/plugins/vite-plugin-rsc-ssr-router-import.js +2 -2
- package/dist/plugins/vite-plugin-rsc-transform-server.d.ts.map +1 -1
- package/dist/plugins/vite-plugin-rsc-transform-server.js +4 -0
- package/dist/rsc/rscRenderer.d.ts.map +1 -1
- package/dist/rsc/rscRenderer.js +19 -5
- package/dist/rsc/rscRequestHandler.d.ts +2 -2
- package/dist/rsc/rscRequestHandler.d.ts.map +1 -1
- package/dist/rsc/rscRequestHandler.js +4 -4
- package/dist/rsc/rscWebSocketServer.d.ts +2 -0
- package/dist/rsc/rscWebSocketServer.d.ts.map +1 -0
- package/dist/rsc/rscWebSocketServer.js +22 -0
- package/dist/runFeServer.js +2 -21
- package/dist/streaming/createReactStreamingHandler.d.ts +1 -1
- package/dist/streaming/createReactStreamingHandler.d.ts.map +1 -1
- package/dist/streaming/createReactStreamingHandler.js +13 -10
- package/dist/streaming/streamHelpers.d.ts +2 -2
- package/dist/streaming/streamHelpers.d.ts.map +1 -1
- package/dist/streaming/streamHelpers.js +49 -31
- package/dist/streaming/triggerRouteHooks.d.ts +2 -2
- package/dist/streaming/triggerRouteHooks.d.ts.map +1 -1
- package/dist/streaming/triggerRouteHooks.js +3 -3
- package/package.json +11 -11
|
@@ -50,10 +50,10 @@ const createReactStreamingHandler = async ({
|
|
|
50
50
|
clientEntryPath,
|
|
51
51
|
getStylesheetLinks,
|
|
52
52
|
getMiddlewareRouter
|
|
53
|
-
},
|
|
53
|
+
}, viteSsrDevServer) => {
|
|
54
54
|
const rwPaths = (0, import_project_config.getPaths)();
|
|
55
55
|
const rwConfig = (0, import_project_config.getConfig)();
|
|
56
|
-
const isProd = !
|
|
56
|
+
const isProd = !viteSsrDevServer;
|
|
57
57
|
const middlewareRouter = await getMiddlewareRouter();
|
|
58
58
|
let entryServerImport;
|
|
59
59
|
let fallbackDocumentImport;
|
|
@@ -97,7 +97,7 @@ const createReactStreamingHandler = async ({
|
|
|
97
97
|
route: currentRoute,
|
|
98
98
|
cssPaths: cssLinks,
|
|
99
99
|
params: matchedMw?.params,
|
|
100
|
-
|
|
100
|
+
viteSsrDevServer
|
|
101
101
|
}
|
|
102
102
|
);
|
|
103
103
|
if (mwResponse.isRedirect() || mwResponse.body) {
|
|
@@ -116,8 +116,8 @@ const createReactStreamingHandler = async ({
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
if (!isProd) {
|
|
119
|
-
entryServerImport = await (0, import_utils.ssrLoadEntryServer)(
|
|
120
|
-
fallbackDocumentImport = await
|
|
119
|
+
entryServerImport = await (0, import_utils.ssrLoadEntryServer)(viteSsrDevServer);
|
|
120
|
+
fallbackDocumentImport = await viteSsrDevServer.ssrLoadModule(
|
|
121
121
|
rwPaths.web.document
|
|
122
122
|
);
|
|
123
123
|
}
|
|
@@ -134,10 +134,12 @@ const createReactStreamingHandler = async ({
|
|
|
134
134
|
req,
|
|
135
135
|
parsedParams
|
|
136
136
|
},
|
|
137
|
-
|
|
137
|
+
viteSsrDevServer
|
|
138
138
|
});
|
|
139
139
|
metaTags = routeHookOutput.meta;
|
|
140
|
-
const jsBundles = [
|
|
140
|
+
const jsBundles = [
|
|
141
|
+
viteSsrDevServer ? clientEntryPath : "/" + clientEntryPath
|
|
142
|
+
];
|
|
141
143
|
if (currentRoute.bundle) {
|
|
142
144
|
jsBundles.push("/" + currentRoute.bundle);
|
|
143
145
|
}
|
|
@@ -157,12 +159,13 @@ const createReactStreamingHandler = async ({
|
|
|
157
159
|
{
|
|
158
160
|
waitForAllReady: isSeoCrawler,
|
|
159
161
|
onError: (err) => {
|
|
160
|
-
if (!isProd &&
|
|
161
|
-
|
|
162
|
+
if (!isProd && viteSsrDevServer) {
|
|
163
|
+
viteSsrDevServer.ssrFixStacktrace(err);
|
|
162
164
|
}
|
|
163
165
|
console.error(err);
|
|
164
166
|
}
|
|
165
|
-
}
|
|
167
|
+
},
|
|
168
|
+
viteSsrDevServer
|
|
166
169
|
);
|
|
167
170
|
return reactResponse;
|
|
168
171
|
};
|
|
@@ -28,7 +28,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var streamHelpers_exports = {};
|
|
30
30
|
__export(streamHelpers_exports, {
|
|
31
|
-
importModule: () => importModule,
|
|
32
31
|
reactRenderToStreamResponse: () => reactRenderToStreamResponse
|
|
33
32
|
});
|
|
34
33
|
module.exports = __toCommonJS(streamHelpers_exports);
|
|
@@ -62,7 +61,7 @@ globalThis.__webpack_require__ ||= (id) => {
|
|
|
62
61
|
return globalThis.__rw_module_cache__.get(id)
|
|
63
62
|
};
|
|
64
63
|
`;
|
|
65
|
-
async function reactRenderToStreamResponse(mwRes, renderOptions, streamOptions) {
|
|
64
|
+
async function reactRenderToStreamResponse(mwRes, renderOptions, streamOptions, viteDevServer) {
|
|
66
65
|
const { waitForAllReady = false } = streamOptions;
|
|
67
66
|
const {
|
|
68
67
|
ServerEntry,
|
|
@@ -84,13 +83,13 @@ async function reactRenderToStreamResponse(mwRes, renderOptions, streamOptions)
|
|
|
84
83
|
meta: metaTags
|
|
85
84
|
});
|
|
86
85
|
const rscEnabled = (0, import_project_config.getConfig)().experimental?.rsc?.enabled;
|
|
87
|
-
const { createElement } = rscEnabled ? await importModule("__cedarjs__react") : await import("react");
|
|
86
|
+
const { createElement } = rscEnabled ? await importModule("__cedarjs__react", !!viteDevServer) : await import("react");
|
|
88
87
|
const {
|
|
89
88
|
createInjector,
|
|
90
89
|
ServerHtmlProvider,
|
|
91
90
|
ServerInjectedHtml
|
|
92
|
-
} = rscEnabled ? await importModule("__cedarjs__server_inject") : await import("@cedarjs/web/serverInject");
|
|
93
|
-
const { renderToString } = rscEnabled ? await importModule("rd-server") : await import("react-dom/server");
|
|
91
|
+
} = rscEnabled ? await importModule("__cedarjs__server_inject", !!viteDevServer) : await import("@cedarjs/web/serverInject");
|
|
92
|
+
const { renderToString } = rscEnabled ? await importModule("rd-server", !!viteDevServer) : await import("react-dom/server");
|
|
94
93
|
const { injectionState, injectToPage } = createInjector();
|
|
95
94
|
const bufferTransform = (0, import_bufferedTransform.createBufferedTransformStream)();
|
|
96
95
|
const serverInjectionTransform = (0, import_serverInjectionTransform.createServerInjectionTransform)({
|
|
@@ -105,8 +104,8 @@ async function reactRenderToStreamResponse(mwRes, renderOptions, streamOptions)
|
|
|
105
104
|
controller.abort();
|
|
106
105
|
}, 1e4);
|
|
107
106
|
const timeoutTransform = (0, import_cancelTimeoutTransform.createTimeoutTransform)(timeoutHandle);
|
|
108
|
-
const { ServerAuthProvider } = rscEnabled ? await importModule("__cedarjs__server_auth_provider") : await import("@cedarjs/auth/dist/AuthProvider/ServerAuthProvider.js");
|
|
109
|
-
const { LocationProvider } = rscEnabled ? await importModule("__cedarjs__location") : await import("@cedarjs/router/location");
|
|
107
|
+
const { ServerAuthProvider } = rscEnabled ? await importModule("__cedarjs__server_auth_provider", !!viteDevServer) : await import("@cedarjs/auth/dist/AuthProvider/ServerAuthProvider.js");
|
|
108
|
+
const { LocationProvider } = rscEnabled ? await importModule("__cedarjs__location", !!viteDevServer) : await import("@cedarjs/router/location");
|
|
110
109
|
const renderRoot = (url) => {
|
|
111
110
|
return createElement(
|
|
112
111
|
ServerAuthProvider,
|
|
@@ -138,7 +137,7 @@ async function reactRenderToStreamResponse(mwRes, renderOptions, streamOptions)
|
|
|
138
137
|
),
|
|
139
138
|
bootstrapModules: jsBundles
|
|
140
139
|
};
|
|
141
|
-
const { renderToReadableStream } = rscEnabled ? await importModule("rd-server") : await import("react-dom/server.edge");
|
|
140
|
+
const { renderToReadableStream } = rscEnabled ? await importModule("rd-server", !!viteDevServer) : await import("react-dom/server.edge");
|
|
142
141
|
try {
|
|
143
142
|
let didErrorOutsideShell = false;
|
|
144
143
|
const renderToStreamOptions = {
|
|
@@ -197,34 +196,52 @@ function applyStreamTransforms(reactStream, transformsToApply) {
|
|
|
197
196
|
}
|
|
198
197
|
return outputStream;
|
|
199
198
|
}
|
|
200
|
-
async function importModule(mod) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
199
|
+
async function importModule(mod, isDev) {
|
|
200
|
+
if (isDev) {
|
|
201
|
+
if (mod === "rd-server") {
|
|
202
|
+
const loadedMod = await import("react-dom/server.edge");
|
|
203
|
+
return loadedMod.default;
|
|
204
|
+
} else if (mod === "__cedarjs__react") {
|
|
205
|
+
const loadedMod = await import("react");
|
|
206
|
+
return loadedMod.default;
|
|
207
|
+
} else if (mod === "__cedarjs__location") {
|
|
208
|
+
const loadedMod = await import("@cedarjs/router/location");
|
|
209
|
+
return loadedMod;
|
|
210
|
+
} else if (mod === "__cedarjs__server_auth_provider") {
|
|
211
|
+
const loadedMod = await import("@cedarjs/auth/dist/AuthProvider/ServerAuthProvider.js");
|
|
212
|
+
return loadedMod;
|
|
213
|
+
} else if (mod === "__cedarjs__server_inject") {
|
|
214
|
+
const loadedMod = await import("@cedarjs/web/serverInject");
|
|
215
|
+
return loadedMod;
|
|
216
|
+
}
|
|
217
|
+
} else {
|
|
218
|
+
const distSsr = (0, import_project_config.getPaths)().web.distSsr;
|
|
219
|
+
const rdServerPath = (0, import_utils.makeFilePath)(import_node_path.default.join(distSsr, "rd-server.mjs"));
|
|
220
|
+
const reactPath = (0, import_utils.makeFilePath)(import_node_path.default.join(distSsr, "__cedarjs__react.mjs"));
|
|
221
|
+
const locationPath = (0, import_utils.makeFilePath)(
|
|
222
|
+
import_node_path.default.join(distSsr, "__cedarjs__location.mjs")
|
|
223
|
+
);
|
|
224
|
+
const serverAuthProviderPath = (0, import_utils.makeFilePath)(
|
|
225
|
+
import_node_path.default.join(distSsr, "__cedarjs__server_auth_provider.mjs")
|
|
226
|
+
);
|
|
227
|
+
const serverInjectPath = (0, import_utils.makeFilePath)(
|
|
228
|
+
import_node_path.default.join(distSsr, "__cedarjs__server_inject.mjs")
|
|
229
|
+
);
|
|
230
|
+
if (mod === "rd-server") {
|
|
231
|
+
return (await import(rdServerPath)).default;
|
|
232
|
+
} else if (mod === "__cedarjs__react") {
|
|
233
|
+
return (await import(reactPath)).default;
|
|
234
|
+
} else if (mod === "__cedarjs__location") {
|
|
235
|
+
return await import(locationPath);
|
|
236
|
+
} else if (mod === "__cedarjs__server_auth_provider") {
|
|
237
|
+
return await import(serverAuthProviderPath);
|
|
238
|
+
} else if (mod === "__cedarjs__server_inject") {
|
|
239
|
+
return await import(serverInjectPath);
|
|
240
|
+
}
|
|
223
241
|
}
|
|
224
242
|
throw new Error("Unknown module " + mod);
|
|
225
243
|
}
|
|
226
244
|
// Annotate the CommonJS export names for ESM import in node:
|
|
227
245
|
0 && (module.exports = {
|
|
228
|
-
importModule,
|
|
229
246
|
reactRenderToStreamResponse
|
|
230
247
|
});
|
|
@@ -55,11 +55,11 @@ const defaultRouteHookOutput = {
|
|
|
55
55
|
const loadAndRunRouteHooks = async ({
|
|
56
56
|
paths = [],
|
|
57
57
|
reqMeta,
|
|
58
|
-
|
|
58
|
+
viteSsrDevServer,
|
|
59
59
|
previousOutput = defaultRouteHookOutput
|
|
60
60
|
}) => {
|
|
61
61
|
const loadModule = async (path) => {
|
|
62
|
-
return
|
|
62
|
+
return viteSsrDevServer ? viteSsrDevServer.ssrLoadModule(path) : import(path);
|
|
63
63
|
};
|
|
64
64
|
let currentRouteHooks;
|
|
65
65
|
let rhOutput = defaultRouteHookOutput;
|
|
@@ -79,7 +79,7 @@ const loadAndRunRouteHooks = async ({
|
|
|
79
79
|
paths,
|
|
80
80
|
reqMeta,
|
|
81
81
|
previousOutput: rhOutput,
|
|
82
|
-
|
|
82
|
+
viteSsrDevServer
|
|
83
83
|
});
|
|
84
84
|
} else {
|
|
85
85
|
return rhOutput;
|
package/dist/devFeServer.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import http from "node:http";
|
|
1
2
|
import { createServerAdapter } from "@whatwg-node/server";
|
|
2
3
|
import express from "express";
|
|
3
|
-
import { createServer as createViteServer } from "vite";
|
|
4
|
+
import { createServer as createViteServer, createViteRuntime } from "vite";
|
|
4
5
|
import { cjsInterop } from "vite-plugin-cjs-interop";
|
|
5
6
|
import { getProjectRoutes } from "@cedarjs/internal/dist/routes.js";
|
|
6
7
|
import { getConfig, getPaths } from "@cedarjs/project-config";
|
|
@@ -9,6 +10,10 @@ import { registerFwGlobalsAndShims } from "./lib/registerFwGlobalsAndShims.js";
|
|
|
9
10
|
import { invoke } from "./middleware/invokeMiddleware.js";
|
|
10
11
|
import { createMiddlewareRouter } from "./middleware/register.js";
|
|
11
12
|
import { rscRoutesAutoLoader } from "./plugins/vite-plugin-rsc-routes-auto-loader.js";
|
|
13
|
+
import { rscRoutesImports } from "./plugins/vite-plugin-rsc-routes-imports.js";
|
|
14
|
+
import { rscSsrRouterImport } from "./plugins/vite-plugin-rsc-ssr-router-import.js";
|
|
15
|
+
import { rscTransformUseServerPlugin } from "./plugins/vite-plugin-rsc-transform-server.js";
|
|
16
|
+
import { createWebSocketServer } from "./rsc/rscWebSocketServer.js";
|
|
12
17
|
import { collectCssPaths, componentsModules } from "./streaming/collectCss.js";
|
|
13
18
|
import { createReactStreamingHandler } from "./streaming/createReactStreamingHandler.js";
|
|
14
19
|
import {
|
|
@@ -17,10 +22,13 @@ import {
|
|
|
17
22
|
getFullUrl
|
|
18
23
|
} from "./utils.js";
|
|
19
24
|
globalThis.__REDWOOD__PRERENDER_PAGES = {};
|
|
25
|
+
globalThis.__cedarjs__vite_ssr_runtime = void 0;
|
|
26
|
+
globalThis.__cedarjs__vite_rsc_runtime = void 0;
|
|
20
27
|
async function createServer() {
|
|
21
28
|
ensureProcessDirWeb();
|
|
22
29
|
registerFwGlobalsAndShims();
|
|
23
30
|
const app = express();
|
|
31
|
+
const server = http.createServer(app);
|
|
24
32
|
const rwPaths = getPaths();
|
|
25
33
|
const rscEnabled = getConfig().experimental.rsc?.enabled ?? false;
|
|
26
34
|
const serverStorage = createServerStorage();
|
|
@@ -43,8 +51,78 @@ async function createServer() {
|
|
|
43
51
|
"Vite config not found. You need to setup your project with Vite using `yarn cedar setup vite`"
|
|
44
52
|
);
|
|
45
53
|
}
|
|
46
|
-
const
|
|
54
|
+
const viteSsrDevServer = await createViteServer({
|
|
47
55
|
configFile: rwPaths.web.viteConfig,
|
|
56
|
+
envFile: false,
|
|
57
|
+
define: {
|
|
58
|
+
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
|
|
59
|
+
},
|
|
60
|
+
ssr: {
|
|
61
|
+
// Inline every file apart from node built-ins. We want vite/rollup to
|
|
62
|
+
// inline dependencies in the server build. This gets round runtime
|
|
63
|
+
// importing of "server-only" and other packages with poisoned imports.
|
|
64
|
+
//
|
|
65
|
+
// Files included in `noExternal` are files we want Vite to analyze
|
|
66
|
+
// As of vite 5.2 `true` here means "all except node built-ins"
|
|
67
|
+
// noExternal: true,
|
|
68
|
+
// TODO (RSC): Other frameworks build for RSC without `noExternal: true`.
|
|
69
|
+
// What are we missing here? When/why is that a better choice? I know
|
|
70
|
+
// we would have to explicitly add a bunch of packages to noExternal, if
|
|
71
|
+
// we wanted to go that route.
|
|
72
|
+
// noExternal: ['@tobbe.dev/rsc-test'],
|
|
73
|
+
// Can't inline prisma client (db calls fail at runtime) or react-dom
|
|
74
|
+
// (css pre-init failure)
|
|
75
|
+
// Server store has to be externalized, because it's a singleton (shared between FW and App)
|
|
76
|
+
external: [
|
|
77
|
+
"@prisma/client",
|
|
78
|
+
"@prisma/adapter-better-sqlite3",
|
|
79
|
+
"@prisma/fetch-engine",
|
|
80
|
+
"@prisma/internals",
|
|
81
|
+
"better-sqlite3",
|
|
82
|
+
"@cedarjs/auth-dbauth-api",
|
|
83
|
+
"@cedarjs/cookie-jar",
|
|
84
|
+
"@cedarjs/server-store",
|
|
85
|
+
"@simplewebauthn/server",
|
|
86
|
+
"graphql-scalars",
|
|
87
|
+
"minimatch",
|
|
88
|
+
"playwright",
|
|
89
|
+
"react-dom"
|
|
90
|
+
],
|
|
91
|
+
resolve: {
|
|
92
|
+
// These conditions are used in the plugin pipeline, and only affect non-externalized
|
|
93
|
+
// dependencies during the SSR build. Which because of `noExternal: true` means all
|
|
94
|
+
// dependencies apart from node built-ins.
|
|
95
|
+
// TODO (RSC): What's the difference between `conditions` and
|
|
96
|
+
// `externalConditions`? When is one used over the other?
|
|
97
|
+
// conditions: ['react-server'],
|
|
98
|
+
// externalConditions: ['react-server'],
|
|
99
|
+
},
|
|
100
|
+
optimizeDeps: {
|
|
101
|
+
// We need Vite to optimize these dependencies so that they are resolved
|
|
102
|
+
// with the correct conditions. And so that CJS modules work correctly.
|
|
103
|
+
// include: [
|
|
104
|
+
// 'react/**/*',
|
|
105
|
+
// 'react-dom/server',
|
|
106
|
+
// 'react-dom/server.edge',
|
|
107
|
+
// 'rehackt',
|
|
108
|
+
// 'react-server-dom-webpack/server',
|
|
109
|
+
// 'react-server-dom-webpack/client',
|
|
110
|
+
// '@apollo/client/cache/*',
|
|
111
|
+
// '@apollo/client/utilities/*',
|
|
112
|
+
// '@apollo/client/react/hooks/*',
|
|
113
|
+
// 'react-fast-compare',
|
|
114
|
+
// 'invariant',
|
|
115
|
+
// 'shallowequal',
|
|
116
|
+
// 'graphql/language/*',
|
|
117
|
+
// 'stacktracey',
|
|
118
|
+
// 'deepmerge',
|
|
119
|
+
// 'fast-glob',
|
|
120
|
+
// ],
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
resolve: {
|
|
124
|
+
// conditions: ['react-server'],
|
|
125
|
+
},
|
|
48
126
|
plugins: [
|
|
49
127
|
cjsInterop({
|
|
50
128
|
dependencies: [
|
|
@@ -58,16 +136,184 @@ async function createServer() {
|
|
|
58
136
|
"@cedarjs/auth-!(dbauth)-web"
|
|
59
137
|
]
|
|
60
138
|
}),
|
|
61
|
-
rscEnabled && rscRoutesAutoLoader()
|
|
139
|
+
rscEnabled && rscRoutesAutoLoader(),
|
|
140
|
+
rscEnabled && rscSsrRouterImport()
|
|
62
141
|
],
|
|
63
142
|
server: { middlewareMode: true },
|
|
64
143
|
logLevel: "info",
|
|
65
144
|
clearScreen: false,
|
|
66
145
|
appType: "custom"
|
|
67
146
|
});
|
|
147
|
+
globalThis.__cedarjs__vite_ssr_runtime = await createViteRuntime(viteSsrDevServer);
|
|
148
|
+
globalThis.__cedarjs__client_references = /* @__PURE__ */ new Set();
|
|
149
|
+
globalThis.__cedarjs__server_references = /* @__PURE__ */ new Set();
|
|
150
|
+
const viteRscServer = await createViteServer({
|
|
151
|
+
envFile: false,
|
|
152
|
+
define: {
|
|
153
|
+
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
|
|
154
|
+
},
|
|
155
|
+
ssr: {
|
|
156
|
+
// Inline every file apart from node built-ins. We want vite/rollup to
|
|
157
|
+
// inline dependencies in the server build. This gets round runtime
|
|
158
|
+
// importing of "server-only" and other packages with poisoned imports.
|
|
159
|
+
//
|
|
160
|
+
// Files included in `noExternal` are files we want Vite to analyze
|
|
161
|
+
// As of vite 5.2 `true` here means "all except node built-ins"
|
|
162
|
+
noExternal: true,
|
|
163
|
+
// TODO (RSC): Other frameworks build for RSC without `noExternal: true`.
|
|
164
|
+
// What are we missing here? When/why is that a better choice? I know
|
|
165
|
+
// we would have to explicitly add a bunch of packages to noExternal, if
|
|
166
|
+
// we wanted to go that route.
|
|
167
|
+
// noExternal: ['@tobbe.dev/rsc-test'],
|
|
168
|
+
// Can't inline prisma client (db calls fail at runtime) or react-dom
|
|
169
|
+
// (css pre-init failure)
|
|
170
|
+
// Server store has to be externalized, because it's a singleton (shared between FW and App)
|
|
171
|
+
external: [
|
|
172
|
+
"@prisma/client",
|
|
173
|
+
"@prisma/adapter-better-sqlite3",
|
|
174
|
+
"@prisma/fetch-engine",
|
|
175
|
+
"@prisma/internals",
|
|
176
|
+
"better-sqlite3",
|
|
177
|
+
"@cedarjs/auth-dbauth-api",
|
|
178
|
+
"@cedarjs/cookie-jar",
|
|
179
|
+
"@cedarjs/server-store",
|
|
180
|
+
"@cedarjs/structure",
|
|
181
|
+
"@simplewebauthn/server",
|
|
182
|
+
"graphql-scalars",
|
|
183
|
+
"minimatch",
|
|
184
|
+
"playwright",
|
|
185
|
+
"react-dom"
|
|
186
|
+
],
|
|
187
|
+
resolve: {
|
|
188
|
+
// These conditions are used in the plugin pipeline, and only affect non-externalized
|
|
189
|
+
// dependencies during the SSR build. Which because of `noExternal: true` means all
|
|
190
|
+
// dependencies apart from node built-ins.
|
|
191
|
+
// TODO (RSC): What's the difference between `conditions` and
|
|
192
|
+
// `externalConditions`? When is one used over the other?
|
|
193
|
+
conditions: ["react-server"],
|
|
194
|
+
externalConditions: ["react-server"]
|
|
195
|
+
},
|
|
196
|
+
optimizeDeps: {
|
|
197
|
+
// We need Vite to optimize these dependencies so that they are resolved
|
|
198
|
+
// with the correct conditions. And so that CJS modules work correctly.
|
|
199
|
+
include: [
|
|
200
|
+
"react/**/*",
|
|
201
|
+
"react-dom/server",
|
|
202
|
+
"react-dom/server.edge",
|
|
203
|
+
"rehackt",
|
|
204
|
+
"react-server-dom-webpack/server",
|
|
205
|
+
"react-server-dom-webpack/server.edge",
|
|
206
|
+
"react-server-dom-webpack/client",
|
|
207
|
+
"react-server-dom-webpack/client.edge",
|
|
208
|
+
"@apollo/client/cache/*",
|
|
209
|
+
"@apollo/client/utilities/*",
|
|
210
|
+
"@apollo/client/react/hooks/*",
|
|
211
|
+
"react-fast-compare",
|
|
212
|
+
"invariant",
|
|
213
|
+
"shallowequal",
|
|
214
|
+
"graphql/language/*",
|
|
215
|
+
"stacktracey",
|
|
216
|
+
"deepmerge",
|
|
217
|
+
"fast-glob",
|
|
218
|
+
"@whatwg-node/fetch",
|
|
219
|
+
"busboy",
|
|
220
|
+
"cookie"
|
|
221
|
+
],
|
|
222
|
+
// Without excluding `util` we get "TypeError: util.TextEncoder is not
|
|
223
|
+
// a constructor" in react-server-dom-webpack.server because it'll try
|
|
224
|
+
// to use Browserify's `util` instead of Node's. And Browserify's
|
|
225
|
+
// polyfill is missing TextEncoder+TextDecoder. The reason it's using
|
|
226
|
+
// the Browserify polyfill is because we have
|
|
227
|
+
// `vite-plugin-node-polyfills` as a dependency, and that'll add
|
|
228
|
+
// Browserify's `node-util` to `node_modules`, so when Vite goes to
|
|
229
|
+
// resolve `import { TextEncoder } from 'util` it'll find the one in
|
|
230
|
+
// `node_modules` instead of Node's internal version.
|
|
231
|
+
// We only see this in dev, and not in prod. I'm not entirely sure why
|
|
232
|
+
// but I have two guesses: 1. When RSC is enabled we don't actually use
|
|
233
|
+
// `vite-plugin-node-polyfill`, so some kind of tree shaking is
|
|
234
|
+
// happening, which prevents the issue from occurring. 2. In prod we
|
|
235
|
+
// only use Node's dependency resolution. Vite is not involved. And
|
|
236
|
+
// that difference in resolution is what prevents the issue from
|
|
237
|
+
// occurring.
|
|
238
|
+
exclude: ["util"]
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
resolve: {
|
|
242
|
+
conditions: ["react-server"]
|
|
243
|
+
},
|
|
244
|
+
plugins: [
|
|
245
|
+
{
|
|
246
|
+
name: "rsc-record-and-tranform-use-client-plugin",
|
|
247
|
+
transform(code, id, _options) {
|
|
248
|
+
globalThis.__cedarjs__client_references?.delete(id);
|
|
249
|
+
if (!/^(["'])use client\1/.test(code)) {
|
|
250
|
+
return void 0;
|
|
251
|
+
}
|
|
252
|
+
console.log(
|
|
253
|
+
"rsc-record-and-transform-use-client-plugin: adding client reference",
|
|
254
|
+
id
|
|
255
|
+
);
|
|
256
|
+
globalThis.__cedarjs__client_references?.add(id);
|
|
257
|
+
const fns = code.matchAll(/export function (\w+)\(/g);
|
|
258
|
+
const consts = code.matchAll(/export const (\w+) = \(/g);
|
|
259
|
+
const names = [...fns, ...consts].map(([, name]) => name);
|
|
260
|
+
const result = [
|
|
261
|
+
`import { registerClientReference } from "react-server-dom-webpack/server.edge";`,
|
|
262
|
+
"",
|
|
263
|
+
...names.map((name) => {
|
|
264
|
+
return name === "default" ? `export default registerClientReference({}, "${id}", "${name}");` : `export const ${name} = registerClientReference({}, "${id}", "${name}");`;
|
|
265
|
+
})
|
|
266
|
+
].join("\n");
|
|
267
|
+
console.log("rsc-record-and-transform-use-client-plugin result");
|
|
268
|
+
console.log(
|
|
269
|
+
result.split("\n").map((line, i) => ` ${i + 1}: ${line}`).join("\n")
|
|
270
|
+
);
|
|
271
|
+
return { code: result, map: null };
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
rscTransformUseServerPlugin("", {}),
|
|
275
|
+
// The rscTransformUseClientPlugin maps paths like
|
|
276
|
+
// /Users/tobbe/.../rw-app/node_modules/@tobbe.dev/rsc-test/dist/rsc-test.es.js
|
|
277
|
+
// to
|
|
278
|
+
// /Users/tobbe/.../rw-app/web/dist/ssr/assets/rsc0.js
|
|
279
|
+
// That's why it needs the `clientEntryFiles` data
|
|
280
|
+
// (It does other things as well, but that's why it needs clientEntryFiles)
|
|
281
|
+
// rscTransformUseClientPlugin(clientEntryFiles),
|
|
282
|
+
// rscTransformUseServerPlugin(outDir, serverEntryFiles),
|
|
283
|
+
rscRoutesImports(),
|
|
284
|
+
{
|
|
285
|
+
name: "rsc-hot-update",
|
|
286
|
+
handleHotUpdate(ctx) {
|
|
287
|
+
console.log("rsc-hot-update ctx.modules", ctx.modules);
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
],
|
|
292
|
+
build: {
|
|
293
|
+
ssr: true
|
|
294
|
+
},
|
|
295
|
+
server: {
|
|
296
|
+
// We never call `viteRscServer.listen()`, so we should run this in
|
|
297
|
+
// middleware mode
|
|
298
|
+
middlewareMode: true,
|
|
299
|
+
// The hmr/fast-refresh websocket in this server collides with the one in
|
|
300
|
+
// the other Vite server. So we can either disable it or run it on a
|
|
301
|
+
// different port.
|
|
302
|
+
// TODO (RSC): Figure out if we should disable or just pick a different
|
|
303
|
+
// port
|
|
304
|
+
ws: false
|
|
305
|
+
// hmr: {
|
|
306
|
+
// port: 24679,
|
|
307
|
+
// },
|
|
308
|
+
},
|
|
309
|
+
appType: "custom",
|
|
310
|
+
// Using a unique cache dir here to not clash with our other vite server
|
|
311
|
+
cacheDir: "../node_modules/.vite-rsc"
|
|
312
|
+
});
|
|
313
|
+
globalThis.__cedarjs__vite_rsc_runtime = await createViteRuntime(viteRscServer);
|
|
68
314
|
const handleWithMiddleware = (route) => {
|
|
69
315
|
return createServerAdapter(async (req) => {
|
|
70
|
-
const middlewareRouter = await createMiddlewareRouter(
|
|
316
|
+
const middlewareRouter = await createMiddlewareRouter(viteSsrDevServer);
|
|
71
317
|
const middleware = middlewareRouter.find(
|
|
72
318
|
req.method,
|
|
73
319
|
req.url
|
|
@@ -77,19 +323,22 @@ async function createServer() {
|
|
|
77
323
|
}
|
|
78
324
|
const [mwRes] = await invoke(req, middleware, {
|
|
79
325
|
route,
|
|
80
|
-
|
|
326
|
+
viteSsrDevServer
|
|
81
327
|
});
|
|
82
328
|
return mwRes.toResponse();
|
|
83
329
|
});
|
|
84
330
|
};
|
|
85
|
-
app.use(
|
|
331
|
+
app.use(viteSsrDevServer.middlewares);
|
|
86
332
|
if (rscEnabled) {
|
|
87
|
-
|
|
333
|
+
createWebSocketServer();
|
|
334
|
+
const { createRscRequestHandler } = await globalThis.__cedarjs__vite_rsc_runtime.executeUrl(
|
|
335
|
+
new URL("./rsc/rscRequestHandler.js", import.meta.url).pathname
|
|
336
|
+
);
|
|
88
337
|
app.use(
|
|
89
338
|
"/rw-rsc",
|
|
90
|
-
createRscRequestHandler({
|
|
91
|
-
getMiddlewareRouter: async () => createMiddlewareRouter(
|
|
92
|
-
|
|
339
|
+
await createRscRequestHandler({
|
|
340
|
+
getMiddlewareRouter: async () => createMiddlewareRouter(viteSsrDevServer),
|
|
341
|
+
viteSsrDevServer
|
|
93
342
|
})
|
|
94
343
|
);
|
|
95
344
|
}
|
|
@@ -99,18 +348,22 @@ async function createServer() {
|
|
|
99
348
|
routes,
|
|
100
349
|
clientEntryPath: rwPaths.web.entryClient,
|
|
101
350
|
getStylesheetLinks: (route) => {
|
|
102
|
-
return getCssLinks({
|
|
351
|
+
return getCssLinks({
|
|
352
|
+
rwPaths,
|
|
353
|
+
route,
|
|
354
|
+
viteSsrDevServer
|
|
355
|
+
});
|
|
103
356
|
},
|
|
104
357
|
// Recreate middleware router on each request in dev
|
|
105
|
-
getMiddlewareRouter: async () => createMiddlewareRouter(
|
|
358
|
+
getMiddlewareRouter: async () => createMiddlewareRouter(viteSsrDevServer)
|
|
106
359
|
},
|
|
107
|
-
|
|
360
|
+
viteSsrDevServer
|
|
108
361
|
);
|
|
109
362
|
app.get("*", createServerAdapter(routeHandler));
|
|
110
363
|
app.post("*", handleWithMiddleware());
|
|
111
364
|
const port = getConfig().web.port;
|
|
112
365
|
console.log(`Started server on http://localhost:${port}`);
|
|
113
|
-
return
|
|
366
|
+
return server.listen(port);
|
|
114
367
|
}
|
|
115
368
|
let devApp = createServer();
|
|
116
369
|
process.stdin.on("data", async (data) => {
|
|
@@ -125,11 +378,11 @@ process.stdin.on("data", async (data) => {
|
|
|
125
378
|
function getCssLinks({
|
|
126
379
|
rwPaths,
|
|
127
380
|
route,
|
|
128
|
-
|
|
381
|
+
viteSsrDevServer
|
|
129
382
|
}) {
|
|
130
383
|
const appAndRouteModules = componentsModules(
|
|
131
384
|
[rwPaths.web.app, route?.filePath].filter(Boolean),
|
|
132
|
-
|
|
385
|
+
viteSsrDevServer
|
|
133
386
|
);
|
|
134
387
|
const collectedCss = collectCssPaths(appAndRouteModules);
|
|
135
388
|
const cssLinks = Array.from(collectedCss);
|
|
@@ -55,6 +55,15 @@ function registerFwShims() {
|
|
|
55
55
|
globalThis.__rw_module_cache__ ||= /* @__PURE__ */ new Map();
|
|
56
56
|
globalThis.__webpack_chunk_load__ ||= async (id) => {
|
|
57
57
|
console.log("registerFwShims chunk load id", id);
|
|
58
|
+
if (globalThis.__cedarjs__vite_ssr_runtime) {
|
|
59
|
+
return globalThis.__cedarjs__vite_ssr_runtime?.executeUrl(id).then((mod) => {
|
|
60
|
+
console.log("registerFwShims chunk load mod", mod);
|
|
61
|
+
if (mod.default && typeof mod.default === "object") {
|
|
62
|
+
return globalThis.__rw_module_cache__.set(id, mod.default);
|
|
63
|
+
}
|
|
64
|
+
return globalThis.__rw_module_cache__.set(id, mod);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
58
67
|
return import(id).then((mod) => {
|
|
59
68
|
console.log("registerFwShims chunk load mod", mod);
|
|
60
69
|
if (mod.default && typeof mod.default === "object") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-rsc-ssr-router-import.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-rsc-ssr-router-import.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAKlC;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"vite-plugin-rsc-ssr-router-import.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-rsc-ssr-router-import.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAKlC;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAsC3C"}
|
|
@@ -11,8 +11,8 @@ function rscSsrRouterImport() {
|
|
|
11
11
|
const routesFileId = normalizePath(getPaths().web.routes);
|
|
12
12
|
return {
|
|
13
13
|
name: "rsc-ssr-router-import",
|
|
14
|
-
transform: async function(code, id) {
|
|
15
|
-
if (id !== routesFileId) {
|
|
14
|
+
transform: async function(code, id, options) {
|
|
15
|
+
if (!options?.ssr || id !== routesFileId) {
|
|
16
16
|
return null;
|
|
17
17
|
}
|
|
18
18
|
const ext = path.extname(id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-rsc-transform-server.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-rsc-transform-server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC,MAAM,
|
|
1
|
+
{"version":3,"file":"vite-plugin-rsc-transform-server.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-rsc-transform-server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC,MAAM,CAuHR"}
|
|
@@ -8,6 +8,10 @@ function rscTransformUseServerPlugin(outDir, serverEntryFiles) {
|
|
|
8
8
|
if (!code.includes("use server")) {
|
|
9
9
|
return code;
|
|
10
10
|
}
|
|
11
|
+
if (id.includes("node_modules/.vite") || id.includes("/react-server-dom-webpack/") || id.includes("/react-server-dom-webpack.server")) {
|
|
12
|
+
console.log("vite-plugin-rsc-transform-server.ts: Skipping", id);
|
|
13
|
+
return code;
|
|
14
|
+
}
|
|
11
15
|
let mod;
|
|
12
16
|
const isTypescript = id.endsWith(".ts") || id.endsWith(".tsx");
|
|
13
17
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rscRenderer.d.ts","sourceRoot":"","sources":["../../src/rsc/rscRenderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"rscRenderer.d.ts","sourceRoot":"","sources":["../../src/rsc/rscRenderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AASrD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,SAAS,CAAA;CAC7B,CAAA;AAID,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,cAAc,CAAC,CAEzB;AAyCD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CA2BtD"}
|