rwsdk 1.4.1 → 1.5.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/dist/lib/e2e/environment.d.mts +1 -1
- package/dist/lib/e2e/environment.mjs +28 -1
- package/dist/lib/e2e/tarball.d.mts +2 -1
- package/dist/lib/e2e/tarball.mjs +2 -2
- package/dist/lib/e2e/testHarness.d.mts +5 -0
- package/dist/lib/e2e/testHarness.mjs +7 -1
- package/dist/lib/smokeTests/environment.mjs +1 -0
- package/dist/lib/smokeTests/types.d.mts +1 -0
- package/dist/runtime/render/assembleDocument.js +1 -1
- package/dist/runtime/render/renderDocumentHtmlStream.js +1 -1
- package/dist/runtime/render/stylesheets.js +22 -0
- package/dist/scripts/smoke-test.mjs +8 -0
- package/dist/vite/addOptimizeDepsPlugin.d.mts +10 -0
- package/dist/vite/addOptimizeDepsPlugin.mjs +6 -0
- package/dist/vite/buildApp.mjs +54 -15
- package/dist/vite/configPlugin.mjs +27 -20
- package/dist/vite/createDirectiveLookupPlugin.mjs +11 -15
- package/dist/vite/directiveModulesDevPlugin.mjs +86 -103
- package/dist/vite/directivesFilteringPlugin.mjs +55 -14
- package/dist/vite/directivesPlugin.mjs +44 -87
- package/dist/vite/knownDepsResolverPlugin.mjs +29 -36
- package/dist/vite/linkerPlugin.mjs +1 -1
- package/dist/vite/prismaPlugin.mjs +7 -10
- package/dist/vite/redwoodPlugin.mjs +5 -4
- package/dist/vite/runDirectivesScan.mjs +1 -1
- package/dist/vite/ssrBridgePlugin.mjs +11 -21
- package/dist/vite/statePlugin.mjs +8 -15
- package/dist/vite/transformJsxScriptTagsPlugin.mjs +3 -3
- package/dist/vite/viteCompat.d.mts +5 -0
- package/dist/vite/viteCompat.mjs +378 -0
- package/dist/vite/viteCompat.test.d.mts +1 -0
- package/dist/vite/viteCompat.test.mjs +72 -0
- package/dist/vite/vitePreamblePlugin.d.mts +2 -153
- package/package.json +8 -7
|
@@ -5,7 +5,7 @@ export declare function getDirectoryHash(directory: string): Promise<string>;
|
|
|
5
5
|
/**
|
|
6
6
|
* Copy project to a temporary directory with a unique name
|
|
7
7
|
*/
|
|
8
|
-
export declare function copyProjectToTempDir(projectDir: string, resourceUniqueKey: string, packageManager?: PackageManager, monorepoRoot?: string, installDependenciesRetries?: number): Promise<{
|
|
8
|
+
export declare function copyProjectToTempDir(projectDir: string, resourceUniqueKey: string, packageManager?: PackageManager, monorepoRoot?: string, installDependenciesRetries?: number, viteVersion?: number): Promise<{
|
|
9
9
|
tempDir: tmp.DirectoryResult;
|
|
10
10
|
targetDir: string;
|
|
11
11
|
workerName: string;
|
|
@@ -136,7 +136,7 @@ const setTarballDependency = async (targetDir, tarballName) => {
|
|
|
136
136
|
/**
|
|
137
137
|
* Copy project to a temporary directory with a unique name
|
|
138
138
|
*/
|
|
139
|
-
export async function copyProjectToTempDir(projectDir, resourceUniqueKey, packageManager, monorepoRoot, installDependenciesRetries) {
|
|
139
|
+
export async function copyProjectToTempDir(projectDir, resourceUniqueKey, packageManager, monorepoRoot, installDependenciesRetries, viteVersion) {
|
|
140
140
|
const { tarballPath, cleanupTarball } = await createSdkTarball();
|
|
141
141
|
try {
|
|
142
142
|
log("Creating temporary directory for project");
|
|
@@ -249,6 +249,33 @@ export async function copyProjectToTempDir(projectDir, resourceUniqueKey, packag
|
|
|
249
249
|
log("Created .yarnrc with cache-folder for yarn-classic");
|
|
250
250
|
}
|
|
251
251
|
await setTarballDependency(targetDir, tarballFilename);
|
|
252
|
+
if (viteVersion === 7) {
|
|
253
|
+
log("Patching package.json for Vite 7 compatibility");
|
|
254
|
+
const pkgJsonPath = join(targetDir, "package.json");
|
|
255
|
+
const pkgJson = JSON.parse(await fs.promises.readFile(pkgJsonPath, "utf-8"));
|
|
256
|
+
pkgJson.devDependencies ??= {};
|
|
257
|
+
pkgJson.devDependencies.vite = "~7.3.5";
|
|
258
|
+
pkgJson.devDependencies["@vitejs/plugin-react"] = "~5.1.4";
|
|
259
|
+
await fs.promises.writeFile(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
260
|
+
const viteConfigExtensions = [".mts", ".ts", ".js", ".mjs", ".cjs"];
|
|
261
|
+
let viteConfigPath;
|
|
262
|
+
for (const ext of viteConfigExtensions) {
|
|
263
|
+
const candidate = join(targetDir, `vite.config${ext}`);
|
|
264
|
+
if (await pathExists(candidate)) {
|
|
265
|
+
viteConfigPath = candidate;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (viteConfigPath) {
|
|
270
|
+
log("Patching %s to include @vitejs/plugin-react", basename(viteConfigPath));
|
|
271
|
+
let viteConfig = await fs.promises.readFile(viteConfigPath, "utf-8");
|
|
272
|
+
if (!viteConfig.includes("@vitejs/plugin-react")) {
|
|
273
|
+
viteConfig = `import react from "@vitejs/plugin-react";\n${viteConfig}`;
|
|
274
|
+
viteConfig = viteConfig.replace(/plugins:\s*\[/, "plugins: [\n react(),");
|
|
275
|
+
await fs.promises.writeFile(viteConfigPath, viteConfig);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
252
279
|
// Install dependencies in the target directory
|
|
253
280
|
const installDir = monorepoRoot ? tempCopyRoot : targetDir;
|
|
254
281
|
await retry(() => installDependencies(installDir, packageManager, projectDir, monorepoRoot), {
|
|
@@ -2,6 +2,7 @@ interface SetupTarballOptions {
|
|
|
2
2
|
projectDir: string;
|
|
3
3
|
monorepoRoot?: string;
|
|
4
4
|
packageManager?: "pnpm" | "npm" | "yarn" | "yarn-classic";
|
|
5
|
+
viteVersion?: number;
|
|
5
6
|
}
|
|
6
7
|
interface TarballEnvironment {
|
|
7
8
|
targetDir: string;
|
|
@@ -10,5 +11,5 @@ interface TarballEnvironment {
|
|
|
10
11
|
/**
|
|
11
12
|
* Creates a tarball-based test environment similar to the release script approach
|
|
12
13
|
*/
|
|
13
|
-
export declare function setupTarballEnvironment({ projectDir, monorepoRoot, packageManager, }: SetupTarballOptions): Promise<TarballEnvironment>;
|
|
14
|
+
export declare function setupTarballEnvironment({ projectDir, monorepoRoot, packageManager, viteVersion, }: SetupTarballOptions): Promise<TarballEnvironment>;
|
|
14
15
|
export {};
|
package/dist/lib/e2e/tarball.mjs
CHANGED
|
@@ -65,7 +65,7 @@ async function copyWranglerCache(targetDir, sdkRoot) {
|
|
|
65
65
|
/**
|
|
66
66
|
* Creates a tarball-based test environment similar to the release script approach
|
|
67
67
|
*/
|
|
68
|
-
export async function setupTarballEnvironment({ projectDir, monorepoRoot, packageManager = "pnpm", }) {
|
|
68
|
+
export async function setupTarballEnvironment({ projectDir, monorepoRoot, packageManager = "pnpm", viteVersion, }) {
|
|
69
69
|
log(`🚀 Setting up tarball environment for ${projectDir}`);
|
|
70
70
|
// Generate a resource unique key for this test run
|
|
71
71
|
// Use just the hash to keep worker names short (under Cloudflare's 54 char limit)
|
|
@@ -75,7 +75,7 @@ export async function setupTarballEnvironment({ projectDir, monorepoRoot, packag
|
|
|
75
75
|
.substring(0, 8);
|
|
76
76
|
const resourceUniqueKey = hash;
|
|
77
77
|
try {
|
|
78
|
-
const { tempDir, targetDir } = await copyProjectToTempDir(projectDir, resourceUniqueKey, packageManager, monorepoRoot);
|
|
78
|
+
const { tempDir, targetDir } = await copyProjectToTempDir(projectDir, resourceUniqueKey, packageManager, monorepoRoot, undefined, viteVersion);
|
|
79
79
|
// Copy wrangler cache to improve deployment performance
|
|
80
80
|
const sdkRoot = ROOT_DIR;
|
|
81
81
|
await copyWranglerCache(targetDir, sdkRoot);
|
|
@@ -45,6 +45,11 @@ export interface SetupPlaygroundEnvironmentOptions {
|
|
|
45
45
|
* @default true
|
|
46
46
|
*/
|
|
47
47
|
autoStartDevServer?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Major Vite version to test against. When set to 7, the test project
|
|
50
|
+
* is patched to use Vite 7 + @vitejs/plugin-react 5.
|
|
51
|
+
*/
|
|
52
|
+
viteVersion?: number;
|
|
48
53
|
}
|
|
49
54
|
/**
|
|
50
55
|
* A Vitest hook that sets up a playground environment for a test file.
|
|
@@ -109,9 +109,13 @@ function getPlaygroundDirFromImportMeta(importMetaUrl) {
|
|
|
109
109
|
* This ensures that tests run in a clean, isolated environment.
|
|
110
110
|
*/
|
|
111
111
|
export function setupPlaygroundEnvironment(options) {
|
|
112
|
-
const { sourceProjectDir, monorepoRoot, dev = true, deploy = true, autoStartDevServer = true, } = typeof options === "string"
|
|
112
|
+
const { sourceProjectDir, monorepoRoot, dev = true, deploy = true, autoStartDevServer = true, viteVersion: explicitViteVersion, } = typeof options === "string"
|
|
113
113
|
? { sourceProjectDir: options, autoStartDevServer: true }
|
|
114
114
|
: options;
|
|
115
|
+
const envViteVersion = process.env.RWSDK_VITE_VERSION
|
|
116
|
+
? Number(process.env.RWSDK_VITE_VERSION)
|
|
117
|
+
: undefined;
|
|
118
|
+
const viteVersion = explicitViteVersion ?? envViteVersion;
|
|
115
119
|
ensureHooksRegistered();
|
|
116
120
|
beforeAll(async () => {
|
|
117
121
|
let projectDir;
|
|
@@ -132,6 +136,7 @@ export function setupPlaygroundEnvironment(options) {
|
|
|
132
136
|
projectDir,
|
|
133
137
|
monorepoRoot,
|
|
134
138
|
packageManager: process.env.PACKAGE_MANAGER || "pnpm",
|
|
139
|
+
viteVersion,
|
|
135
140
|
});
|
|
136
141
|
globalDevPlaygroundEnv = {
|
|
137
142
|
projectDir: devEnv.targetDir,
|
|
@@ -156,6 +161,7 @@ export function setupPlaygroundEnvironment(options) {
|
|
|
156
161
|
projectDir,
|
|
157
162
|
monorepoRoot,
|
|
158
163
|
packageManager: process.env.PACKAGE_MANAGER || "pnpm",
|
|
164
|
+
viteVersion,
|
|
159
165
|
});
|
|
160
166
|
globalDeployPlaygroundEnv = {
|
|
161
167
|
projectDir: deployEnv.targetDir,
|
|
@@ -11,6 +11,7 @@ export async function setupTestEnvironment(options = {}) {
|
|
|
11
11
|
const tarballEnv = await setupTarballEnvironment({
|
|
12
12
|
projectDir: options.projectDir,
|
|
13
13
|
packageManager: options.packageManager,
|
|
14
|
+
viteVersion: options.viteVersion,
|
|
14
15
|
});
|
|
15
16
|
const resources = {
|
|
16
17
|
tempDirCleanup: tarballEnv.cleanup,
|
|
@@ -17,6 +17,6 @@ export const assembleDocument = ({ requestInfo, pageElement, shouldSSR, }) => {
|
|
|
17
17
|
};
|
|
18
18
|
const Document = requestInfo.rw.Document;
|
|
19
19
|
return (_jsxs(Document, { ...requestInfo, children: [_jsx("script", { nonce: requestInfo.rw.nonce, dangerouslySetInnerHTML: {
|
|
20
|
-
__html: `globalThis.__RWSDK_CONTEXT = ${JSON.stringify(clientContext)}`,
|
|
20
|
+
__html: `globalThis.__RWSDK_CONTEXT = ${JSON.stringify(clientContext)};if(!globalThis.__webpack_require__){globalThis.__webpack_require__=function(id){throw new Error("rwsdk: __webpack_require__ called before client init for: "+id)};globalThis.__webpack_require__.u=function(){}}`,
|
|
21
21
|
} }), _jsx(Stylesheets, { requestInfo: requestInfo }), _jsx(Preloads, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root", children: pageElement })] }));
|
|
22
22
|
};
|
|
@@ -20,7 +20,7 @@ export const renderDocumentHtmlStream = async ({ rscPayloadStream, Document, req
|
|
|
20
20
|
};
|
|
21
21
|
// Create the outer document with a marker for injection
|
|
22
22
|
const documentElement = (_jsxs(Document, { ...requestInfo, children: [_jsx("script", { nonce: requestInfo.rw.nonce, dangerouslySetInnerHTML: {
|
|
23
|
-
__html: `globalThis.__RWSDK_CONTEXT = ${JSON.stringify(clientContext)}`,
|
|
23
|
+
__html: `globalThis.__RWSDK_CONTEXT = ${JSON.stringify(clientContext)};if(!globalThis.__webpack_require__){globalThis.__webpack_require__=function(id){throw new Error("rwsdk: __webpack_require__ called before client init for: "+id)};globalThis.__webpack_require__.u=function(){}}`,
|
|
24
24
|
} }), _jsx(Stylesheets, { requestInfo: requestInfo }), _jsx(Preloads, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root", children: _jsx("div", { id: "rwsdk-app-start" }) })] }));
|
|
25
25
|
const outerHtmlStream = await renderHtmlStream({
|
|
26
26
|
node: documentElement,
|
|
@@ -23,6 +23,20 @@ const findCssForModule = (scriptId, manifest) => {
|
|
|
23
23
|
css.add(href);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
+
// context(justinvdm, 2026-04-23): Rolldown associates CSS with the
|
|
27
|
+
// chunk that imports the CSS file, which may be a dynamic import target
|
|
28
|
+
// rather than the entry chunk. Walk both static and dynamic imports to
|
|
29
|
+
// find CSS from transitive dependencies.
|
|
30
|
+
if (entry.imports) {
|
|
31
|
+
for (const importId of entry.imports) {
|
|
32
|
+
inner(importId);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (entry.dynamicImports) {
|
|
36
|
+
for (const importId of entry.dynamicImports) {
|
|
37
|
+
inner(importId);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
26
40
|
};
|
|
27
41
|
inner(scriptId);
|
|
28
42
|
return Array.from(css);
|
|
@@ -37,5 +51,13 @@ export const Stylesheets = async ({ requestInfo, }) => {
|
|
|
37
51
|
allStylesheets.add(toAbsoluteHref(entry));
|
|
38
52
|
}
|
|
39
53
|
}
|
|
54
|
+
for (const [, entry] of Object.entries(manifest)) {
|
|
55
|
+
if (entry.isEntry) {
|
|
56
|
+
const css = findCssForModule(entry.src ?? "", manifest);
|
|
57
|
+
for (const href of css) {
|
|
58
|
+
allStylesheets.add(toAbsoluteHref(href));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
40
62
|
return (_jsx(_Fragment, { children: Array.from(allStylesheets).map((href) => (_jsx("link", { rel: "stylesheet", href: href, precedence: "first" }, href))) }));
|
|
41
63
|
};
|
|
@@ -77,6 +77,13 @@ if (fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
|
77
77
|
else if (arg === "--realtime") {
|
|
78
78
|
options.realtime = true;
|
|
79
79
|
}
|
|
80
|
+
else if (arg.startsWith("--vite-version=")) {
|
|
81
|
+
const version = parseInt(arg.substring(15), 10);
|
|
82
|
+
if (Number.isNaN(version) || version <= 0) {
|
|
83
|
+
throw new Error(`Invalid Vite version: ${arg}`);
|
|
84
|
+
}
|
|
85
|
+
options.viteVersion = version;
|
|
86
|
+
}
|
|
80
87
|
else if (arg === "--help" || arg === "-h") {
|
|
81
88
|
// Display help text
|
|
82
89
|
console.log(`
|
|
@@ -99,6 +106,7 @@ Options:
|
|
|
99
106
|
--bail Stop on first test failure
|
|
100
107
|
--copy-project Copy the project to the artifacts directory
|
|
101
108
|
--realtime Only run realtime smoke tests, skip initial tests
|
|
109
|
+
--vite-version=VERSION Major Vite version to test against (default: current, e.g. --vite-version=7)
|
|
102
110
|
--help Show this help message
|
|
103
111
|
`);
|
|
104
112
|
process.exit(0);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { EnvironmentOptions } from "vite";
|
|
2
|
+
interface OptimizeDepsPlugin {
|
|
3
|
+
name: string;
|
|
4
|
+
resolveId?: (id: string, importer: string | undefined, opts: {
|
|
5
|
+
kind: string;
|
|
6
|
+
}) => any;
|
|
7
|
+
load?: (id: string) => any;
|
|
8
|
+
}
|
|
9
|
+
export declare function addOptimizeDepsPlugin(config: EnvironmentOptions, plugin: OptimizeDepsPlugin): void;
|
|
10
|
+
export {};
|
package/dist/vite/buildApp.mjs
CHANGED
|
@@ -25,20 +25,20 @@ export async function buildApp({ builder, clientEntryPoints, clientFiles, server
|
|
|
25
25
|
await mkdir(dirname(tempEntryPath), { recursive: true });
|
|
26
26
|
}
|
|
27
27
|
await writeFile(tempEntryPath, "");
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
28
|
+
// context(justinvdm, 2026-05-13): Mutate the resolved build config in
|
|
29
|
+
// place rather than replacing the build object. Creating a new object
|
|
30
|
+
// loses Vite's rolldownOptions compat proxy, so we save and restore
|
|
31
|
+
// individual properties instead.
|
|
32
|
+
const originalWrite = workerEnv.config.build.write;
|
|
33
|
+
const originalInput = workerEnv.config.build.rolldownOptions.input;
|
|
34
|
+
workerEnv.config.build.write = false;
|
|
35
|
+
workerEnv.config.build.rolldownOptions.input = {
|
|
36
|
+
index: tempEntryPath,
|
|
38
37
|
};
|
|
39
38
|
await builder.build(workerEnv);
|
|
40
39
|
// Restore the original config
|
|
41
|
-
workerEnv.config.build =
|
|
40
|
+
workerEnv.config.build.write = originalWrite;
|
|
41
|
+
workerEnv.config.build.rolldownOptions.input = originalInput;
|
|
42
42
|
}
|
|
43
43
|
finally {
|
|
44
44
|
await rm(tempEntryPath, { force: true });
|
|
@@ -51,6 +51,19 @@ export async function buildApp({ builder, clientEntryPoints, clientFiles, server
|
|
|
51
51
|
entries: [workerEntryPathname],
|
|
52
52
|
esbuildOptions,
|
|
53
53
|
});
|
|
54
|
+
// context(justinvdm, 2026-05-13): In Vite 8 (Rolldown), the worker build
|
|
55
|
+
// fragments into hundreds of tiny chunks by default. Disabling code
|
|
56
|
+
// splitting forces a single consolidated intermediate worker file, matching
|
|
57
|
+
// the architecture's expectation of an intermediate `worker.js` and
|
|
58
|
+
// preventing leftover artifacts from cluttering the final output.
|
|
59
|
+
workerEnv.config.build.rolldownOptions.output ??= {};
|
|
60
|
+
if (Array.isArray(workerEnv.config.build.rolldownOptions.output)) {
|
|
61
|
+
workerEnv.config.build.rolldownOptions.output.forEach((o) => (o.codeSplitting = false));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
workerEnv.config.build.rolldownOptions.output.codeSplitting =
|
|
65
|
+
false;
|
|
66
|
+
}
|
|
54
67
|
console.log("Building worker...");
|
|
55
68
|
process.env.RWSDK_BUILD_PASS = "worker";
|
|
56
69
|
await builder.build(workerEnv);
|
|
@@ -61,14 +74,14 @@ export async function buildApp({ builder, clientEntryPoints, clientFiles, server
|
|
|
61
74
|
console.log("Building client...");
|
|
62
75
|
const clientEnv = builder.environments["client"];
|
|
63
76
|
clientEnv.config.build ??= {};
|
|
64
|
-
clientEnv.config.build.
|
|
77
|
+
clientEnv.config.build.rolldownOptions ??= {};
|
|
65
78
|
const clientEntryPointsArray = Array.from(clientEntryPoints);
|
|
66
79
|
if (clientEntryPointsArray.length === 0) {
|
|
67
80
|
log("No client entry points discovered, using default: src/client.tsx");
|
|
68
|
-
clientEnv.config.build.
|
|
81
|
+
clientEnv.config.build.rolldownOptions.input = ["src/client.tsx"];
|
|
69
82
|
}
|
|
70
83
|
else {
|
|
71
|
-
clientEnv.config.build.
|
|
84
|
+
clientEnv.config.build.rolldownOptions.input = clientEntryPointsArray;
|
|
72
85
|
}
|
|
73
86
|
await builder.build(clientEnv);
|
|
74
87
|
console.log("Linking worker build...");
|
|
@@ -82,10 +95,36 @@ export async function buildApp({ builder, clientEntryPoints, clientFiles, server
|
|
|
82
95
|
// directly. Instead, we re-point the original entry to the intermediate
|
|
83
96
|
// worker bundle from the first pass. This allows the linker pass to re-use
|
|
84
97
|
// the same plugin-driven configuration while bundling the final worker.
|
|
85
|
-
workerConfig.build.
|
|
98
|
+
workerConfig.build.rolldownOptions.input = {
|
|
86
99
|
index: resolve(projectRootDir, "dist", "worker", "index.js"),
|
|
87
100
|
};
|
|
101
|
+
// context(justinvdm, 2026-05-13): In Vite 8 (Rolldown), the linker pass
|
|
102
|
+
// was producing hundreds of tiny chunks instead of a single consolidated
|
|
103
|
+
// worker bundle. Setting codeSplitting:false forces all code (including
|
|
104
|
+
// dynamic imports from the intermediate worker artifact) into the entry
|
|
105
|
+
// chunk, restoring the single-file worker output the architecture expects.
|
|
106
|
+
workerConfig.build.rolldownOptions.output ??= {};
|
|
107
|
+
if (Array.isArray(workerConfig.build.rolldownOptions.output)) {
|
|
108
|
+
workerConfig.build.rolldownOptions.output.forEach((o) => (o.codeSplitting = false));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
workerConfig.build.rolldownOptions.output.codeSplitting = false;
|
|
112
|
+
}
|
|
88
113
|
await builder.build(workerEnv);
|
|
114
|
+
// Remove first-pass JS artifacts that are now inlined into the final worker
|
|
115
|
+
// bundle. Without this cleanup, ~480 leftover chunks from the first pass
|
|
116
|
+
// clutter dist/worker/assets/ and inflate deployment file counts.
|
|
117
|
+
const workerAssetsDir = resolve(projectRootDir, "dist", "worker", "assets");
|
|
118
|
+
try {
|
|
119
|
+
for (const entry of await readdir(workerAssetsDir)) {
|
|
120
|
+
if (entry.endsWith(".js") || entry.endsWith(".js.map")) {
|
|
121
|
+
await rm(join(workerAssetsDir, entry), { force: true });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Directory may not exist (e.g. if the app has no worker assets)
|
|
127
|
+
}
|
|
89
128
|
console.log("Build complete!");
|
|
90
129
|
// context(zshannon, 16 Mar 2026): Nest client output under base subdirectory
|
|
91
130
|
// for Cloudflare's assets module, which maps URL paths directly to file paths.
|
|
@@ -50,11 +50,13 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
50
50
|
],
|
|
51
51
|
exclude: [],
|
|
52
52
|
entries: [workerEntryPathname],
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
rolldownOptions: {
|
|
54
|
+
transform: {
|
|
55
|
+
jsx: "react-jsx",
|
|
56
|
+
define: {
|
|
57
|
+
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
58
|
+
"__webpack_require__": "globalThis.__webpack_require__",
|
|
59
|
+
},
|
|
58
60
|
},
|
|
59
61
|
},
|
|
60
62
|
},
|
|
@@ -70,6 +72,9 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
70
72
|
appType: "custom",
|
|
71
73
|
mode,
|
|
72
74
|
logLevel: silent ? "silent" : "info",
|
|
75
|
+
resolve: {
|
|
76
|
+
tsconfigPaths: true,
|
|
77
|
+
},
|
|
73
78
|
build: {
|
|
74
79
|
minify: mode !== "development",
|
|
75
80
|
sourcemap,
|
|
@@ -86,7 +91,7 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
86
91
|
build: {
|
|
87
92
|
outDir: resolve(projectRootDir, "dist", "client"),
|
|
88
93
|
manifest: true,
|
|
89
|
-
|
|
94
|
+
rolldownOptions: {
|
|
90
95
|
input: [],
|
|
91
96
|
},
|
|
92
97
|
},
|
|
@@ -105,12 +110,13 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
105
110
|
"rwsdk/use-synced-state/client",
|
|
106
111
|
],
|
|
107
112
|
entries: [],
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
rolldownOptions: {
|
|
114
|
+
transform: {
|
|
115
|
+
jsx: "react-jsx",
|
|
116
|
+
define: {
|
|
117
|
+
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
118
|
+
"__webpack_require__": "globalThis.__webpack_require__",
|
|
119
|
+
},
|
|
114
120
|
},
|
|
115
121
|
},
|
|
116
122
|
},
|
|
@@ -143,12 +149,13 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
143
149
|
"rwsdk/realtime/worker",
|
|
144
150
|
"rwsdk/use-synced-state/client",
|
|
145
151
|
],
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
rolldownOptions: {
|
|
153
|
+
transform: {
|
|
154
|
+
jsx: "react-jsx",
|
|
155
|
+
define: {
|
|
156
|
+
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
157
|
+
"__webpack_require__": "globalThis.__webpack_require__",
|
|
158
|
+
},
|
|
152
159
|
},
|
|
153
160
|
},
|
|
154
161
|
},
|
|
@@ -161,7 +168,7 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
161
168
|
fileName: () => path.basename(INTERMEDIATE_SSR_BRIDGE_PATH),
|
|
162
169
|
},
|
|
163
170
|
outDir: path.dirname(INTERMEDIATE_SSR_BRIDGE_PATH),
|
|
164
|
-
|
|
171
|
+
rolldownOptions: {
|
|
165
172
|
output: {
|
|
166
173
|
// context(justinvdm, 15 Sep 2025): The SSR bundle is a
|
|
167
174
|
// pre-compiled artifact. When the linker pass bundles it into
|
|
@@ -176,7 +183,7 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
|
|
|
176
183
|
// context(justinvdm, 19 Nov 2025): We use a custom plugin
|
|
177
184
|
// (ssrBridgeWrapPlugin) to intelligently inject the IIFE *after*
|
|
178
185
|
// any top-level external imports, ensuring they remain valid.
|
|
179
|
-
|
|
186
|
+
codeSplitting: false,
|
|
180
187
|
},
|
|
181
188
|
plugins: [ssrBridgeWrapPlugin()],
|
|
182
189
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
2
|
import MagicString from "magic-string";
|
|
3
3
|
import path from "path";
|
|
4
|
+
import { addOptimizeDepsPlugin } from "./addOptimizeDepsPlugin.mjs";
|
|
4
5
|
import { VENDOR_CLIENT_BARREL_EXPORT_PATH, VENDOR_SERVER_BARREL_EXPORT_PATH, } from "../lib/constants.mjs";
|
|
5
6
|
export function generateLookupMap({ files, isDev, kind, exportName, }) {
|
|
6
7
|
const s = new MagicString(`
|
|
@@ -55,32 +56,27 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
|
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
57
58
|
log("Configuring environment: env=%s", env);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
viteConfig
|
|
59
|
+
const escapedVirtualModuleName = config.virtualModuleName.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
60
|
+
const escapedPrefixedModuleName = `/@id/${config.virtualModuleName}`.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
61
|
+
const lookupFilter = new RegExp(`^(${escapedVirtualModuleName}|${escapedPrefixedModuleName})\\.js$`);
|
|
62
|
+
addOptimizeDepsPlugin(viteConfig, {
|
|
62
63
|
name: `rwsdk:${config.pluginName}`,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// Handle both direct virtual module name and /@id/ prefixed version
|
|
66
|
-
const escapedVirtualModuleName = config.virtualModuleName.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
67
|
-
const escapedPrefixedModuleName = `/@id/${config.virtualModuleName}`.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
68
|
-
build.onResolve({
|
|
69
|
-
filter: new RegExp(`^(${escapedVirtualModuleName}|${escapedPrefixedModuleName})\\.js$`),
|
|
70
|
-
}, () => {
|
|
64
|
+
resolveId(id) {
|
|
65
|
+
if (lookupFilter.test(id)) {
|
|
71
66
|
process.env.VERBOSE &&
|
|
72
|
-
log("
|
|
67
|
+
log("Marking %s as external", config.virtualModuleName);
|
|
73
68
|
return {
|
|
74
|
-
|
|
69
|
+
id: `${config.virtualModuleName}.js`,
|
|
75
70
|
external: true,
|
|
76
71
|
};
|
|
77
|
-
}
|
|
72
|
+
}
|
|
78
73
|
},
|
|
79
74
|
});
|
|
80
75
|
const shouldOptimizeForEnv = !config.optimizeForEnvironments ||
|
|
81
76
|
config.optimizeForEnvironments.includes(env);
|
|
82
77
|
if (shouldOptimizeForEnv) {
|
|
83
78
|
log("Applying optimizeDeps and aliasing for environment: %s", env);
|
|
79
|
+
viteConfig.optimizeDeps ??= {};
|
|
84
80
|
viteConfig.optimizeDeps.include ??= [];
|
|
85
81
|
for (const file of files) {
|
|
86
82
|
if (file.includes("node_modules")) {
|