rwsdk 0.2.0-alpha.9 → 0.3.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/constants.d.mts +6 -1
- package/dist/lib/constants.mjs +6 -1
- package/dist/lib/smokeTests/browser.mjs +5 -21
- package/dist/lib/smokeTests/codeUpdates.d.mts +1 -1
- package/dist/lib/smokeTests/codeUpdates.mjs +41 -5
- package/dist/lib/smokeTests/development.d.mts +1 -1
- package/dist/lib/smokeTests/development.mjs +4 -10
- package/dist/lib/smokeTests/release.d.mts +1 -1
- package/dist/lib/smokeTests/release.mjs +4 -9
- package/dist/lib/smokeTests/runSmokeTests.mjs +2 -2
- package/dist/lib/smokeTests/templates/SmokeTest.template.js +3 -2
- package/dist/lib/testUtils/stubEnvVars.d.mts +2 -0
- package/dist/lib/testUtils/stubEnvVars.mjs +11 -0
- package/dist/runtime/client/client.d.ts +10 -0
- package/dist/runtime/{client.js → client/client.js} +13 -10
- package/dist/runtime/{clientNavigation.test.js → client/navigation.test.js} +1 -1
- package/dist/runtime/client/setWebpackRequire.d.ts +1 -0
- package/dist/runtime/client/setWebpackRequire.js +2 -0
- package/dist/runtime/{client.d.ts → client/types.d.ts} +4 -10
- package/dist/runtime/client/types.js +1 -0
- package/dist/runtime/entries/client.d.ts +2 -2
- package/dist/runtime/entries/client.js +2 -2
- package/dist/runtime/imports/client.d.ts +3 -3
- package/dist/runtime/imports/client.js +11 -15
- package/dist/runtime/imports/ssr.d.ts +3 -3
- package/dist/runtime/imports/ssr.js +3 -3
- package/dist/runtime/imports/worker.d.ts +3 -3
- package/dist/runtime/imports/worker.js +5 -4
- package/dist/runtime/lib/manifest.d.ts +11 -2
- package/dist/runtime/lib/manifest.js +1 -1
- package/dist/runtime/lib/memoizeOnId.d.ts +1 -0
- package/dist/runtime/lib/memoizeOnId.js +11 -0
- package/dist/runtime/lib/realtime/client.d.ts +1 -1
- package/dist/runtime/lib/realtime/client.js +1 -1
- package/dist/runtime/lib/router.d.ts +3 -3
- package/dist/runtime/lib/router.js +77 -33
- package/dist/runtime/register/ssr.d.ts +1 -1
- package/dist/runtime/register/ssr.js +4 -3
- package/dist/runtime/render/preloads.d.ts +6 -0
- package/dist/runtime/render/preloads.js +40 -0
- package/dist/runtime/render/renderRscThenableToHtmlStream.js +2 -1
- package/dist/runtime/render/stylesheets.js +1 -1
- package/dist/runtime/requestInfo/types.d.ts +3 -1
- package/dist/runtime/requestInfo/worker.js +9 -1
- package/dist/runtime/worker.d.ts +0 -3
- package/dist/runtime/worker.js +2 -11
- package/dist/scripts/debug-sync.mjs +142 -39
- package/dist/scripts/smoke-test.mjs +0 -10
- package/dist/scripts/worker-run.mjs +8 -3
- package/dist/vite/buildApp.d.mts +15 -0
- package/dist/vite/buildApp.mjs +53 -0
- package/dist/vite/configPlugin.d.mts +4 -2
- package/dist/vite/configPlugin.mjs +69 -62
- package/dist/vite/createDirectiveLookupPlugin.d.mts +0 -6
- package/dist/vite/createDirectiveLookupPlugin.mjs +61 -145
- package/dist/vite/directiveModulesDevPlugin.d.mts +8 -0
- package/dist/vite/directiveModulesDevPlugin.mjs +62 -0
- package/dist/vite/directivesFilteringPlugin.d.mts +6 -0
- package/dist/vite/directivesFilteringPlugin.mjs +31 -0
- package/dist/vite/directivesPlugin.mjs +28 -42
- package/dist/vite/getViteEsbuild.d.mts +1 -0
- package/dist/vite/getViteEsbuild.mjs +12 -0
- package/dist/vite/hasOwnReactVitePlugin.d.mts +3 -0
- package/dist/vite/hasOwnReactVitePlugin.mjs +14 -0
- package/dist/vite/injectVitePreamblePlugin.d.mts +3 -2
- package/dist/vite/injectVitePreamblePlugin.mjs +4 -2
- package/dist/vite/linkerPlugin.d.mts +4 -0
- package/dist/vite/linkerPlugin.mjs +41 -0
- package/dist/vite/manifestPlugin.d.mts +2 -2
- package/dist/vite/manifestPlugin.mjs +12 -37
- package/dist/vite/miniflareHMRPlugin.mjs +17 -2
- package/dist/vite/moveStaticAssetsPlugin.mjs +2 -1
- package/dist/vite/prismaPlugin.mjs +1 -1
- package/dist/vite/reactConditionsResolverPlugin.d.mts +3 -4
- package/dist/vite/reactConditionsResolverPlugin.mjs +74 -56
- package/dist/vite/redwoodPlugin.d.mts +1 -1
- package/dist/vite/redwoodPlugin.mjs +36 -12
- package/dist/vite/runDirectivesScan.d.mts +7 -0
- package/dist/vite/runDirectivesScan.mjs +152 -0
- package/dist/vite/ssrBridgePlugin.mjs +13 -14
- package/dist/vite/transformClientComponents.d.mts +0 -1
- package/dist/vite/transformClientComponents.mjs +1 -9
- package/dist/vite/transformJsxScriptTagsPlugin.d.mts +4 -3
- package/dist/vite/transformJsxScriptTagsPlugin.mjs +151 -158
- package/dist/vite/transformJsxScriptTagsPlugin.test.mjs +393 -136
- package/dist/vite/transformServerFunctions.d.mts +1 -1
- package/dist/vite/transformServerFunctions.mjs +11 -12
- package/package.json +28 -4
- /package/dist/runtime/{imports → client}/ClientOnly.d.ts +0 -0
- /package/dist/runtime/{imports → client}/ClientOnly.js +0 -0
- /package/dist/runtime/{clientNavigation.d.ts → client/navigation.d.ts} +0 -0
- /package/dist/runtime/{clientNavigation.js → client/navigation.js} +0 -0
- /package/dist/runtime/{clientNavigation.test.d.ts → client/navigation.test.d.ts} +0 -0
|
@@ -3,6 +3,7 @@ import { unstable_readConfig } from "wrangler";
|
|
|
3
3
|
import { cloudflare } from "@cloudflare/vite-plugin";
|
|
4
4
|
import { devServerConstantPlugin } from "./devServerConstant.mjs";
|
|
5
5
|
import { hasOwnCloudflareVitePlugin } from "./hasOwnCloudflareVitePlugin.mjs";
|
|
6
|
+
import { hasOwnReactVitePlugin } from "./hasOwnReactVitePlugin.mjs";
|
|
6
7
|
import reactPlugin from "@vitejs/plugin-react";
|
|
7
8
|
import tsconfigPaths from "vite-tsconfig-paths";
|
|
8
9
|
import { transformJsxScriptTagsPlugin } from "./transformJsxScriptTagsPlugin.mjs";
|
|
@@ -23,6 +24,9 @@ import { ssrBridgePlugin } from "./ssrBridgePlugin.mjs";
|
|
|
23
24
|
import { hasPkgScript } from "../lib/hasPkgScript.mjs";
|
|
24
25
|
import { devServerTimingPlugin } from "./devServerTimingPlugin.mjs";
|
|
25
26
|
import { manifestPlugin } from "./manifestPlugin.mjs";
|
|
27
|
+
import { linkerPlugin } from "./linkerPlugin.mjs";
|
|
28
|
+
import { directiveModulesDevPlugin } from "./directiveModulesDevPlugin.mjs";
|
|
29
|
+
import { directivesFilteringPlugin } from "./directivesFilteringPlugin.mjs";
|
|
26
30
|
const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, options) => {
|
|
27
31
|
if (options.entry?.worker) {
|
|
28
32
|
return resolve(projectRootDir, options.entry.worker);
|
|
@@ -30,17 +34,20 @@ const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, op
|
|
|
30
34
|
const workerConfig = unstable_readConfig({ config: workerConfigPath });
|
|
31
35
|
return resolve(projectRootDir, workerConfig.main ?? "src/worker.tsx");
|
|
32
36
|
};
|
|
37
|
+
const clientFiles = new Set();
|
|
38
|
+
const serverFiles = new Set();
|
|
39
|
+
const clientEntryPoints = new Set();
|
|
33
40
|
export const redwoodPlugin = async (options = {}) => {
|
|
34
41
|
const projectRootDir = process.cwd();
|
|
35
|
-
const workerConfigPath = options.configPath ??
|
|
42
|
+
const workerConfigPath = options.configPath ??
|
|
43
|
+
(process.env.RWSDK_WRANGLER_CONFIG
|
|
44
|
+
? resolve(projectRootDir, process.env.RWSDK_WRANGLER_CONFIG)
|
|
45
|
+
: await findWranglerConfig(projectRootDir));
|
|
36
46
|
const workerEntryPathname = await determineWorkerEntryPathname(projectRootDir, workerConfigPath, options);
|
|
37
|
-
const clientEntryPathnames = (Array.isArray(options.entry?.client)
|
|
38
|
-
? options.entry.client
|
|
39
|
-
: [options.entry?.client ?? "src/client.tsx"]).map((entry) => resolve(projectRootDir, entry));
|
|
40
|
-
const clientFiles = new Set();
|
|
41
|
-
const serverFiles = new Set();
|
|
42
47
|
const shouldIncludeCloudflarePlugin = options.includeCloudflarePlugin ??
|
|
43
48
|
!(await hasOwnCloudflareVitePlugin({ rootProjectDir: projectRootDir }));
|
|
49
|
+
const shouldIncludeReactPlugin = options.includeReactPlugin ??
|
|
50
|
+
!(await hasOwnReactVitePlugin({ rootProjectDir: projectRootDir }));
|
|
44
51
|
// context(justinvdm, 31 Mar 2025): We assume that if there is no .wrangler directory,
|
|
45
52
|
// then this is fresh install, and we run `npm run dev:init` here.
|
|
46
53
|
if (process.env.RWSDK_WORKER_RUN !== "1" &&
|
|
@@ -56,19 +63,26 @@ export const redwoodPlugin = async (options = {}) => {
|
|
|
56
63
|
}
|
|
57
64
|
return [
|
|
58
65
|
devServerTimingPlugin(),
|
|
66
|
+
directiveModulesDevPlugin({
|
|
67
|
+
clientFiles,
|
|
68
|
+
serverFiles,
|
|
69
|
+
projectRootDir,
|
|
70
|
+
}),
|
|
59
71
|
devServerConstantPlugin(),
|
|
60
72
|
configPlugin({
|
|
61
73
|
silent: options.silent ?? false,
|
|
62
74
|
projectRootDir,
|
|
63
|
-
clientEntryPathnames,
|
|
64
75
|
workerEntryPathname,
|
|
76
|
+
clientFiles,
|
|
77
|
+
serverFiles,
|
|
78
|
+
clientEntryPoints,
|
|
65
79
|
}),
|
|
66
80
|
ssrBridgePlugin({
|
|
67
81
|
clientFiles,
|
|
68
82
|
serverFiles,
|
|
69
83
|
projectRootDir,
|
|
70
84
|
}),
|
|
71
|
-
reactConditionsResolverPlugin(),
|
|
85
|
+
reactConditionsResolverPlugin({ projectRootDir }),
|
|
72
86
|
tsconfigPaths({ root: projectRootDir }),
|
|
73
87
|
shouldIncludeCloudflarePlugin
|
|
74
88
|
? cloudflare({
|
|
@@ -83,14 +97,17 @@ export const redwoodPlugin = async (options = {}) => {
|
|
|
83
97
|
viteEnvironment: { name: "worker" },
|
|
84
98
|
workerEntryPathname,
|
|
85
99
|
}),
|
|
86
|
-
reactPlugin(),
|
|
100
|
+
shouldIncludeReactPlugin ? reactPlugin() : [],
|
|
87
101
|
directivesPlugin({
|
|
88
102
|
projectRootDir,
|
|
89
103
|
clientFiles,
|
|
90
104
|
serverFiles,
|
|
91
105
|
}),
|
|
92
106
|
vitePreamblePlugin(),
|
|
93
|
-
injectVitePreamble({
|
|
107
|
+
injectVitePreamble({
|
|
108
|
+
clientEntryPoints,
|
|
109
|
+
projectRootDir,
|
|
110
|
+
}),
|
|
94
111
|
useClientLookupPlugin({
|
|
95
112
|
projectRootDir,
|
|
96
113
|
clientFiles,
|
|
@@ -100,12 +117,19 @@ export const redwoodPlugin = async (options = {}) => {
|
|
|
100
117
|
serverFiles,
|
|
101
118
|
}),
|
|
102
119
|
transformJsxScriptTagsPlugin({
|
|
103
|
-
|
|
120
|
+
clientEntryPoints,
|
|
121
|
+
projectRootDir,
|
|
104
122
|
}),
|
|
105
123
|
manifestPlugin({
|
|
106
|
-
|
|
124
|
+
projectRootDir,
|
|
107
125
|
}),
|
|
108
126
|
moveStaticAssetsPlugin({ rootDir: projectRootDir }),
|
|
109
127
|
prismaPlugin({ projectRootDir }),
|
|
128
|
+
linkerPlugin({ projectRootDir }),
|
|
129
|
+
directivesFilteringPlugin({
|
|
130
|
+
clientFiles,
|
|
131
|
+
serverFiles,
|
|
132
|
+
projectRootDir,
|
|
133
|
+
}),
|
|
110
134
|
];
|
|
111
135
|
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import fsp from "node:fs/promises";
|
|
2
|
+
import { hasDirective } from "./hasDirective.mjs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import debug from "debug";
|
|
5
|
+
import { ensureAliasArray } from "./ensureAliasArray.mjs";
|
|
6
|
+
import { getViteEsbuild } from "./getViteEsbuild.mjs";
|
|
7
|
+
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
8
|
+
const log = debug("rwsdk:vite:run-directives-scan");
|
|
9
|
+
// Copied from Vite's source code.
|
|
10
|
+
// https://github.com/vitejs/vite/blob/main/packages/vite/src/shared/utils.ts
|
|
11
|
+
const isObject = (value) => Object.prototype.toString.call(value) === "[object Object]";
|
|
12
|
+
// Copied from Vite's source code.
|
|
13
|
+
// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/utils.ts
|
|
14
|
+
const externalRE = /^(https?:)?\/\//;
|
|
15
|
+
const isExternalUrl = (url) => externalRE.test(url);
|
|
16
|
+
function createEsbuildScanPlugin({ clientFiles, serverFiles, aliases, projectRootDir, }) {
|
|
17
|
+
return {
|
|
18
|
+
name: "rwsdk:esbuild-scan-plugin",
|
|
19
|
+
setup(build) {
|
|
20
|
+
// Match Vite's behavior by externalizing assets and special queries.
|
|
21
|
+
// This prevents esbuild from trying to bundle them, which would fail.
|
|
22
|
+
const scriptFilter = /\.(c|m)?[jt]sx?$/;
|
|
23
|
+
const specialQueryFilter = /[?&](?:url|raw|worker|sharedworker|inline)\b/;
|
|
24
|
+
// This regex is used to identify if a path has any file extension.
|
|
25
|
+
const hasExtensionRegex = /\.[^/]+$/;
|
|
26
|
+
build.onResolve({ filter: specialQueryFilter }, (args) => {
|
|
27
|
+
log("Externalizing special query:", args.path);
|
|
28
|
+
return { external: true };
|
|
29
|
+
});
|
|
30
|
+
build.onResolve({ filter: /.*/, namespace: "file" }, (args) => {
|
|
31
|
+
// Externalize if the path has an extension AND that extension is not a
|
|
32
|
+
// script extension. Extensionless paths are assumed to be scripts and
|
|
33
|
+
// are allowed to pass through for resolution.
|
|
34
|
+
if (hasExtensionRegex.test(args.path) &&
|
|
35
|
+
!scriptFilter.test(args.path)) {
|
|
36
|
+
log("Externalizing non-script import:", args.path);
|
|
37
|
+
return { external: true };
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
build.onResolve({ filter: /.*/ }, async (args) => {
|
|
41
|
+
// Prevent infinite recursion.
|
|
42
|
+
if (args.pluginData?.rwsdkScanResolver) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
// 1. First, try to resolve aliases.
|
|
46
|
+
for (const { find, replacement } of aliases) {
|
|
47
|
+
const findPattern = find instanceof RegExp ? find : new RegExp(`^${find}(\\/.*)?$`);
|
|
48
|
+
if (findPattern.test(args.path)) {
|
|
49
|
+
const newPath = args.path.replace(findPattern, (_match, rest) => {
|
|
50
|
+
// `rest` is the captured group `(\\/.*)?` from the regex.
|
|
51
|
+
return replacement + (rest || "");
|
|
52
|
+
});
|
|
53
|
+
const resolved = await build.resolve(newPath, {
|
|
54
|
+
importer: args.importer,
|
|
55
|
+
resolveDir: args.resolveDir,
|
|
56
|
+
kind: args.kind,
|
|
57
|
+
pluginData: { rwsdkScanResolver: true },
|
|
58
|
+
});
|
|
59
|
+
if (resolved.errors.length === 0) {
|
|
60
|
+
return resolved;
|
|
61
|
+
}
|
|
62
|
+
log("Could not resolve aliased path '%s' (from '%s'). Marking as external. Errors: %s", newPath, args.path, resolved.errors.map((e) => e.text).join(", "));
|
|
63
|
+
return { external: true };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// 2. If no alias matches, try esbuild's default resolver.
|
|
67
|
+
const resolved = await build.resolve(args.path, {
|
|
68
|
+
importer: args.importer,
|
|
69
|
+
resolveDir: args.resolveDir,
|
|
70
|
+
kind: args.kind,
|
|
71
|
+
pluginData: { rwsdkScanResolver: true },
|
|
72
|
+
});
|
|
73
|
+
// If it fails, mark as external but don't crash.
|
|
74
|
+
if (resolved.errors.length > 0) {
|
|
75
|
+
log("Could not resolve '%s'. Marking as external. Errors: %s", args.path, resolved.errors.map((e) => e.text).join(", "));
|
|
76
|
+
return { external: true };
|
|
77
|
+
}
|
|
78
|
+
return resolved;
|
|
79
|
+
});
|
|
80
|
+
build.onLoad({ filter: /\.(m|c)?[jt]sx?$/ }, async (args) => {
|
|
81
|
+
if (!args.path.startsWith("/") ||
|
|
82
|
+
args.path.includes("virtual:") ||
|
|
83
|
+
isExternalUrl(args.path)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const contents = await fsp.readFile(args.path, "utf-8");
|
|
88
|
+
if (hasDirective(contents, "use client")) {
|
|
89
|
+
log("Discovered 'use client' in:", args.path);
|
|
90
|
+
clientFiles.add(normalizeModulePath(args.path, projectRootDir));
|
|
91
|
+
}
|
|
92
|
+
if (hasDirective(contents, "use server")) {
|
|
93
|
+
log("Discovered 'use server' in:", args.path);
|
|
94
|
+
serverFiles.add(normalizeModulePath(args.path, projectRootDir));
|
|
95
|
+
}
|
|
96
|
+
return { contents, loader: "default" };
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
log("Could not read file during scan, skipping:", args.path, e);
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
export async function runDirectivesScan({ rootConfig, envName, clientFiles, serverFiles, }) {
|
|
107
|
+
const esbuild = await getViteEsbuild(rootConfig.root);
|
|
108
|
+
const env = rootConfig.environments[envName];
|
|
109
|
+
const input = env.build.rollupOptions?.input;
|
|
110
|
+
let entries;
|
|
111
|
+
if (Array.isArray(input)) {
|
|
112
|
+
entries = input;
|
|
113
|
+
}
|
|
114
|
+
else if (typeof input === "string") {
|
|
115
|
+
entries = [input];
|
|
116
|
+
}
|
|
117
|
+
else if (isObject(input)) {
|
|
118
|
+
entries = Object.values(input);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
entries = [];
|
|
122
|
+
}
|
|
123
|
+
if (entries.length === 0) {
|
|
124
|
+
log("No entries found for directives scan in environment '%s', skipping.", envName);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const absoluteEntries = entries.map((entry) => path.resolve(rootConfig.root, entry));
|
|
128
|
+
log("Starting directives scan for environment '%s' with entries:", envName, absoluteEntries);
|
|
129
|
+
try {
|
|
130
|
+
const result = await esbuild.build({
|
|
131
|
+
entryPoints: absoluteEntries,
|
|
132
|
+
bundle: true,
|
|
133
|
+
write: false,
|
|
134
|
+
platform: "node",
|
|
135
|
+
format: "esm",
|
|
136
|
+
logLevel: "silent",
|
|
137
|
+
metafile: true,
|
|
138
|
+
plugins: [
|
|
139
|
+
createEsbuildScanPlugin({
|
|
140
|
+
clientFiles,
|
|
141
|
+
serverFiles,
|
|
142
|
+
aliases: ensureAliasArray(env),
|
|
143
|
+
projectRootDir: rootConfig.root,
|
|
144
|
+
}),
|
|
145
|
+
],
|
|
146
|
+
});
|
|
147
|
+
return result.metafile;
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
throw new Error(`RWSDK directive scan failed:\n${e.message}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
|
-
import { SSR_BRIDGE_PATH } from "../lib/constants.mjs";
|
|
3
2
|
import { findSsrImportCallSites } from "./findSsrSpecifiers.mjs";
|
|
3
|
+
import { INTERMEDIATE_SSR_BRIDGE_PATH } from "../lib/constants.mjs";
|
|
4
4
|
import MagicString from "magic-string";
|
|
5
5
|
const log = debug("rwsdk:vite:ssr-bridge-plugin");
|
|
6
6
|
export const VIRTUAL_SSR_PREFIX = "virtual:rwsdk:ssr:";
|
|
7
7
|
export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
8
|
-
log("Initializing SSR bridge plugin with SSR_BRIDGE_PATH=%s", SSR_BRIDGE_PATH);
|
|
9
8
|
let devServer;
|
|
10
9
|
let isDev = false;
|
|
11
10
|
const ssrBridgePlugin = {
|
|
@@ -49,8 +48,6 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
49
48
|
}
|
|
50
49
|
},
|
|
51
50
|
async resolveId(id) {
|
|
52
|
-
process.env.VERBOSE &&
|
|
53
|
-
log("Resolving id=%s, environment=%s, isDev=%s", id, this.environment?.name, isDev);
|
|
54
51
|
if (isDev) {
|
|
55
52
|
// context(justinvdm, 27 May 2025): In dev, we need to dynamically load
|
|
56
53
|
// SSR modules, so we return the virtual id so that the dynamic loading
|
|
@@ -75,20 +72,23 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
75
72
|
}
|
|
76
73
|
}
|
|
77
74
|
else {
|
|
78
|
-
//
|
|
79
|
-
// originate at SSR bridge module, we return the path to the already built
|
|
80
|
-
// SSR bridge bundle - SSR env builds it, worker build tries to resolve it
|
|
81
|
-
// here and uses it
|
|
75
|
+
// In build mode, the behavior depends on the build pass
|
|
82
76
|
if (id === "rwsdk/__ssr_bridge" && this.environment.name === "worker") {
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
if (process.env.RWSDK_BUILD_PASS === "worker") {
|
|
78
|
+
// First pass: resolve to a temporary, external path
|
|
79
|
+
log("Bridge module case (build-worker pass): resolving to external path");
|
|
80
|
+
return { id: INTERMEDIATE_SSR_BRIDGE_PATH, external: true };
|
|
81
|
+
}
|
|
82
|
+
else if (process.env.RWSDK_BUILD_PASS === "linker") {
|
|
83
|
+
// Second pass (linker): resolve to the real intermediate build
|
|
84
|
+
// artifact so it can be bundled in.
|
|
85
|
+
log("Bridge module case (build-linker pass): resolving to bundleable path");
|
|
86
|
+
return { id: INTERMEDIATE_SSR_BRIDGE_PATH, external: false };
|
|
87
|
+
}
|
|
85
88
|
}
|
|
86
89
|
}
|
|
87
|
-
process.env.VERBOSE && log("No resolution for id=%s", id);
|
|
88
90
|
},
|
|
89
91
|
async load(id) {
|
|
90
|
-
process.env.VERBOSE &&
|
|
91
|
-
log("Loading id=%s, isDev=%s, environment=%s", id, isDev, this.environment.name);
|
|
92
92
|
if (id.startsWith(VIRTUAL_SSR_PREFIX) &&
|
|
93
93
|
this.environment.name === "worker") {
|
|
94
94
|
const realId = id.slice(VIRTUAL_SSR_PREFIX.length);
|
|
@@ -132,7 +132,6 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
132
132
|
return out;
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
-
process.env.VERBOSE && log("No load handling for id=%s", id);
|
|
136
135
|
},
|
|
137
136
|
};
|
|
138
137
|
return ssrBridgePlugin;
|
|
@@ -5,16 +5,10 @@ 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
7
|
export async function transformClientComponents(code, normalizedId, ctx) {
|
|
8
|
-
const log = ctx.isEsbuild ? logEsbuild : logVite;
|
|
9
|
-
log("Called transformClientComponents for id: id=%s", normalizedId);
|
|
10
8
|
if (!hasDirective(code, "use client")) {
|
|
11
|
-
log("Skipping: no 'use client' directive in id=%s", normalizedId);
|
|
12
|
-
process.env.VERBOSE &&
|
|
13
|
-
log(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
|
|
14
9
|
return;
|
|
15
10
|
}
|
|
16
|
-
log
|
|
17
|
-
ctx.addClientModule?.(ctx.environmentName, normalizedId);
|
|
11
|
+
const log = ctx.isEsbuild ? logEsbuild : logVite;
|
|
18
12
|
// Parse exports using the findExports helper
|
|
19
13
|
const exportInfos = findExports(normalizedId, code, log);
|
|
20
14
|
const processedExports = [];
|
|
@@ -85,7 +79,6 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
85
79
|
const computedLocalNames = new Map(processedExports.map((info) => [getComputedLocalName(info), info]));
|
|
86
80
|
// Add registerClientReference assignments for unique names
|
|
87
81
|
for (const [computedLocalName, correspondingInfo] of computedLocalNames) {
|
|
88
|
-
log(":isEsbuild=%s: Registering client reference for named export: %s as %s", !!ctx.isEsbuild, correspondingInfo.local, correspondingInfo.exported);
|
|
89
82
|
s.append(`const ${computedLocalName} = registerClientReference("${normalizedId}", "${correspondingInfo.exported}");\n`);
|
|
90
83
|
}
|
|
91
84
|
// Add grouped export statement for named exports (preserving order and alias)
|
|
@@ -93,7 +86,6 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
93
86
|
const exportNames = Array.from(computedLocalNames.entries()).map(([computedLocalName, correspondingInfo]) => correspondingInfo.local === correspondingInfo.exported
|
|
94
87
|
? computedLocalName
|
|
95
88
|
: `${computedLocalName} as ${correspondingInfo.exported}`);
|
|
96
|
-
log(":isEsbuild=%s: Exporting named exports: %O", !!ctx.isEsbuild, exportNames);
|
|
97
89
|
s.append(`export { ${exportNames.join(", ")} };\n`);
|
|
98
90
|
}
|
|
99
91
|
// Add default export if present
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type Plugin } from "vite";
|
|
2
|
-
export declare function transformJsxScriptTagsCode(code: string, manifest
|
|
2
|
+
export declare function transformJsxScriptTagsCode(code: string, clientEntryPoints: Set<string>, manifest: Record<string, any> | undefined, projectRootDir: string): Promise<{
|
|
3
3
|
code: string;
|
|
4
4
|
map: null;
|
|
5
5
|
} | undefined>;
|
|
6
|
-
export declare const transformJsxScriptTagsPlugin: ({
|
|
7
|
-
|
|
6
|
+
export declare const transformJsxScriptTagsPlugin: ({ clientEntryPoints, projectRootDir, }: {
|
|
7
|
+
clientEntryPoints: Set<string>;
|
|
8
|
+
projectRootDir: string;
|
|
8
9
|
}) => Plugin;
|