rwsdk 0.1.14 → 0.1.15
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/vite/configPlugin.d.mts +1 -2
- package/dist/vite/configPlugin.mjs +10 -3
- package/dist/vite/createDirectiveLookupPlugin.mjs +24 -21
- package/dist/vite/directivesPlugin.mjs +11 -7
- package/dist/vite/findSpecifiers.mjs +2 -2
- package/dist/vite/findSsrSpecifiers.mjs +1 -1
- package/dist/vite/injectVitePreamblePlugin.d.mts +1 -2
- package/dist/vite/injectVitePreamblePlugin.mjs +2 -2
- package/dist/vite/miniflareHMRPlugin.mjs +4 -2
- package/dist/vite/mode.d.mts +5 -0
- package/dist/vite/mode.mjs +25 -0
- package/dist/vite/modePlugin.d.mts +2 -0
- package/dist/vite/modePlugin.mjs +10 -0
- package/dist/vite/reactConditionsResolverPlugin.mjs +21 -12
- package/dist/vite/redwoodPlugin.d.mts +0 -1
- package/dist/vite/redwoodPlugin.mjs +1 -4
- package/dist/vite/ssrBridgePlugin.mjs +13 -9
- package/dist/vite/transformClientComponents.mjs +9 -8
- package/dist/vite/transformServerFunctions.mjs +18 -12
- package/package.json +1 -1
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
2
|
export declare const cloudflareBuiltInModules: string[];
|
|
3
3
|
export declare const externalModules: string[];
|
|
4
|
-
export declare const configPlugin: ({
|
|
5
|
-
mode: "development" | "production";
|
|
4
|
+
export declare const configPlugin: ({ silent, projectRootDir, clientEntryPathnames, workerEntryPathname, }: {
|
|
6
5
|
silent: boolean;
|
|
7
6
|
projectRootDir: string;
|
|
8
7
|
clientEntryPathnames: string[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path, { resolve } from "node:path";
|
|
2
|
+
import { builtinModules } from "node:module";
|
|
2
3
|
import enhancedResolve from "enhanced-resolve";
|
|
3
4
|
import { SSR_BRIDGE_PATH } from "../lib/constants.mjs";
|
|
4
|
-
import { builtinModules } from "node:module";
|
|
5
5
|
// port(justinvdm, 09 Jun 2025):
|
|
6
6
|
// https://github.com/cloudflare/workers-sdk/blob/d533f5ee7da69c205d8d5e2a5f264d2370fc612b/packages/vite-plugin-cloudflare/src/cloudflare-environment.ts#L123-L128
|
|
7
7
|
export const cloudflareBuiltInModules = [
|
|
@@ -15,9 +15,10 @@ export const externalModules = [
|
|
|
15
15
|
...builtinModules,
|
|
16
16
|
...builtinModules.map((m) => `node:${m}`),
|
|
17
17
|
];
|
|
18
|
-
export const configPlugin = ({
|
|
18
|
+
export const configPlugin = ({ silent, projectRootDir, clientEntryPathnames, workerEntryPathname, }) => ({
|
|
19
19
|
name: "rwsdk:config",
|
|
20
|
-
config: (_
|
|
20
|
+
config: async (_) => {
|
|
21
|
+
const mode = process.env.NODE_ENV;
|
|
21
22
|
const baseConfig = {
|
|
22
23
|
appType: "custom",
|
|
23
24
|
mode,
|
|
@@ -78,6 +79,9 @@ export const configPlugin = ({ mode, silent, projectRootDir, clientEntryPathname
|
|
|
78
79
|
jsx: "automatic",
|
|
79
80
|
jsxImportSource: "react",
|
|
80
81
|
plugins: [],
|
|
82
|
+
define: {
|
|
83
|
+
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
84
|
+
},
|
|
81
85
|
},
|
|
82
86
|
},
|
|
83
87
|
build: {
|
|
@@ -121,6 +125,9 @@ export const configPlugin = ({ mode, silent, projectRootDir, clientEntryPathname
|
|
|
121
125
|
esbuildOptions: {
|
|
122
126
|
jsx: "automatic",
|
|
123
127
|
jsxImportSource: "react",
|
|
128
|
+
define: {
|
|
129
|
+
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
130
|
+
},
|
|
124
131
|
},
|
|
125
132
|
},
|
|
126
133
|
build: {
|
|
@@ -9,7 +9,6 @@ import { getSrcPaths } from "../lib/getSrcPaths.js";
|
|
|
9
9
|
import { hasDirective } from "./hasDirective.mjs";
|
|
10
10
|
export const findFilesContainingDirective = async ({ projectRootDir, files, directive, debugNamespace, }) => {
|
|
11
11
|
const log = debug(debugNamespace);
|
|
12
|
-
const verboseLog = debug(`verbose:${debugNamespace}`);
|
|
13
12
|
log("Starting search for '%s' files in projectRootDir=%s", directive, projectRootDir);
|
|
14
13
|
const filesToScan = await getSrcPaths(projectRootDir);
|
|
15
14
|
log("Found %d files to scan for '%s' directive", filesToScan.length, directive);
|
|
@@ -17,10 +16,10 @@ export const findFilesContainingDirective = async ({ projectRootDir, files, dire
|
|
|
17
16
|
try {
|
|
18
17
|
const stats = await stat(file);
|
|
19
18
|
if (!stats.isFile()) {
|
|
20
|
-
|
|
19
|
+
process.env.VERBOSE && log("Skipping %s (not a file)", file);
|
|
21
20
|
continue;
|
|
22
21
|
}
|
|
23
|
-
|
|
22
|
+
process.env.VERBOSE && log("Scanning file: %s", file);
|
|
24
23
|
const content = await readFile(file, "utf-8");
|
|
25
24
|
if (hasDirective(content, directive)) {
|
|
26
25
|
const normalizedPath = normalizeModulePath(projectRootDir, file);
|
|
@@ -33,11 +32,11 @@ export const findFilesContainingDirective = async ({ projectRootDir, files, dire
|
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
34
|
log("Completed scan. Found %d %s files total", files.size, directive);
|
|
36
|
-
|
|
35
|
+
process.env.VERBOSE &&
|
|
36
|
+
log("Found files for %s: %j", directive, Array.from(files));
|
|
37
37
|
};
|
|
38
38
|
const resolveOptimizedDep = async (projectRootDir, id, environment, debugNamespace) => {
|
|
39
39
|
const log = debug(debugNamespace);
|
|
40
|
-
const verboseLog = debug(`verbose:${debugNamespace}`);
|
|
41
40
|
try {
|
|
42
41
|
const depsDir = environment === "client" ? "deps" : `deps_${environment}`;
|
|
43
42
|
const nodeModulesDepsDirPath = path.join("node_modules", ".vite", depsDir);
|
|
@@ -57,25 +56,26 @@ const resolveOptimizedDep = async (projectRootDir, id, environment, debugNamespa
|
|
|
57
56
|
log("Found optimized dependency: filePath=%s, optimizedPath=%s", id, optimizedPath);
|
|
58
57
|
return optimizedPath;
|
|
59
58
|
}
|
|
60
|
-
|
|
59
|
+
process.env.VERBOSE &&
|
|
60
|
+
log("File not found in optimized dependencies: id=%s", id);
|
|
61
61
|
return undefined;
|
|
62
62
|
}
|
|
63
63
|
catch (error) {
|
|
64
|
-
|
|
64
|
+
process.env.VERBOSE &&
|
|
65
|
+
log("Error resolving optimized dependency for id=%s: %s", id, error);
|
|
65
66
|
return undefined;
|
|
66
67
|
}
|
|
67
68
|
};
|
|
68
69
|
const addOptimizedDepsEntries = async ({ projectRootDir, directive, environment, debugNamespace, files, }) => {
|
|
69
70
|
const log = debug(debugNamespace);
|
|
70
|
-
const verboseLog = debug(`verbose:${debugNamespace}`);
|
|
71
71
|
try {
|
|
72
72
|
const depsDir = environment === "client" ? "deps" : `deps_${environment}`;
|
|
73
73
|
const depsDirPath = path.join(projectRootDir, "node_modules", ".vite", depsDir);
|
|
74
74
|
const manifestPath = path.join(depsDirPath, "_metadata.json");
|
|
75
|
-
|
|
75
|
+
process.env.VERBOSE && log("Checking for manifest at: %s", manifestPath);
|
|
76
76
|
const manifestExists = await pathExists(manifestPath);
|
|
77
77
|
if (!manifestExists) {
|
|
78
|
-
|
|
78
|
+
process.env.VERBOSE && log("Manifest not found at %s", manifestPath);
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
const manifestContent = await readFile(manifestPath, "utf-8");
|
|
@@ -89,7 +89,8 @@ const addOptimizedDepsEntries = async ({ projectRootDir, directive, environment,
|
|
|
89
89
|
contents = await readFile(resolvedSrcPath, "utf-8");
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
|
92
|
-
|
|
92
|
+
process.env.VERBOSE &&
|
|
93
|
+
log("Error reading file %s: %s", resolvedSrcPath, error);
|
|
93
94
|
continue;
|
|
94
95
|
}
|
|
95
96
|
if (hasDirective(contents, directive)) {
|
|
@@ -103,13 +104,13 @@ const addOptimizedDepsEntries = async ({ projectRootDir, directive, environment,
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
catch (error) {
|
|
106
|
-
|
|
107
|
+
process.env.VERBOSE &&
|
|
108
|
+
log("Error adding optimized deps entries: %s", error);
|
|
107
109
|
}
|
|
108
110
|
};
|
|
109
111
|
export const createDirectiveLookupPlugin = async ({ projectRootDir, files, config, }) => {
|
|
110
112
|
const debugNamespace = `rwsdk:vite:${config.pluginName}`;
|
|
111
113
|
const log = debug(debugNamespace);
|
|
112
|
-
const verboseLog = debug(`verbose:${debugNamespace}`);
|
|
113
114
|
let isDev = false;
|
|
114
115
|
log("Initializing %s plugin with projectRootDir=%s", config.pluginName, projectRootDir);
|
|
115
116
|
await findFilesContainingDirective({
|
|
@@ -151,7 +152,8 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
|
|
|
151
152
|
build.onResolve({
|
|
152
153
|
filter: new RegExp(`^(${escapedVirtualModuleName}|${escapedPrefixedModuleName})$`),
|
|
153
154
|
}, () => {
|
|
154
|
-
|
|
155
|
+
process.env.VERBOSE &&
|
|
156
|
+
log("Esbuild onResolve: marking %s as external", config.virtualModuleName);
|
|
155
157
|
return {
|
|
156
158
|
path: config.virtualModuleName,
|
|
157
159
|
external: true,
|
|
@@ -166,7 +168,8 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
|
|
|
166
168
|
viteConfig.optimizeDeps.include ??= [];
|
|
167
169
|
for (const file of files) {
|
|
168
170
|
const actualFilePath = path.join(projectRootDir, file);
|
|
169
|
-
|
|
171
|
+
process.env.VERBOSE &&
|
|
172
|
+
log("Adding to optimizeDeps.entries: %s", actualFilePath);
|
|
170
173
|
const entries = Array.isArray(viteConfig.optimizeDeps.entries)
|
|
171
174
|
? viteConfig.optimizeDeps.entries
|
|
172
175
|
: [].concat(viteConfig.optimizeDeps.entries ?? []);
|
|
@@ -180,19 +183,19 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
|
|
|
180
183
|
}
|
|
181
184
|
},
|
|
182
185
|
resolveId(source) {
|
|
183
|
-
|
|
186
|
+
process.env.VERBOSE && log("Resolving id=%s", source);
|
|
184
187
|
if (source === config.virtualModuleName ||
|
|
185
188
|
source === `/@id/${config.virtualModuleName}` ||
|
|
186
189
|
source === `/@id/${config.virtualModuleName}.js`) {
|
|
187
190
|
log("Resolving %s module", config.virtualModuleName);
|
|
188
191
|
// context(justinvdm, 16 Jun 2025): Include .js extension
|
|
189
192
|
// so it goes through vite processing chain
|
|
190
|
-
return config.virtualModuleName
|
|
193
|
+
return `${config.virtualModuleName}.js`;
|
|
191
194
|
}
|
|
192
|
-
|
|
195
|
+
process.env.VERBOSE && log("No resolution for id=%s", source);
|
|
193
196
|
},
|
|
194
197
|
async load(id) {
|
|
195
|
-
|
|
198
|
+
process.env.VERBOSE && log("Loading id=%s", id);
|
|
196
199
|
if (id === config.virtualModuleName + ".js") {
|
|
197
200
|
log("Loading %s module with %d files", config.virtualModuleName, files.size);
|
|
198
201
|
const environment = this.environment?.name || "client";
|
|
@@ -218,13 +221,13 @@ export const ${config.exportName} = {
|
|
|
218
221
|
const code = s.toString();
|
|
219
222
|
const map = s.generateMap();
|
|
220
223
|
log("Generated virtual module code length: %d", code.length);
|
|
221
|
-
|
|
224
|
+
process.env.VERBOSE && log("Generated virtual module code: %s", code);
|
|
222
225
|
return {
|
|
223
226
|
code,
|
|
224
227
|
map,
|
|
225
228
|
};
|
|
226
229
|
}
|
|
227
|
-
|
|
230
|
+
process.env.VERBOSE && log("No load handling for id=%s", id);
|
|
228
231
|
},
|
|
229
232
|
};
|
|
230
233
|
};
|
|
@@ -5,7 +5,6 @@ import { transformClientComponents } from "./transformClientComponents.mjs";
|
|
|
5
5
|
import { transformServerFunctions } from "./transformServerFunctions.mjs";
|
|
6
6
|
import { normalizeModulePath } from "./normalizeModulePath.mjs";
|
|
7
7
|
const log = debug("rwsdk:vite:rsc-directives-plugin");
|
|
8
|
-
const verboseLog = debug("verbose:rwsdk:vite:rsc-directives-plugin");
|
|
9
8
|
const getLoader = (filePath) => {
|
|
10
9
|
const ext = path.extname(filePath).slice(1);
|
|
11
10
|
switch (ext) {
|
|
@@ -76,7 +75,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
|
|
|
76
75
|
});
|
|
77
76
|
},
|
|
78
77
|
async transform(code, id) {
|
|
79
|
-
|
|
78
|
+
process.env.VERBOSE &&
|
|
79
|
+
log("Transform called for id=%s, environment=%s", id, this.environment.name);
|
|
80
80
|
const normalizedId = normalizeModulePath(projectRootDir, id);
|
|
81
81
|
const clientResult = await transformClientComponents(code, normalizedId, {
|
|
82
82
|
environmentName: this.environment.name,
|
|
@@ -98,7 +98,7 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
|
|
|
98
98
|
map: serverResult.map,
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
|
|
101
|
+
process.env.VERBOSE && log("No transformation applied for id=%s", id);
|
|
102
102
|
},
|
|
103
103
|
configEnvironment(env, config) {
|
|
104
104
|
log("Configuring environment: env=%s", env);
|
|
@@ -110,7 +110,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
|
|
|
110
110
|
setup(build) {
|
|
111
111
|
log("Setting up esbuild plugin for environment: %s", env);
|
|
112
112
|
build.onLoad({ filter: /\.(js|ts|jsx|tsx|mts|mjs|cjs)$/ }, async (args) => {
|
|
113
|
-
|
|
113
|
+
process.env.VERBOSE &&
|
|
114
|
+
log("Esbuild onLoad called for environment=%s, path=%s", env, args.path);
|
|
114
115
|
const normalizedPath = normalizeModulePath(projectRootDir, args.path);
|
|
115
116
|
// context(justinvdm,2025-06-15): If we're in app code,
|
|
116
117
|
// we will be doing the transform work in the vite plugin hooks,
|
|
@@ -161,7 +162,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
|
|
|
161
162
|
code = await fs.readFile(args.path, "utf-8");
|
|
162
163
|
}
|
|
163
164
|
catch {
|
|
164
|
-
|
|
165
|
+
process.env.VERBOSE &&
|
|
166
|
+
log("Failed to read file: %s, environment=%s", args.path, env);
|
|
165
167
|
return undefined;
|
|
166
168
|
}
|
|
167
169
|
const clientResult = await transformClientComponents(code, normalizedPath, {
|
|
@@ -172,7 +174,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
|
|
|
172
174
|
});
|
|
173
175
|
if (clientResult) {
|
|
174
176
|
log("Esbuild client component transformation successful for environment=%s, path=%s", env, args.path);
|
|
175
|
-
|
|
177
|
+
process.env.VERBOSE &&
|
|
178
|
+
log("Esbuild client component transformation for environment=%s, path=%s, code: %j", env, args.path, clientResult.code);
|
|
176
179
|
return {
|
|
177
180
|
contents: clientResult.code,
|
|
178
181
|
loader: getLoader(args.path),
|
|
@@ -186,7 +189,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
|
|
|
186
189
|
loader: getLoader(args.path),
|
|
187
190
|
};
|
|
188
191
|
}
|
|
189
|
-
|
|
192
|
+
process.env.VERBOSE &&
|
|
193
|
+
log("Esbuild no transformation applied for environment=%s, path=%s", env, args.path);
|
|
190
194
|
});
|
|
191
195
|
},
|
|
192
196
|
});
|
|
@@ -52,7 +52,7 @@ export const EXPORT_PATTERNS = [
|
|
|
52
52
|
export function findImportSpecifiers(id, code, ignoredImportPatterns, log) {
|
|
53
53
|
const ext = path.extname(id).toLowerCase();
|
|
54
54
|
const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
|
|
55
|
-
const logger = log ?? (() => { });
|
|
55
|
+
const logger = process.env.VERBOSE ? (log ?? (() => { })) : () => { };
|
|
56
56
|
const results = [];
|
|
57
57
|
try {
|
|
58
58
|
// sgParse and lang must be provided by the consumer
|
|
@@ -101,7 +101,7 @@ export function findImportSpecifiers(id, code, ignoredImportPatterns, log) {
|
|
|
101
101
|
export function findExports(id, code, log) {
|
|
102
102
|
const ext = path.extname(id).toLowerCase();
|
|
103
103
|
const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
|
|
104
|
-
const logger = log ?? (() => { });
|
|
104
|
+
const logger = process.env.VERBOSE ? (log ?? (() => { })) : () => { };
|
|
105
105
|
const results = [];
|
|
106
106
|
const seen = new Set(); // Track seen exports to avoid duplicates
|
|
107
107
|
try {
|
|
@@ -10,7 +10,7 @@ import path from "path";
|
|
|
10
10
|
export function findSsrImportSpecifiers(id, code, log) {
|
|
11
11
|
const ext = path.extname(id).toLowerCase();
|
|
12
12
|
const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
|
|
13
|
-
const logger = log ?? (() => { });
|
|
13
|
+
const logger = process.env.VERBOSE ? (log ?? (() => { })) : () => { };
|
|
14
14
|
const imports = [];
|
|
15
15
|
const dynamicImports = [];
|
|
16
16
|
try {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type Plugin } from "vite";
|
|
2
|
-
export declare const injectVitePreamble: ({ clientEntryPathnames,
|
|
2
|
+
export declare const injectVitePreamble: ({ clientEntryPathnames, }: {
|
|
3
3
|
clientEntryPathnames: string[];
|
|
4
|
-
mode: "development" | "production";
|
|
5
4
|
}) => Plugin;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import MagicString from "magic-string";
|
|
2
|
-
export const injectVitePreamble = ({ clientEntryPathnames,
|
|
2
|
+
export const injectVitePreamble = ({ clientEntryPathnames, }) => ({
|
|
3
3
|
name: "rwsdk:inject-vite-preamble",
|
|
4
4
|
apply: "serve",
|
|
5
5
|
transform(code, id) {
|
|
@@ -10,7 +10,7 @@ export const injectVitePreamble = ({ clientEntryPathnames, mode, }) => ({
|
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
// Only inject preamble in development mode
|
|
13
|
-
if (
|
|
13
|
+
if (process.env.NODE_ENV !== "development") {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
const s = new MagicString(code);
|
|
@@ -8,7 +8,7 @@ import { hasDirective as sourceHasDirective } from "./hasDirective.mjs";
|
|
|
8
8
|
import { isJsFile } from "./isJsFile.mjs";
|
|
9
9
|
import { invalidateModule } from "./invalidateModule.mjs";
|
|
10
10
|
import { getShortName } from "../lib/getShortName.mjs";
|
|
11
|
-
const
|
|
11
|
+
const log = debug("rwsdk:vite:hmr-plugin");
|
|
12
12
|
const hasDirective = async (filepath, directive) => {
|
|
13
13
|
if (!isJsFile(filepath)) {
|
|
14
14
|
return false;
|
|
@@ -37,7 +37,9 @@ export const miniflareHMRPlugin = (givenOptions) => [
|
|
|
37
37
|
name: "rwsdk:miniflare-hmr",
|
|
38
38
|
async hotUpdate(ctx) {
|
|
39
39
|
const { clientFiles, serverFiles, viteEnvironment: { name: environment }, workerEntryPathname: entry, } = givenOptions;
|
|
40
|
-
|
|
40
|
+
if (process.env.VERBOSE) {
|
|
41
|
+
this.environment.logger.info(`Hot update: (env=${this.environment.name}) ${ctx.file}\nModule graph:\n\n${dumpFullModuleGraph(ctx.server, this.environment.name)}`);
|
|
42
|
+
}
|
|
41
43
|
if (!["client", environment].includes(this.environment.name)) {
|
|
42
44
|
return [];
|
|
43
45
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import debug from "debug";
|
|
2
|
+
const log = debug("rwsdk:vite:mode");
|
|
3
|
+
const initialNodeEnv = process.env.NODE_ENV;
|
|
4
|
+
let mode;
|
|
5
|
+
export const resolveMode = (env) => {
|
|
6
|
+
if (mode) {
|
|
7
|
+
return mode;
|
|
8
|
+
}
|
|
9
|
+
if (initialNodeEnv) {
|
|
10
|
+
mode = initialNodeEnv === "development" ? "development" : "production";
|
|
11
|
+
log(`Resolved mode: %s (from initial NODE_ENV=%s)`, mode, initialNodeEnv);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
mode =
|
|
15
|
+
env.command === "serve" || env.isPreview ? "development" : "production";
|
|
16
|
+
log(`Resolved mode: %s (env.command=%s, env.isPreview=%s)`, mode, env.isPreview, env.command);
|
|
17
|
+
}
|
|
18
|
+
return mode;
|
|
19
|
+
};
|
|
20
|
+
export const ensureMode = () => {
|
|
21
|
+
if (mode === undefined) {
|
|
22
|
+
throw new Error("RedwoodSDK: mode is not resolved yet");
|
|
23
|
+
}
|
|
24
|
+
return mode;
|
|
25
|
+
};
|
|
@@ -3,7 +3,6 @@ import { ROOT_DIR } from "../lib/constants.mjs";
|
|
|
3
3
|
import enhancedResolve from "enhanced-resolve";
|
|
4
4
|
import { ensureAliasArray } from "./ensureAliasArray.mjs";
|
|
5
5
|
const log = debug("rwsdk:vite:react-conditions-resolver-plugin");
|
|
6
|
-
const verboseLog = debug("verbose:rwsdk:vite:react-conditions-resolver-plugin");
|
|
7
6
|
export const ENV_REACT_IMPORTS = {
|
|
8
7
|
worker: [
|
|
9
8
|
"react",
|
|
@@ -47,18 +46,22 @@ export const ENV_IMPORT_MAPPINGS = Object.fromEntries(Object.keys(ENV_RESOLVERS)
|
|
|
47
46
|
resolveEnvImportMappings(env),
|
|
48
47
|
]));
|
|
49
48
|
function resolveEnvImportMappings(env) {
|
|
50
|
-
|
|
49
|
+
process.env.VERBOSE &&
|
|
50
|
+
log("Resolving environment import mappings for env=%s", env);
|
|
51
51
|
const mappings = new Map();
|
|
52
52
|
const reactImports = ENV_REACT_IMPORTS[env];
|
|
53
53
|
for (const importRequest of reactImports) {
|
|
54
|
-
|
|
54
|
+
process.env.VERBOSE &&
|
|
55
|
+
log("Resolving import request=%s for env=%s", importRequest, env);
|
|
55
56
|
let resolved = false;
|
|
56
57
|
try {
|
|
57
58
|
resolved = ENV_RESOLVERS[env](ROOT_DIR, importRequest);
|
|
58
|
-
|
|
59
|
+
process.env.VERBOSE &&
|
|
60
|
+
log("Successfully resolved %s to %s for env=%s", importRequest, resolved, env);
|
|
59
61
|
}
|
|
60
62
|
catch {
|
|
61
|
-
|
|
63
|
+
process.env.VERBOSE &&
|
|
64
|
+
log("Failed to resolve %s for env=%s", importRequest, env);
|
|
62
65
|
}
|
|
63
66
|
if (resolved) {
|
|
64
67
|
mappings.set(importRequest, resolved);
|
|
@@ -77,10 +80,12 @@ function createEsbuildResolverPlugin(envName) {
|
|
|
77
80
|
name: `rwsdk:react-conditions-resolver-esbuild-${envName}`,
|
|
78
81
|
setup(build) {
|
|
79
82
|
build.onResolve({ filter: /.*/ }, (args) => {
|
|
80
|
-
|
|
83
|
+
process.env.VERBOSE &&
|
|
84
|
+
log("ESBuild resolving %s for env=%s, args=%O", args.path, envName, args);
|
|
81
85
|
const resolved = mappings.get(args.path);
|
|
82
86
|
if (resolved && args.importer !== "") {
|
|
83
|
-
|
|
87
|
+
process.env.VERBOSE &&
|
|
88
|
+
log("ESBuild resolving %s -> %s for env=%s", args.path, resolved, envName);
|
|
84
89
|
if (args.path === "react-server-dom-webpack/client.edge") {
|
|
85
90
|
return;
|
|
86
91
|
}
|
|
@@ -89,7 +94,8 @@ function createEsbuildResolverPlugin(envName) {
|
|
|
89
94
|
};
|
|
90
95
|
}
|
|
91
96
|
else {
|
|
92
|
-
|
|
97
|
+
process.env.VERBOSE &&
|
|
98
|
+
log("ESBuild no resolution found for %s for env=%s", args.path, envName);
|
|
93
99
|
}
|
|
94
100
|
});
|
|
95
101
|
},
|
|
@@ -124,7 +130,7 @@ export const reactConditionsResolverPlugin = () => {
|
|
|
124
130
|
envConfig.optimizeDeps ??= {};
|
|
125
131
|
envConfig.optimizeDeps.esbuildOptions ??= {};
|
|
126
132
|
envConfig.optimizeDeps.esbuildOptions.define ??= {};
|
|
127
|
-
envConfig.optimizeDeps.esbuildOptions.define["process.env.NODE_ENV"] = JSON.stringify(process.env.NODE_ENV
|
|
133
|
+
envConfig.optimizeDeps.esbuildOptions.define["process.env.NODE_ENV"] = JSON.stringify(process.env.NODE_ENV);
|
|
128
134
|
envConfig.optimizeDeps.esbuildOptions.plugins ??= [];
|
|
129
135
|
envConfig.optimizeDeps.esbuildOptions.plugins.push(esbuildPlugin);
|
|
130
136
|
envConfig.optimizeDeps.include ??= [];
|
|
@@ -152,10 +158,12 @@ export const reactConditionsResolverPlugin = () => {
|
|
|
152
158
|
if (!envName) {
|
|
153
159
|
return;
|
|
154
160
|
}
|
|
155
|
-
|
|
161
|
+
process.env.VERBOSE &&
|
|
162
|
+
log("Resolving id=%s, environment=%s, importer=%s", id, envName, importer);
|
|
156
163
|
const mappings = ENV_IMPORT_MAPPINGS[envName];
|
|
157
164
|
if (!mappings) {
|
|
158
|
-
|
|
165
|
+
process.env.VERBOSE &&
|
|
166
|
+
log("No mappings found for environment: %s", envName);
|
|
159
167
|
return;
|
|
160
168
|
}
|
|
161
169
|
const resolved = mappings.get(id);
|
|
@@ -163,7 +171,8 @@ export const reactConditionsResolverPlugin = () => {
|
|
|
163
171
|
log("Resolved %s -> %s for env=%s", id, resolved, envName);
|
|
164
172
|
return resolved;
|
|
165
173
|
}
|
|
166
|
-
|
|
174
|
+
process.env.VERBOSE &&
|
|
175
|
+
log("No resolution found for id=%s in env=%s", id, envName);
|
|
167
176
|
},
|
|
168
177
|
},
|
|
169
178
|
];
|
|
@@ -30,8 +30,6 @@ const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, op
|
|
|
30
30
|
};
|
|
31
31
|
export const redwoodPlugin = async (options = {}) => {
|
|
32
32
|
const projectRootDir = process.cwd();
|
|
33
|
-
const mode = options.mode ??
|
|
34
|
-
(process.env.NODE_ENV === "development" ? "development" : "production");
|
|
35
33
|
const workerConfigPath = options.configPath ?? (await findWranglerConfig(projectRootDir));
|
|
36
34
|
const workerEntryPathname = await determineWorkerEntryPathname(projectRootDir, workerConfigPath, options);
|
|
37
35
|
const clientEntryPathnames = (Array.isArray(options.entry?.client)
|
|
@@ -57,7 +55,6 @@ export const redwoodPlugin = async (options = {}) => {
|
|
|
57
55
|
return [
|
|
58
56
|
devServerTimingPlugin(),
|
|
59
57
|
configPlugin({
|
|
60
|
-
mode,
|
|
61
58
|
silent: options.silent ?? false,
|
|
62
59
|
projectRootDir,
|
|
63
60
|
clientEntryPathnames,
|
|
@@ -90,7 +87,7 @@ export const redwoodPlugin = async (options = {}) => {
|
|
|
90
87
|
serverFiles,
|
|
91
88
|
}),
|
|
92
89
|
vitePreamblePlugin(),
|
|
93
|
-
injectVitePreamble({ clientEntryPathnames
|
|
90
|
+
injectVitePreamble({ clientEntryPathnames }),
|
|
94
91
|
useClientLookupPlugin({
|
|
95
92
|
projectRootDir,
|
|
96
93
|
clientFiles,
|
|
@@ -2,7 +2,6 @@ import debug from "debug";
|
|
|
2
2
|
import { SSR_BRIDGE_PATH } from "../lib/constants.mjs";
|
|
3
3
|
import { findSsrImportSpecifiers } from "./findSsrSpecifiers.mjs";
|
|
4
4
|
const log = debug("rwsdk:vite:ssr-bridge-plugin");
|
|
5
|
-
const verboseLog = debug("verbose:rwsdk:vite:ssr-bridge-plugin");
|
|
6
5
|
export const VIRTUAL_SSR_PREFIX = "virtual:rwsdk:ssr:";
|
|
7
6
|
export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
8
7
|
log("Initializing SSR bridge plugin with SSR_BRIDGE_PATH=%s", SSR_BRIDGE_PATH);
|
|
@@ -33,7 +32,8 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
33
32
|
setup(build) {
|
|
34
33
|
log("Setting up esbuild plugin to mark rwsdk/__ssr paths as external for worker");
|
|
35
34
|
build.onResolve({ filter: /.*$/ }, (args) => {
|
|
36
|
-
|
|
35
|
+
process.env.VERBOSE &&
|
|
36
|
+
log("Esbuild onResolve called for path=%s, args=%O", args.path, args);
|
|
37
37
|
if (args.path === "rwsdk/__ssr_bridge") {
|
|
38
38
|
log("Marking as external: %s", args.path);
|
|
39
39
|
return {
|
|
@@ -48,7 +48,8 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
async resolveId(id) {
|
|
51
|
-
|
|
51
|
+
process.env.VERBOSE &&
|
|
52
|
+
log("Resolving id=%s, environment=%s, isDev=%s", id, this.environment?.name, isDev);
|
|
52
53
|
if (isDev) {
|
|
53
54
|
// context(justinvdm, 27 May 2025): In dev, we need to dynamically load
|
|
54
55
|
// SSR modules, so we return the virtual id so that the dynamic loading
|
|
@@ -77,10 +78,11 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
77
78
|
return SSR_BRIDGE_PATH;
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
+
process.env.VERBOSE && log("No resolution for id=%s", id);
|
|
81
82
|
},
|
|
82
83
|
async load(id) {
|
|
83
|
-
|
|
84
|
+
process.env.VERBOSE &&
|
|
85
|
+
log("Loading id=%s, isDev=%s, environment=%s", id, isDev, this.environment.name);
|
|
84
86
|
if (id.startsWith(VIRTUAL_SSR_PREFIX) &&
|
|
85
87
|
this.environment.name === "worker") {
|
|
86
88
|
const realId = id.slice(VIRTUAL_SSR_PREFIX.length);
|
|
@@ -88,10 +90,11 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
88
90
|
if (isDev) {
|
|
89
91
|
log("Dev mode: fetching SSR module for realPath=%s", realId);
|
|
90
92
|
const result = await devServer?.environments.ssr.fetchModule(realId);
|
|
91
|
-
|
|
93
|
+
process.env.VERBOSE &&
|
|
94
|
+
log("Fetch module result: id=%s, result=%O", realId, result);
|
|
92
95
|
const code = "code" in result ? result.code : undefined;
|
|
93
96
|
log("Fetched SSR module code length: %d", code?.length || 0);
|
|
94
|
-
const { imports, dynamicImports } = findSsrImportSpecifiers(realId, code || "",
|
|
97
|
+
const { imports, dynamicImports } = findSsrImportSpecifiers(realId, code || "", log);
|
|
95
98
|
const allSpecifiers = [...new Set([...imports, ...dynamicImports])];
|
|
96
99
|
const switchCases = allSpecifiers
|
|
97
100
|
.map((specifier) => ` case "${specifier}": return import("${VIRTUAL_SSR_PREFIX}${specifier}");`)
|
|
@@ -109,11 +112,12 @@ ${switchCases}
|
|
|
109
112
|
}
|
|
110
113
|
`;
|
|
111
114
|
log("Transformed SSR module code length: %d", transformedCode.length);
|
|
112
|
-
|
|
115
|
+
process.env.VERBOSE &&
|
|
116
|
+
log("Transformed SSR module code for realId=%s: %s", realId, transformedCode);
|
|
113
117
|
return transformedCode;
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
|
-
|
|
120
|
+
process.env.VERBOSE && log("No load handling for id=%s", id);
|
|
117
121
|
},
|
|
118
122
|
};
|
|
119
123
|
return ssrBridgePlugin;
|
|
@@ -4,21 +4,19 @@ import { hasDirective } from "./hasDirective.mjs";
|
|
|
4
4
|
import { findExports } from "./findSpecifiers.mjs";
|
|
5
5
|
const logVite = debug("rwsdk:vite:transform-client-components:vite");
|
|
6
6
|
const logEsbuild = debug("rwsdk:vite:transform-client-components:esbuild");
|
|
7
|
-
const verboseLogVite = debug("verbose:rwsdk:vite:transform-client-components:vite");
|
|
8
|
-
const verboseLogEsbuild = debug("verbose:rwsdk:vite:transform-client-components:esbuild");
|
|
9
7
|
export async function transformClientComponents(code, normalizedId, ctx) {
|
|
10
8
|
const log = ctx.isEsbuild ? logEsbuild : logVite;
|
|
11
|
-
const verboseLog = ctx.isEsbuild ? verboseLogEsbuild : verboseLogVite;
|
|
12
9
|
log("Called transformClientComponents for id: id=%s", normalizedId);
|
|
13
10
|
if (!hasDirective(code, "use client")) {
|
|
14
11
|
log("Skipping: no 'use client' directive in id=%s", normalizedId);
|
|
15
|
-
|
|
12
|
+
process.env.VERBOSE &&
|
|
13
|
+
log(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
|
|
16
14
|
return;
|
|
17
15
|
}
|
|
18
16
|
log("Processing 'use client' module: id=%s", normalizedId);
|
|
19
17
|
ctx.addClientModule?.(ctx.environmentName, normalizedId);
|
|
20
18
|
// Parse exports using the findExports helper
|
|
21
|
-
const exportInfos = findExports(normalizedId, code,
|
|
19
|
+
const exportInfos = findExports(normalizedId, code, log);
|
|
22
20
|
const processedExports = [];
|
|
23
21
|
let defaultExportInfo;
|
|
24
22
|
// Helper to get the computed local name (with alias suffix if present)
|
|
@@ -62,7 +60,8 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
62
60
|
const start = match.index;
|
|
63
61
|
const end = match.index + match[0].length;
|
|
64
62
|
s.remove(start, end);
|
|
65
|
-
|
|
63
|
+
process.env.VERBOSE &&
|
|
64
|
+
log("Removed 'use client' directive from normalizedId=%s", normalizedId);
|
|
66
65
|
break; // Only remove the first one
|
|
67
66
|
}
|
|
68
67
|
const sourceMap = s.generateMap({
|
|
@@ -70,7 +69,8 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
70
69
|
includeContent: true,
|
|
71
70
|
hires: true,
|
|
72
71
|
});
|
|
73
|
-
|
|
72
|
+
process.env.VERBOSE &&
|
|
73
|
+
log(":VERBOSE: SSR transformed code for %s:\n%s", normalizedId, s.toString());
|
|
74
74
|
return {
|
|
75
75
|
code: s.toString(),
|
|
76
76
|
map: sourceMap,
|
|
@@ -107,7 +107,8 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
107
107
|
hires: true,
|
|
108
108
|
});
|
|
109
109
|
const finalResult = s.toString();
|
|
110
|
-
|
|
110
|
+
process.env.VERBOSE &&
|
|
111
|
+
log(":VERBOSE: Transformed code (env=%s, normalizedId=%s):\n%s", normalizedId, ctx.environmentName, finalResult);
|
|
111
112
|
return {
|
|
112
113
|
code: finalResult,
|
|
113
114
|
map: sourceMap,
|
|
@@ -5,15 +5,14 @@ import { findExports } from "./findSpecifiers.mjs";
|
|
|
5
5
|
import { parse as sgParse, Lang as SgLang, Lang } from "@ast-grep/napi";
|
|
6
6
|
import path from "path";
|
|
7
7
|
const log = debug("rwsdk:vite:transform-server-functions");
|
|
8
|
-
const verboseLog = debug("verbose:rwsdk:vite:transform-server-functions");
|
|
9
8
|
export const findExportedFunctions = (code, normalizedId) => {
|
|
10
9
|
return findExportInfo(code, normalizedId).localFunctions;
|
|
11
10
|
};
|
|
12
11
|
export const findExportInfo = (code, normalizedId) => {
|
|
13
|
-
|
|
12
|
+
process.env.VERBOSE && log("Finding exported functions in source file");
|
|
14
13
|
const localFunctions = new Set();
|
|
15
14
|
const reExports = [];
|
|
16
|
-
const exportInfos = findExports(normalizedId || "file.ts", code,
|
|
15
|
+
const exportInfos = findExports(normalizedId || "file.ts", code, log);
|
|
17
16
|
for (const exportInfo of exportInfos) {
|
|
18
17
|
if (exportInfo.isReExport && exportInfo.moduleSpecifier) {
|
|
19
18
|
// For re-exports, we need to determine the original name by parsing the code
|
|
@@ -29,11 +28,13 @@ export const findExportInfo = (code, normalizedId) => {
|
|
|
29
28
|
originalName: originalName,
|
|
30
29
|
moduleSpecifier: exportInfo.moduleSpecifier,
|
|
31
30
|
});
|
|
32
|
-
|
|
31
|
+
process.env.VERBOSE &&
|
|
32
|
+
log("Found re-exported function: %s (original: %s) from %s", exportInfo.name, originalName, exportInfo.moduleSpecifier);
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
35
35
|
localFunctions.add(exportInfo.name);
|
|
36
|
-
|
|
36
|
+
process.env.VERBOSE &&
|
|
37
|
+
log("Found exported function: %s", exportInfo.name);
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
log("Found %d local functions: %O", localFunctions.size, Array.from(localFunctions));
|
|
@@ -55,7 +56,7 @@ function findDefaultFunctionName(code, normalizedId) {
|
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
catch (err) {
|
|
58
|
-
|
|
59
|
+
process.env.VERBOSE && log("Error finding default function name: %O", err);
|
|
59
60
|
}
|
|
60
61
|
return null;
|
|
61
62
|
}
|
|
@@ -79,15 +80,17 @@ function hasDefaultExport(code, normalizedId) {
|
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
catch (err) {
|
|
82
|
-
|
|
83
|
+
process.env.VERBOSE && log("Error checking for default export: %O", err);
|
|
83
84
|
}
|
|
84
85
|
return false;
|
|
85
86
|
}
|
|
86
87
|
export const transformServerFunctions = (code, normalizedId, environment, serverFiles, addServerModule) => {
|
|
87
|
-
|
|
88
|
+
process.env.VERBOSE &&
|
|
89
|
+
log("Transform server functions called for normalizedId=%s, environment=%s", normalizedId, environment);
|
|
88
90
|
if (!hasDirective(code, "use server")) {
|
|
89
91
|
log("Skipping: no 'use server' directive in id=%s", normalizedId);
|
|
90
|
-
|
|
92
|
+
process.env.VERBOSE &&
|
|
93
|
+
log(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
|
|
91
94
|
return;
|
|
92
95
|
}
|
|
93
96
|
log("Processing 'use server' module: normalizedId=%s, environment=%s", normalizedId, environment);
|
|
@@ -144,7 +147,8 @@ export const transformServerFunctions = (code, normalizedId, environment, server
|
|
|
144
147
|
const start = match.index;
|
|
145
148
|
const end = match.index + match[0].length;
|
|
146
149
|
s.remove(start, end);
|
|
147
|
-
|
|
150
|
+
process.env.VERBOSE &&
|
|
151
|
+
log("Removed 'use server' directive from normalizedId=%s", normalizedId);
|
|
148
152
|
break; // Only remove the first one
|
|
149
153
|
}
|
|
150
154
|
// Add imports at the very beginning
|
|
@@ -239,7 +243,8 @@ export const transformServerFunctions = (code, normalizedId, environment, server
|
|
|
239
243
|
}
|
|
240
244
|
}
|
|
241
245
|
catch (err) {
|
|
242
|
-
|
|
246
|
+
process.env.VERBOSE &&
|
|
247
|
+
log("Error processing default function: %O", err);
|
|
243
248
|
}
|
|
244
249
|
}
|
|
245
250
|
// Add registration calls at the end
|
|
@@ -286,5 +291,6 @@ export const transformServerFunctions = (code, normalizedId, environment, server
|
|
|
286
291
|
}),
|
|
287
292
|
};
|
|
288
293
|
}
|
|
289
|
-
|
|
294
|
+
process.env.VERBOSE &&
|
|
295
|
+
log("No transformation applied for environment=%s, normalizedId=%s", environment, normalizedId);
|
|
290
296
|
};
|