rwsdk 1.0.0-alpha.2 → 1.0.0-alpha.20
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/browser.d.mts +10 -0
- package/dist/lib/e2e/browser.mjs +124 -0
- package/dist/lib/e2e/dev.d.mts +8 -0
- package/dist/lib/e2e/dev.mjs +242 -0
- package/dist/lib/e2e/environment.d.mts +14 -0
- package/dist/lib/e2e/environment.mjs +266 -0
- package/dist/lib/e2e/index.d.mts +8 -0
- package/dist/lib/e2e/index.mjs +8 -0
- package/dist/lib/e2e/poll.d.mts +8 -0
- package/dist/lib/e2e/poll.mjs +31 -0
- package/dist/lib/e2e/release.d.mts +56 -0
- package/dist/lib/e2e/release.mjs +559 -0
- package/dist/lib/e2e/retry.d.mts +4 -0
- package/dist/lib/e2e/retry.mjs +16 -0
- package/dist/lib/e2e/setup.d.mts +2 -0
- package/dist/lib/e2e/setup.mjs +1 -0
- package/dist/lib/e2e/tarball.d.mts +14 -0
- package/dist/lib/e2e/tarball.mjs +99 -0
- package/dist/lib/e2e/testHarness.d.mts +132 -0
- package/dist/lib/e2e/testHarness.mjs +437 -0
- package/dist/lib/e2e/types.d.mts +32 -0
- package/dist/lib/getShortName.mjs +6 -1
- package/dist/lib/getShortName.test.d.mts +1 -0
- package/dist/lib/getShortName.test.mjs +25 -0
- package/dist/lib/hasPkgScript.d.mts +4 -1
- package/dist/lib/hasPkgScript.mjs +9 -6
- package/dist/lib/hasPkgScript.test.d.mts +1 -0
- package/dist/lib/hasPkgScript.test.mjs +33 -0
- package/dist/lib/jsonUtils.mjs +3 -0
- package/dist/lib/jsonUtils.test.d.mts +1 -0
- package/dist/lib/jsonUtils.test.mjs +90 -0
- package/dist/lib/normalizeModulePath.d.mts +5 -0
- package/dist/lib/normalizeModulePath.mjs +1 -1
- package/dist/lib/normalizeModulePath.test.d.mts +1 -0
- package/dist/lib/{normalizeModulePath.test.js → normalizeModulePath.test.mjs} +20 -1
- package/dist/lib/smokeTests/browser.mjs +3 -94
- package/dist/lib/smokeTests/development.mjs +2 -223
- package/dist/lib/smokeTests/environment.d.mts +4 -11
- package/dist/lib/smokeTests/environment.mjs +10 -158
- package/dist/lib/smokeTests/release.d.mts +2 -49
- package/dist/lib/smokeTests/release.mjs +3 -503
- package/dist/llms/rules/middleware.d.ts +1 -1
- package/dist/llms/rules/middleware.js +4 -4
- package/dist/runtime/entries/worker.d.ts +0 -1
- package/dist/runtime/entries/worker.js +0 -1
- package/dist/runtime/lib/auth/session.d.ts +2 -2
- package/dist/runtime/lib/auth/session.js +4 -4
- package/dist/runtime/lib/memoizeOnId.test.d.ts +1 -0
- package/dist/runtime/lib/memoizeOnId.test.js +49 -0
- package/dist/runtime/lib/realtime/protocol.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/protocol.test.js +107 -0
- package/dist/runtime/lib/realtime/shared.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/shared.test.js +18 -0
- package/dist/runtime/lib/realtime/validateUpgradeRequest.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/validateUpgradeRequest.test.js +66 -0
- package/dist/runtime/lib/realtime/worker.d.ts +1 -1
- package/dist/runtime/lib/router.js +40 -22
- package/dist/runtime/lib/router.test.js +590 -2
- package/dist/runtime/lib/rwContext.d.ts +22 -0
- package/dist/runtime/lib/rwContext.js +1 -0
- package/dist/runtime/lib/stitchDocumentAndAppStreams.d.ts +18 -0
- package/dist/runtime/lib/stitchDocumentAndAppStreams.js +143 -0
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.d.ts +2 -1
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.js +6 -6
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.d.ts +1 -0
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.js +49 -0
- package/dist/runtime/register/worker.d.ts +1 -1
- package/dist/runtime/register/worker.js +33 -21
- package/dist/runtime/render/assembleDocument.d.ts +6 -0
- package/dist/runtime/render/assembleDocument.js +22 -0
- package/dist/runtime/render/createThenableFromReadableStream.d.ts +1 -0
- package/dist/runtime/render/createThenableFromReadableStream.js +9 -0
- package/dist/runtime/render/normalizeActionResult.d.ts +1 -0
- package/dist/runtime/render/normalizeActionResult.js +43 -0
- package/dist/runtime/render/preloads.d.ts +2 -2
- package/dist/runtime/render/preloads.js +2 -3
- package/dist/runtime/render/{renderRscThenableToHtmlStream.d.ts → renderDocumentHtmlStream.d.ts} +3 -3
- package/dist/runtime/render/renderDocumentHtmlStream.js +39 -0
- package/dist/runtime/render/renderHtmlStream.d.ts +7 -0
- package/dist/runtime/render/renderHtmlStream.js +31 -0
- package/dist/runtime/render/renderToRscStream.d.ts +5 -3
- package/dist/runtime/render/renderToRscStream.js +12 -41
- package/dist/runtime/render/renderToStream.d.ts +2 -1
- package/dist/runtime/render/renderToStream.js +15 -8
- package/dist/runtime/render/stylesheets.d.ts +2 -2
- package/dist/runtime/render/stylesheets.js +2 -3
- package/dist/runtime/requestInfo/types.d.ts +0 -2
- package/dist/runtime/requestInfo/worker.js +1 -9
- package/dist/runtime/ssrBridge.d.ts +2 -1
- package/dist/runtime/ssrBridge.js +2 -1
- package/dist/runtime/worker.d.ts +1 -0
- package/dist/runtime/worker.js +11 -14
- package/dist/scripts/debug-sync.mjs +102 -133
- package/dist/vite/buildApp.d.mts +2 -1
- package/dist/vite/buildApp.mjs +9 -5
- package/dist/vite/checkIsUsingPrisma.d.mts +4 -0
- package/dist/vite/checkIsUsingPrisma.mjs +2 -2
- package/dist/vite/checkIsUsingPrisma.test.d.mts +1 -0
- package/dist/vite/checkIsUsingPrisma.test.mjs +30 -0
- package/dist/vite/configPlugin.mjs +54 -14
- package/dist/vite/createDirectiveLookupPlugin.d.mts +9 -0
- package/dist/vite/createDirectiveLookupPlugin.mjs +33 -29
- package/dist/vite/createDirectiveLookupPlugin.test.d.mts +1 -0
- package/dist/vite/createDirectiveLookupPlugin.test.mjs +40 -0
- package/dist/vite/directiveModulesDevPlugin.d.mts +4 -1
- package/dist/vite/directiveModulesDevPlugin.mjs +6 -5
- package/dist/vite/directiveModulesDevPlugin.test.d.mts +1 -0
- package/dist/vite/directiveModulesDevPlugin.test.mjs +59 -0
- package/dist/vite/directivesPlugin.d.mts +1 -0
- package/dist/vite/directivesPlugin.mjs +1 -1
- package/dist/vite/directivesPlugin.test.d.mts +1 -0
- package/dist/vite/directivesPlugin.test.mjs +24 -0
- package/dist/vite/ensureAliasArray.test.d.mts +1 -0
- package/dist/vite/ensureAliasArray.test.mjs +71 -0
- package/dist/vite/findSpecifiers.mjs +2 -1
- package/dist/vite/findSpecifiers.test.d.mts +1 -0
- package/dist/vite/findSpecifiers.test.mjs +202 -0
- package/dist/vite/findSsrSpecifiers.test.d.mts +1 -0
- package/dist/vite/findSsrSpecifiers.test.mjs +99 -0
- package/dist/vite/hasDirective.d.mts +6 -3
- package/dist/vite/hasDirective.mjs +43 -27
- package/dist/vite/hasDirective.test.d.mts +1 -0
- package/dist/vite/hasDirective.test.mjs +107 -0
- package/dist/vite/isJsFile.test.d.mts +1 -0
- package/dist/vite/isJsFile.test.mjs +38 -0
- package/dist/vite/{reactConditionsResolverPlugin.d.mts → knownDepsResolverPlugin.d.mts} +2 -2
- package/dist/vite/{reactConditionsResolverPlugin.mjs → knownDepsResolverPlugin.mjs} +28 -23
- package/dist/vite/linkerPlugin.d.mts +8 -0
- package/dist/vite/linkerPlugin.mjs +30 -22
- package/dist/vite/linkerPlugin.test.d.mts +1 -0
- package/dist/vite/linkerPlugin.test.mjs +41 -0
- package/dist/vite/miniflareHMRPlugin.d.mts +5 -0
- package/dist/vite/miniflareHMRPlugin.mjs +2 -2
- package/dist/vite/miniflareHMRPlugin.test.d.mts +1 -0
- package/dist/vite/miniflareHMRPlugin.test.mjs +42 -0
- package/dist/vite/redwoodPlugin.d.mts +9 -0
- package/dist/vite/redwoodPlugin.mjs +29 -5
- package/dist/vite/redwoodPlugin.test.d.mts +1 -0
- package/dist/vite/redwoodPlugin.test.mjs +34 -0
- package/dist/vite/resolveForcedPaths.d.mts +4 -0
- package/dist/vite/resolveForcedPaths.mjs +9 -0
- package/dist/vite/runDirectivesScan.d.mts +22 -1
- package/dist/vite/runDirectivesScan.mjs +105 -58
- package/dist/vite/runDirectivesScan.test.d.mts +1 -0
- package/dist/vite/runDirectivesScan.test.mjs +73 -0
- package/dist/vite/ssrBridgePlugin.mjs +8 -1
- package/dist/vite/transformClientComponents.mjs +6 -4
- package/dist/vite/transformClientComponents.test.mjs +116 -58
- package/dist/vite/transformServerFunctions.d.mts +1 -1
- package/dist/vite/transformServerFunctions.mjs +1 -1
- package/dist/vite/transformServerFunctions.test.mjs +3 -3
- package/package.json +56 -47
- package/dist/runtime/imports/resolveSSRValue.d.ts +0 -1
- package/dist/runtime/imports/resolveSSRValue.js +0 -8
- package/dist/runtime/render/renderRscThenableToHtmlStream.js +0 -54
- package/dist/runtime/render/transformRscToHtmlStream.d.ts +0 -8
- package/dist/runtime/render/transformRscToHtmlStream.js +0 -19
- /package/dist/lib/{normalizeModulePath.test.d.ts → e2e/types.mjs} +0 -0
|
@@ -17,7 +17,7 @@ const hasDirective = async (filepath, directive) => {
|
|
|
17
17
|
const content = await readFile(filepath, "utf-8");
|
|
18
18
|
return sourceHasDirective(content, directive);
|
|
19
19
|
};
|
|
20
|
-
const hasEntryAsAncestor = (module, entryFile, seen = new Set()) => {
|
|
20
|
+
export const hasEntryAsAncestor = ({ module, entryFile, seen = new Set(), }) => {
|
|
21
21
|
// Prevent infinite recursion
|
|
22
22
|
if (seen.has(module)) {
|
|
23
23
|
return false;
|
|
@@ -28,7 +28,7 @@ const hasEntryAsAncestor = (module, entryFile, seen = new Set()) => {
|
|
|
28
28
|
if (importer.file === entryFile)
|
|
29
29
|
return true;
|
|
30
30
|
// Recursively check importers
|
|
31
|
-
if (hasEntryAsAncestor(importer, entryFile, seen))
|
|
31
|
+
if (hasEntryAsAncestor({ module: importer, entryFile, seen }))
|
|
32
32
|
return true;
|
|
33
33
|
}
|
|
34
34
|
return false;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { hasEntryAsAncestor } from "./miniflareHMRPlugin.mjs";
|
|
3
|
+
const createModule = (file) => ({
|
|
4
|
+
file,
|
|
5
|
+
importers: new Set(),
|
|
6
|
+
});
|
|
7
|
+
describe("hasEntryAsAncestor", () => {
|
|
8
|
+
it("should return true if the entry file is a direct importer", () => {
|
|
9
|
+
const entry = createModule("entry.js");
|
|
10
|
+
const mod = createModule("mod.js");
|
|
11
|
+
mod.importers.add(entry);
|
|
12
|
+
expect(hasEntryAsAncestor({ module: mod, entryFile: "entry.js" })).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
it("should return true if the entry file is an indirect importer", () => {
|
|
15
|
+
const entry = createModule("entry.js");
|
|
16
|
+
const importer1 = createModule("importer1.js");
|
|
17
|
+
const mod = createModule("mod.js");
|
|
18
|
+
importer1.importers.add(entry);
|
|
19
|
+
mod.importers.add(importer1);
|
|
20
|
+
expect(hasEntryAsAncestor({ module: mod, entryFile: "entry.js" })).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
it("should return false if the entry file is not an importer", () => {
|
|
23
|
+
const entry = createModule("entry.js");
|
|
24
|
+
const other = createModule("other.js");
|
|
25
|
+
const mod = createModule("mod.js");
|
|
26
|
+
mod.importers.add(other);
|
|
27
|
+
expect(hasEntryAsAncestor({ module: mod, entryFile: "entry.js" })).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
it("should handle circular dependencies", () => {
|
|
30
|
+
const entry = createModule("entry.js");
|
|
31
|
+
const modA = createModule("modA.js");
|
|
32
|
+
const modB = createModule("modB.js");
|
|
33
|
+
modA.importers.add(entry);
|
|
34
|
+
modA.importers.add(modB);
|
|
35
|
+
modB.importers.add(modA);
|
|
36
|
+
expect(hasEntryAsAncestor({ module: modB, entryFile: "entry.js" })).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it("should return false for a module with no importers", () => {
|
|
39
|
+
const mod = createModule("mod.js");
|
|
40
|
+
expect(hasEntryAsAncestor({ module: mod, entryFile: "entry.js" })).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { InlineConfig } from "vite";
|
|
2
|
+
import { unstable_readConfig } from "wrangler";
|
|
2
3
|
export type RedwoodPluginOptions = {
|
|
3
4
|
silent?: boolean;
|
|
4
5
|
rootDir?: string;
|
|
5
6
|
includeCloudflarePlugin?: boolean;
|
|
6
7
|
includeReactPlugin?: boolean;
|
|
7
8
|
configPath?: string;
|
|
9
|
+
forceClientPaths?: string[];
|
|
10
|
+
forceServerPaths?: string[];
|
|
8
11
|
entry?: {
|
|
9
12
|
worker?: string;
|
|
10
13
|
};
|
|
11
14
|
};
|
|
15
|
+
export declare const determineWorkerEntryPathname: ({ projectRootDir, workerConfigPath, options, readConfig, }: {
|
|
16
|
+
projectRootDir: string;
|
|
17
|
+
workerConfigPath: string;
|
|
18
|
+
options: RedwoodPluginOptions;
|
|
19
|
+
readConfig?: typeof unstable_readConfig;
|
|
20
|
+
}) => Promise<string>;
|
|
12
21
|
export declare const redwoodPlugin: (options?: RedwoodPluginOptions) => Promise<InlineConfig["plugins"]>;
|
|
@@ -14,7 +14,7 @@ import { miniflareHMRPlugin } from "./miniflareHMRPlugin.mjs";
|
|
|
14
14
|
import { moveStaticAssetsPlugin } from "./moveStaticAssetsPlugin.mjs";
|
|
15
15
|
import { configPlugin } from "./configPlugin.mjs";
|
|
16
16
|
import { $ } from "../lib/$.mjs";
|
|
17
|
-
import {
|
|
17
|
+
import { knownDepsResolverPlugin } from "./knownDepsResolverPlugin.mjs";
|
|
18
18
|
import { findWranglerConfig } from "../lib/findWranglerConfig.mjs";
|
|
19
19
|
import { pathExists } from "fs-extra";
|
|
20
20
|
import { injectVitePreamble } from "./injectVitePreamblePlugin.mjs";
|
|
@@ -27,11 +27,12 @@ import { manifestPlugin } from "./manifestPlugin.mjs";
|
|
|
27
27
|
import { linkerPlugin } from "./linkerPlugin.mjs";
|
|
28
28
|
import { directiveModulesDevPlugin } from "./directiveModulesDevPlugin.mjs";
|
|
29
29
|
import { directivesFilteringPlugin } from "./directivesFilteringPlugin.mjs";
|
|
30
|
-
|
|
30
|
+
import { resolveForcedPaths } from "./resolveForcedPaths.mjs";
|
|
31
|
+
export const determineWorkerEntryPathname = async ({ projectRootDir, workerConfigPath, options, readConfig = unstable_readConfig, }) => {
|
|
31
32
|
if (options.entry?.worker) {
|
|
32
33
|
return resolve(projectRootDir, options.entry.worker);
|
|
33
34
|
}
|
|
34
|
-
const workerConfig =
|
|
35
|
+
const workerConfig = readConfig({ config: workerConfigPath });
|
|
35
36
|
return resolve(projectRootDir, workerConfig.main ?? "src/worker.tsx");
|
|
36
37
|
};
|
|
37
38
|
const clientFiles = new Set();
|
|
@@ -39,11 +40,33 @@ const serverFiles = new Set();
|
|
|
39
40
|
const clientEntryPoints = new Set();
|
|
40
41
|
export const redwoodPlugin = async (options = {}) => {
|
|
41
42
|
const projectRootDir = process.cwd();
|
|
43
|
+
if (options.forceClientPaths) {
|
|
44
|
+
const clientPaths = await resolveForcedPaths({
|
|
45
|
+
patterns: options.forceClientPaths,
|
|
46
|
+
projectRootDir,
|
|
47
|
+
});
|
|
48
|
+
for (const p of clientPaths) {
|
|
49
|
+
clientFiles.add(p);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (options.forceServerPaths) {
|
|
53
|
+
const serverPaths = await resolveForcedPaths({
|
|
54
|
+
patterns: options.forceServerPaths,
|
|
55
|
+
projectRootDir,
|
|
56
|
+
});
|
|
57
|
+
for (const p of serverPaths) {
|
|
58
|
+
serverFiles.add(p);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
42
61
|
const workerConfigPath = options.configPath ??
|
|
43
62
|
(process.env.RWSDK_WRANGLER_CONFIG
|
|
44
63
|
? resolve(projectRootDir, process.env.RWSDK_WRANGLER_CONFIG)
|
|
45
64
|
: await findWranglerConfig(projectRootDir));
|
|
46
|
-
const workerEntryPathname = await determineWorkerEntryPathname(
|
|
65
|
+
const workerEntryPathname = await determineWorkerEntryPathname({
|
|
66
|
+
projectRootDir,
|
|
67
|
+
workerConfigPath,
|
|
68
|
+
options,
|
|
69
|
+
});
|
|
47
70
|
const shouldIncludeCloudflarePlugin = options.includeCloudflarePlugin ??
|
|
48
71
|
!(await hasOwnCloudflareVitePlugin({ rootProjectDir: projectRootDir }));
|
|
49
72
|
const shouldIncludeReactPlugin = options.includeReactPlugin ??
|
|
@@ -68,6 +91,7 @@ export const redwoodPlugin = async (options = {}) => {
|
|
|
68
91
|
clientFiles,
|
|
69
92
|
serverFiles,
|
|
70
93
|
projectRootDir,
|
|
94
|
+
workerEntryPathname,
|
|
71
95
|
}),
|
|
72
96
|
configPlugin({
|
|
73
97
|
silent: options.silent ?? false,
|
|
@@ -82,7 +106,7 @@ export const redwoodPlugin = async (options = {}) => {
|
|
|
82
106
|
serverFiles,
|
|
83
107
|
projectRootDir,
|
|
84
108
|
}),
|
|
85
|
-
|
|
109
|
+
knownDepsResolverPlugin({ projectRootDir }),
|
|
86
110
|
tsconfigPaths({ root: projectRootDir }),
|
|
87
111
|
shouldIncludeCloudflarePlugin
|
|
88
112
|
? cloudflare({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { determineWorkerEntryPathname } from "./redwoodPlugin.mjs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
describe("determineWorkerEntryPathname", () => {
|
|
5
|
+
const projectRootDir = "/test/project";
|
|
6
|
+
it("should use the entry path from options if provided", async () => {
|
|
7
|
+
const result = await determineWorkerEntryPathname({
|
|
8
|
+
projectRootDir,
|
|
9
|
+
workerConfigPath: "/test/project/wrangler.toml",
|
|
10
|
+
options: { entry: { worker: "src/custom-worker.ts" } },
|
|
11
|
+
});
|
|
12
|
+
expect(result).toBe(path.join(projectRootDir, "src/custom-worker.ts"));
|
|
13
|
+
});
|
|
14
|
+
it("should use the main path from wrangler config if no entry option is provided", async () => {
|
|
15
|
+
const readConfig = () => ({ main: "src/wrangler-worker.tsx" });
|
|
16
|
+
const result = await determineWorkerEntryPathname({
|
|
17
|
+
projectRootDir,
|
|
18
|
+
workerConfigPath: "/test/project/wrangler.toml",
|
|
19
|
+
options: {},
|
|
20
|
+
readConfig: readConfig,
|
|
21
|
+
});
|
|
22
|
+
expect(result).toBe(path.join(projectRootDir, "src/wrangler-worker.tsx"));
|
|
23
|
+
});
|
|
24
|
+
it("should use the default path if wrangler config has no main property", async () => {
|
|
25
|
+
const readConfig = () => ({});
|
|
26
|
+
const result = await determineWorkerEntryPathname({
|
|
27
|
+
projectRootDir,
|
|
28
|
+
workerConfigPath: "/test/project/wrangler.toml",
|
|
29
|
+
options: {},
|
|
30
|
+
readConfig: readConfig,
|
|
31
|
+
});
|
|
32
|
+
expect(result).toBe(path.join(projectRootDir, "src/worker.tsx"));
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { glob } from "glob";
|
|
2
|
+
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
3
|
+
export async function resolveForcedPaths({ patterns, projectRootDir, }) {
|
|
4
|
+
return (await glob(patterns, {
|
|
5
|
+
cwd: projectRootDir,
|
|
6
|
+
absolute: true,
|
|
7
|
+
realpath: true,
|
|
8
|
+
})).map((filepath) => normalizeModulePath(filepath, projectRootDir));
|
|
9
|
+
}
|
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import { Environment, ResolvedConfig } from "vite";
|
|
2
|
-
|
|
2
|
+
type Resolver = (context: {}, path: string, request: string, resolveContext: {}, callback: (err: Error | null, result?: string | false) => void) => void;
|
|
3
|
+
export declare function resolveModuleWithEnvironment({ path, importer, importerEnv, clientResolver, workerResolver, }: {
|
|
4
|
+
path: string;
|
|
5
|
+
importer?: string;
|
|
6
|
+
importerEnv: "client" | "worker";
|
|
7
|
+
clientResolver: Resolver;
|
|
8
|
+
workerResolver: Resolver;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
id: string;
|
|
11
|
+
} | null>;
|
|
12
|
+
export declare function classifyModule({ contents, inheritedEnv, }: {
|
|
13
|
+
contents: string;
|
|
14
|
+
inheritedEnv: "client" | "worker";
|
|
15
|
+
}): {
|
|
16
|
+
moduleEnv: "client" | "worker";
|
|
17
|
+
isClient: boolean;
|
|
18
|
+
isServer: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type EsbuildLoader = "js" | "jsx" | "ts" | "tsx" | "default";
|
|
21
|
+
export declare const runDirectivesScan: ({ rootConfig, environments, clientFiles, serverFiles, entries: initialEntries, }: {
|
|
3
22
|
rootConfig: ResolvedConfig;
|
|
4
23
|
environments: Record<string, Environment>;
|
|
5
24
|
clientFiles: Set<string>;
|
|
6
25
|
serverFiles: Set<string>;
|
|
26
|
+
entries?: string[];
|
|
7
27
|
}) => Promise<void>;
|
|
28
|
+
export {};
|
|
@@ -4,8 +4,10 @@ import path from "node:path";
|
|
|
4
4
|
import debug from "debug";
|
|
5
5
|
import { getViteEsbuild } from "./getViteEsbuild.mjs";
|
|
6
6
|
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
7
|
+
import { INTERMEDIATES_OUTPUT_DIR } from "../lib/constants.mjs";
|
|
7
8
|
import { externalModules } from "./constants.mjs";
|
|
8
|
-
import { createViteAwareResolver
|
|
9
|
+
import { createViteAwareResolver } from "./createViteAwareResolver.mjs";
|
|
10
|
+
import { compile } from "@mdx-js/mdx";
|
|
9
11
|
const log = debug("rwsdk:vite:run-directives-scan");
|
|
10
12
|
// Copied from Vite's source code.
|
|
11
13
|
// https://github.com/vitejs/vite/blob/main/packages/vite/src/shared/utils.ts
|
|
@@ -14,13 +16,47 @@ const isObject = (value) => Object.prototype.toString.call(value) === "[object O
|
|
|
14
16
|
// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/utils.ts
|
|
15
17
|
const externalRE = /^(https?:)?\/\//;
|
|
16
18
|
const isExternalUrl = (url) => externalRE.test(url);
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
+
export async function resolveModuleWithEnvironment({ path, importer, importerEnv, clientResolver, workerResolver, }) {
|
|
20
|
+
const resolver = importerEnv === "client" ? clientResolver : workerResolver;
|
|
21
|
+
return new Promise((resolvePromise) => {
|
|
22
|
+
resolver({}, importer || "", path, {}, (err, result) => {
|
|
23
|
+
if (!err && result) {
|
|
24
|
+
resolvePromise({ id: result });
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
if (err) {
|
|
28
|
+
const errorMessage = err.message || String(err);
|
|
29
|
+
if (errorMessage.includes("Package path . is not exported")) {
|
|
30
|
+
log("Package exports error for %s, marking as external", path);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
log("Resolution failed for %s: %s", path, errorMessage);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
resolvePromise(null);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export function classifyModule({ contents, inheritedEnv, }) {
|
|
42
|
+
let moduleEnv = inheritedEnv;
|
|
43
|
+
const isClient = hasDirective(contents, "use client");
|
|
44
|
+
const isServer = hasDirective(contents, "use server");
|
|
45
|
+
if (isClient) {
|
|
46
|
+
moduleEnv = "client";
|
|
47
|
+
}
|
|
48
|
+
else if (isServer) {
|
|
49
|
+
moduleEnv = "worker";
|
|
50
|
+
}
|
|
51
|
+
return { moduleEnv, isClient, isServer };
|
|
52
|
+
}
|
|
53
|
+
export const runDirectivesScan = async ({ rootConfig, environments, clientFiles, serverFiles, entries: initialEntries, }) => {
|
|
54
|
+
deferredLog("\n… (rwsdk) Scanning for 'use client' and 'use server' directives...");
|
|
19
55
|
// Set environment variable to indicate scanning is in progress
|
|
20
56
|
process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE = "true";
|
|
21
57
|
try {
|
|
22
58
|
const esbuild = await getViteEsbuild(rootConfig.root);
|
|
23
|
-
const input = environments.worker.config.build.rollupOptions?.input;
|
|
59
|
+
const input = initialEntries ?? environments.worker.config.build.rollupOptions?.input;
|
|
24
60
|
let entries;
|
|
25
61
|
if (Array.isArray(input)) {
|
|
26
62
|
entries = input;
|
|
@@ -38,7 +74,9 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
38
74
|
log("No entries found for directives scan in worker environment, skipping.");
|
|
39
75
|
return;
|
|
40
76
|
}
|
|
41
|
-
|
|
77
|
+
// Filter out virtual modules since they can't be scanned by esbuild
|
|
78
|
+
const realEntries = entries.filter((entry) => !entry.includes("virtual:"));
|
|
79
|
+
const absoluteEntries = realEntries.map((entry) => path.resolve(rootConfig.root, entry));
|
|
42
80
|
log("Starting directives scan for worker environment with entries:", absoluteEntries);
|
|
43
81
|
const workerResolver = createViteAwareResolver(rootConfig, environments.worker);
|
|
44
82
|
const clientResolver = createViteAwareResolver(rootConfig, environments.client);
|
|
@@ -57,7 +95,7 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
57
95
|
setup(build) {
|
|
58
96
|
// Match Vite's behavior by externalizing assets and special queries.
|
|
59
97
|
// This prevents esbuild from trying to bundle them, which would fail.
|
|
60
|
-
const scriptFilter = /\.(c|m)?[jt]sx
|
|
98
|
+
const scriptFilter = /\.(c|m)?[jt]sx?$|\.mdx$/;
|
|
61
99
|
const specialQueryFilter = /[?&](?:url|raw|worker|sharedworker|inline)\b/;
|
|
62
100
|
// This regex is used to identify if a path has any file extension.
|
|
63
101
|
const hasExtensionRegex = /\.[^/]+$/;
|
|
@@ -87,17 +125,12 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
87
125
|
/\.(m|c)?[jt]sx?$/.test(args.importer)) {
|
|
88
126
|
try {
|
|
89
127
|
const importerContents = await readFileWithCache(args.importer);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
log("Pre-detected importer 'use server' in:", args.importer);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
importerEnv = "worker"; // Default for entry points
|
|
100
|
-
}
|
|
128
|
+
const classification = classifyModule({
|
|
129
|
+
contents: importerContents,
|
|
130
|
+
inheritedEnv: "worker", // Default for entry points
|
|
131
|
+
});
|
|
132
|
+
importerEnv = classification.moduleEnv;
|
|
133
|
+
log("Pre-detected importer environment in:", args.importer, "as", importerEnv);
|
|
101
134
|
moduleEnvironments.set(args.importer, importerEnv);
|
|
102
135
|
}
|
|
103
136
|
catch (e) {
|
|
@@ -109,25 +142,12 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
109
142
|
importerEnv = "worker"; // Default for entry points or non-script files
|
|
110
143
|
}
|
|
111
144
|
log("Importer:", args.importer, "environment:", importerEnv);
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
else {
|
|
119
|
-
if (err) {
|
|
120
|
-
const errorMessage = err.message || String(err);
|
|
121
|
-
if (errorMessage.includes("Package path . is not exported")) {
|
|
122
|
-
log("Package exports error for %s, marking as external", args.path);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
log("Resolution failed for %s: %s", args.path, errorMessage);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
resolve(null);
|
|
129
|
-
}
|
|
130
|
-
});
|
|
145
|
+
const resolved = await resolveModuleWithEnvironment({
|
|
146
|
+
path: args.path,
|
|
147
|
+
importer: args.importer,
|
|
148
|
+
importerEnv,
|
|
149
|
+
clientResolver,
|
|
150
|
+
workerResolver,
|
|
131
151
|
});
|
|
132
152
|
log("Resolution result:", resolved);
|
|
133
153
|
const resolvedPath = resolved?.id;
|
|
@@ -143,7 +163,7 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
143
163
|
log("Marking as external:", args.path, "resolved to:", resolvedPath);
|
|
144
164
|
return { external: true };
|
|
145
165
|
});
|
|
146
|
-
build.onLoad({ filter: /\.(m|c)?[jt]sx
|
|
166
|
+
build.onLoad({ filter: /\.(m|c)?[jt]sx?$|\.mdx$/ }, async (args) => {
|
|
147
167
|
log("onLoad called for:", args.path);
|
|
148
168
|
if (!args.path.startsWith("/") ||
|
|
149
169
|
args.path.includes("virtual:") ||
|
|
@@ -156,33 +176,52 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
156
176
|
return null;
|
|
157
177
|
}
|
|
158
178
|
try {
|
|
159
|
-
const
|
|
179
|
+
const originalContents = await readFileWithCache(args.path);
|
|
160
180
|
const inheritedEnv = args.pluginData?.inheritedEnv || "worker";
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (isClient) {
|
|
166
|
-
currentEnv = "client";
|
|
167
|
-
}
|
|
168
|
-
else if (isServer) {
|
|
169
|
-
// `else if` handles cases where a file might have both directives.
|
|
170
|
-
// "use client" takes precedence.
|
|
171
|
-
currentEnv = "worker";
|
|
172
|
-
}
|
|
181
|
+
const { moduleEnv, isClient, isServer } = classifyModule({
|
|
182
|
+
contents: originalContents,
|
|
183
|
+
inheritedEnv,
|
|
184
|
+
});
|
|
173
185
|
// Store the definitive environment for this module, so it can be used when it becomes an importer.
|
|
174
|
-
|
|
175
|
-
|
|
186
|
+
const realPath = await fsp.realpath(args.path);
|
|
187
|
+
moduleEnvironments.set(realPath, moduleEnv);
|
|
188
|
+
log("Set environment for", realPath, "to", moduleEnv);
|
|
176
189
|
// Finally, populate the output sets if the file has a directive.
|
|
177
190
|
if (isClient) {
|
|
178
|
-
log("Discovered 'use client' in:",
|
|
179
|
-
clientFiles.add(normalizeModulePath(
|
|
191
|
+
log("Discovered 'use client' in:", realPath);
|
|
192
|
+
clientFiles.add(normalizeModulePath(realPath, rootConfig.root));
|
|
180
193
|
}
|
|
181
194
|
if (isServer) {
|
|
182
|
-
log("Discovered 'use server' in:",
|
|
183
|
-
serverFiles.add(normalizeModulePath(
|
|
195
|
+
log("Discovered 'use server' in:", realPath);
|
|
196
|
+
serverFiles.add(normalizeModulePath(realPath, rootConfig.root));
|
|
197
|
+
}
|
|
198
|
+
let code;
|
|
199
|
+
let loader;
|
|
200
|
+
if (args.path.endsWith(".mdx")) {
|
|
201
|
+
const result = await compile(originalContents, {
|
|
202
|
+
jsx: true,
|
|
203
|
+
jsxImportSource: "react",
|
|
204
|
+
});
|
|
205
|
+
code = String(result.value);
|
|
206
|
+
loader = "tsx";
|
|
207
|
+
}
|
|
208
|
+
else if (/\.(m|c)?tsx$/.test(args.path)) {
|
|
209
|
+
code = originalContents;
|
|
210
|
+
loader = "tsx";
|
|
184
211
|
}
|
|
185
|
-
|
|
212
|
+
else if (/\.(m|c)?ts$/.test(args.path)) {
|
|
213
|
+
code = originalContents;
|
|
214
|
+
loader = "ts";
|
|
215
|
+
}
|
|
216
|
+
else if (/\.(m|c)?jsx$/.test(args.path)) {
|
|
217
|
+
code = originalContents;
|
|
218
|
+
loader = "jsx";
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
code = originalContents;
|
|
222
|
+
loader = "js";
|
|
223
|
+
}
|
|
224
|
+
return { contents: code, loader };
|
|
186
225
|
}
|
|
187
226
|
catch (e) {
|
|
188
227
|
log("Could not read file during scan, skipping:", args.path, e);
|
|
@@ -195,6 +234,7 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
195
234
|
entryPoints: absoluteEntries,
|
|
196
235
|
bundle: true,
|
|
197
236
|
write: false,
|
|
237
|
+
outdir: path.join(INTERMEDIATES_OUTPUT_DIR, "directive-scan"),
|
|
198
238
|
platform: "node",
|
|
199
239
|
format: "esm",
|
|
200
240
|
logLevel: "silent",
|
|
@@ -207,6 +247,13 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
207
247
|
finally {
|
|
208
248
|
// Always clear the scanning flag when done
|
|
209
249
|
delete process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE;
|
|
210
|
-
|
|
250
|
+
deferredLog("✔ (rwsdk) Done scanning for 'use client' and 'use server' directives.");
|
|
251
|
+
process.env.VERBOSE &&
|
|
252
|
+
log("Client/server files after scanning: client=%O, server=%O", Array.from(clientFiles), Array.from(serverFiles));
|
|
211
253
|
}
|
|
212
254
|
};
|
|
255
|
+
const deferredLog = (message) => {
|
|
256
|
+
setTimeout(() => {
|
|
257
|
+
console.log(message);
|
|
258
|
+
}, 500);
|
|
259
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { resolveModuleWithEnvironment, classifyModule, } from "./runDirectivesScan.mjs";
|
|
3
|
+
describe("runDirectivesScan helpers", () => {
|
|
4
|
+
describe("resolveModuleWithEnvironment", () => {
|
|
5
|
+
it("should use the client resolver when importerEnv is 'client'", async () => {
|
|
6
|
+
const clientResolver = vi.fn((_a, _b, _c, _d, cb) => cb(null, "/resolved/client"));
|
|
7
|
+
const workerResolver = vi.fn();
|
|
8
|
+
const result = await resolveModuleWithEnvironment({
|
|
9
|
+
path: "test-path",
|
|
10
|
+
importerEnv: "client",
|
|
11
|
+
clientResolver,
|
|
12
|
+
workerResolver,
|
|
13
|
+
});
|
|
14
|
+
expect(clientResolver).toHaveBeenCalled();
|
|
15
|
+
expect(workerResolver).not.toHaveBeenCalled();
|
|
16
|
+
expect(result).toEqual({ id: "/resolved/client" });
|
|
17
|
+
});
|
|
18
|
+
it("should use the worker resolver when importerEnv is 'worker'", async () => {
|
|
19
|
+
const clientResolver = vi.fn();
|
|
20
|
+
const workerResolver = vi.fn((_a, _b, _c, _d, cb) => cb(null, "/resolved/worker"));
|
|
21
|
+
const result = await resolveModuleWithEnvironment({
|
|
22
|
+
path: "test-path",
|
|
23
|
+
importerEnv: "worker",
|
|
24
|
+
clientResolver,
|
|
25
|
+
workerResolver,
|
|
26
|
+
});
|
|
27
|
+
expect(workerResolver).toHaveBeenCalled();
|
|
28
|
+
expect(clientResolver).not.toHaveBeenCalled();
|
|
29
|
+
expect(result).toEqual({ id: "/resolved/worker" });
|
|
30
|
+
});
|
|
31
|
+
it("should return null on resolution error", async () => {
|
|
32
|
+
const clientResolver = vi.fn((_a, _b, _c, _d, cb) => cb(new Error("Resolution failed")));
|
|
33
|
+
const workerResolver = vi.fn();
|
|
34
|
+
const result = await resolveModuleWithEnvironment({
|
|
35
|
+
path: "test-path",
|
|
36
|
+
importerEnv: "client",
|
|
37
|
+
clientResolver,
|
|
38
|
+
workerResolver,
|
|
39
|
+
});
|
|
40
|
+
expect(result).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe("classifyModule", () => {
|
|
44
|
+
it("should return 'client' if 'use client' directive is present", () => {
|
|
45
|
+
const contents = `'use client';\nconsole.log('hello');`;
|
|
46
|
+
const result = classifyModule({ contents, inheritedEnv: "worker" });
|
|
47
|
+
expect(result.moduleEnv).toBe("client");
|
|
48
|
+
expect(result.isClient).toBe(true);
|
|
49
|
+
expect(result.isServer).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
it("should return 'worker' if 'use server' directive is present", () => {
|
|
52
|
+
const contents = `"use server";\nexport default () => {};`;
|
|
53
|
+
const result = classifyModule({ contents, inheritedEnv: "client" });
|
|
54
|
+
expect(result.moduleEnv).toBe("worker");
|
|
55
|
+
expect(result.isClient).toBe(false);
|
|
56
|
+
expect(result.isServer).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
it("should prioritize 'use client' over 'use server'", () => {
|
|
59
|
+
const contents = `'use client';\n'use server';\nconsole.log('hello');`;
|
|
60
|
+
const result = classifyModule({ contents, inheritedEnv: "worker" });
|
|
61
|
+
expect(result.moduleEnv).toBe("client");
|
|
62
|
+
expect(result.isClient).toBe(true);
|
|
63
|
+
expect(result.isServer).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
it("should return the inherited environment if no directive is present", () => {
|
|
66
|
+
const contents = `console.log('no directive');`;
|
|
67
|
+
const result = classifyModule({ contents, inheritedEnv: "worker" });
|
|
68
|
+
expect(result.moduleEnv).toBe("worker");
|
|
69
|
+
expect(result.isClient).toBe(false);
|
|
70
|
+
expect(result.isServer).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -34,7 +34,8 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
34
34
|
build.onResolve({ filter: /.*$/ }, (args) => {
|
|
35
35
|
process.env.VERBOSE &&
|
|
36
36
|
log("Esbuild onResolve called for path=%s, args=%O", args.path, args);
|
|
37
|
-
if (args.path === "rwsdk/__ssr_bridge"
|
|
37
|
+
if (args.path === "rwsdk/__ssr_bridge" ||
|
|
38
|
+
args.path.startsWith(VIRTUAL_SSR_PREFIX)) {
|
|
38
39
|
log("Marking as external: %s", args.path);
|
|
39
40
|
return {
|
|
40
41
|
path: args.path,
|
|
@@ -77,6 +78,12 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
77
78
|
}
|
|
78
79
|
else {
|
|
79
80
|
// In build mode, the behavior depends on the build pass
|
|
81
|
+
if (id.startsWith(VIRTUAL_SSR_PREFIX)) {
|
|
82
|
+
if (this.environment.name === "worker") {
|
|
83
|
+
log("Virtual SSR module case (build-worker pass): resolving to external");
|
|
84
|
+
return { id, external: true };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
80
87
|
if (id === "rwsdk/__ssr_bridge" && this.environment.name === "worker") {
|
|
81
88
|
if (process.env.RWSDK_BUILD_PASS === "worker") {
|
|
82
89
|
// First pass: resolve to a temporary, external path
|
|
@@ -5,7 +5,8 @@ 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
|
-
if (!
|
|
8
|
+
if (!ctx.clientFiles?.has(normalizedId) &&
|
|
9
|
+
!hasDirective(code, "use client")) {
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
11
12
|
const log = ctx.isEsbuild ? logEsbuild : logVite;
|
|
@@ -76,13 +77,14 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
76
77
|
// 4. Non-SSR files: replace all implementation with registerClientReference logic
|
|
77
78
|
// Generate completely new code for worker/client environments
|
|
78
79
|
const s = new MagicString("");
|
|
79
|
-
|
|
80
|
+
s.append('import { ssrLoadModule } from "rwsdk/__ssr_bridge";\n');
|
|
80
81
|
s.append('import { registerClientReference } from "rwsdk/worker";\n');
|
|
82
|
+
s.append(`const SSRModule = await ssrLoadModule("${normalizedId}");\n`);
|
|
81
83
|
// Compute unique computed local names first
|
|
82
84
|
const computedLocalNames = new Map(processedExports.map((info) => [getComputedLocalName(info), info]));
|
|
83
85
|
// Add registerClientReference assignments for unique names
|
|
84
86
|
for (const [computedLocalName, correspondingInfo] of computedLocalNames) {
|
|
85
|
-
s.append(`const ${computedLocalName} = registerClientReference("${normalizedId}", "${correspondingInfo.exported}");\n`);
|
|
87
|
+
s.append(`const ${computedLocalName} = registerClientReference(SSRModule, "${normalizedId}", "${correspondingInfo.exported}");\n`);
|
|
86
88
|
}
|
|
87
89
|
// Add grouped export statement for named exports (preserving order and alias)
|
|
88
90
|
if (processedExports.length > 0) {
|
|
@@ -94,7 +96,7 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
94
96
|
// Add default export if present
|
|
95
97
|
if (defaultExportInfo) {
|
|
96
98
|
log(":isEsbuild=%s: Registering client reference for default export: %s", !!ctx.isEsbuild, defaultExportInfo.exported);
|
|
97
|
-
s.append(`export default registerClientReference("${normalizedId}", "${defaultExportInfo.exported}");\n`);
|
|
99
|
+
s.append(`export default registerClientReference(SSRModule, "${normalizedId}", "${defaultExportInfo.exported}");\n`);
|
|
98
100
|
}
|
|
99
101
|
const sourceMap = s.generateMap({
|
|
100
102
|
source: normalizedId,
|