rwsdk 0.2.0 → 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.
Files changed (58) hide show
  1. package/dist/lib/constants.d.mts +6 -1
  2. package/dist/lib/constants.mjs +6 -1
  3. package/dist/lib/smokeTests/browser.mjs +5 -21
  4. package/dist/lib/smokeTests/codeUpdates.d.mts +1 -1
  5. package/dist/lib/smokeTests/codeUpdates.mjs +41 -5
  6. package/dist/lib/smokeTests/development.d.mts +1 -1
  7. package/dist/lib/smokeTests/development.mjs +4 -10
  8. package/dist/lib/smokeTests/release.d.mts +1 -1
  9. package/dist/lib/smokeTests/release.mjs +4 -9
  10. package/dist/lib/smokeTests/runSmokeTests.mjs +2 -2
  11. package/dist/lib/smokeTests/templates/SmokeTest.template.js +3 -2
  12. package/dist/lib/testUtils/stubEnvVars.d.mts +2 -0
  13. package/dist/lib/testUtils/stubEnvVars.mjs +11 -0
  14. package/dist/runtime/imports/client.js +4 -9
  15. package/dist/runtime/imports/worker.js +2 -1
  16. package/dist/runtime/register/ssr.js +2 -1
  17. package/dist/runtime/requestInfo/worker.js +9 -1
  18. package/dist/runtime/worker.d.ts +0 -3
  19. package/dist/runtime/worker.js +1 -10
  20. package/dist/scripts/debug-sync.mjs +0 -23
  21. package/dist/scripts/smoke-test.mjs +0 -10
  22. package/dist/vite/buildApp.d.mts +15 -0
  23. package/dist/vite/buildApp.mjs +53 -0
  24. package/dist/vite/configPlugin.d.mts +4 -2
  25. package/dist/vite/configPlugin.mjs +69 -62
  26. package/dist/vite/createDirectiveLookupPlugin.d.mts +0 -6
  27. package/dist/vite/createDirectiveLookupPlugin.mjs +61 -145
  28. package/dist/vite/directiveModulesDevPlugin.d.mts +8 -0
  29. package/dist/vite/directiveModulesDevPlugin.mjs +62 -0
  30. package/dist/vite/directivesFilteringPlugin.d.mts +6 -0
  31. package/dist/vite/directivesFilteringPlugin.mjs +31 -0
  32. package/dist/vite/directivesPlugin.mjs +28 -42
  33. package/dist/vite/getViteEsbuild.d.mts +1 -0
  34. package/dist/vite/getViteEsbuild.mjs +12 -0
  35. package/dist/vite/injectVitePreamblePlugin.d.mts +3 -2
  36. package/dist/vite/injectVitePreamblePlugin.mjs +4 -2
  37. package/dist/vite/linkerPlugin.d.mts +4 -0
  38. package/dist/vite/linkerPlugin.mjs +41 -0
  39. package/dist/vite/manifestPlugin.d.mts +2 -2
  40. package/dist/vite/manifestPlugin.mjs +12 -37
  41. package/dist/vite/moveStaticAssetsPlugin.mjs +2 -1
  42. package/dist/vite/prismaPlugin.mjs +1 -1
  43. package/dist/vite/reactConditionsResolverPlugin.mjs +11 -16
  44. package/dist/vite/redwoodPlugin.d.mts +0 -1
  45. package/dist/vite/redwoodPlugin.mjs +27 -9
  46. package/dist/vite/runDirectivesScan.d.mts +7 -0
  47. package/dist/vite/runDirectivesScan.mjs +152 -0
  48. package/dist/vite/ssrBridgePlugin.mjs +13 -14
  49. package/dist/vite/transformClientComponents.d.mts +0 -1
  50. package/dist/vite/transformClientComponents.mjs +1 -9
  51. package/dist/vite/transformJsxScriptTagsPlugin.d.mts +4 -3
  52. package/dist/vite/transformJsxScriptTagsPlugin.mjs +62 -84
  53. package/dist/vite/transformJsxScriptTagsPlugin.test.mjs +67 -41
  54. package/dist/vite/transformServerFunctions.d.mts +1 -1
  55. package/dist/vite/transformServerFunctions.mjs +11 -12
  56. package/package.json +7 -1
  57. package/dist/runtime/clientNavigation.d.ts +0 -9
  58. package/dist/runtime/clientNavigation.js +0 -88
@@ -28,36 +28,12 @@ const getLoader = (filePath) => {
28
28
  export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, }) => {
29
29
  let devServer;
30
30
  let isAfterFirstResponse = false;
31
- const addModule = (kind, environment, id) => {
32
- const files = kind === "client" ? clientFiles : serverFiles;
33
- const rawId = id.split("?")[0];
34
- const resolvedId = normalizeModulePath(rawId, projectRootDir);
35
- const fullPath = normalizeModulePath(rawId, projectRootDir, {
36
- absolute: true,
37
- });
38
- const isNodeModule = id.includes("node_modules");
39
- const hadFile = files.has(id);
40
- log("Adding %s module to %s and invalidating cache: id=%s", kind, files, resolvedId);
41
- files.add(resolvedId);
42
- if (devServer && isNodeModule) {
43
- const lookupModule = kind === "client"
44
- ? "virtual:use-client-lookup"
45
- : "virtual:use-server-lookup";
46
- log("Registering missing import for %s module resolvedId=%s in environment %s, fullPath=%s", kind, resolvedId, environment, fullPath);
47
- devServer.environments[environment].depsOptimizer?.registerMissingImport(resolvedId, fullPath);
48
- if (isAfterFirstResponse && !hadFile) {
49
- log("Invalidating cache for lookup module %s after adding module id=%s", lookupModule, id);
50
- }
51
- }
52
- };
53
- const addClientModule = (environment, id) => {
54
- addModule("client", environment, id);
55
- };
56
- const addServerModule = (environment, id) => {
57
- addModule("server", environment, id);
58
- };
31
+ let isBuild = false;
59
32
  return {
60
33
  name: "rwsdk:rsc-directives",
34
+ configResolved(config) {
35
+ isBuild = config.command === "build";
36
+ },
61
37
  configureServer(server) {
62
38
  devServer = server;
63
39
  devServer.middlewares.use((_req, res, next) => {
@@ -76,33 +52,42 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
76
52
  });
77
53
  },
78
54
  async transform(code, id) {
79
- process.env.VERBOSE &&
80
- log("Transform called for id=%s, environment=%s", id, this.environment.name);
55
+ if (isBuild &&
56
+ this.environment?.name === "worker" &&
57
+ process.env.RWSDK_BUILD_PASS !== "worker") {
58
+ return;
59
+ }
81
60
  const normalizedId = normalizeModulePath(id, projectRootDir);
82
61
  const clientResult = await transformClientComponents(code, normalizedId, {
83
62
  environmentName: this.environment.name,
84
63
  clientFiles,
85
- addClientModule,
86
64
  });
87
65
  if (clientResult) {
88
- log("Client component transformation successful for id=%s", id);
66
+ process.env.VERBOSE &&
67
+ log("Client component transformation successful for id=%s", id);
89
68
  return {
90
69
  code: clientResult.code,
91
70
  map: clientResult.map,
92
71
  };
93
72
  }
94
- const serverResult = transformServerFunctions(code, normalizedId, this.environment.name, serverFiles, addServerModule);
73
+ const serverResult = transformServerFunctions(code, normalizedId, this.environment.name, serverFiles);
95
74
  if (serverResult) {
96
- log("Server function transformation successful for id=%s", id);
75
+ process.env.VERBOSE &&
76
+ log("Server function transformation successful for id=%s", id);
97
77
  return {
98
78
  code: serverResult.code,
99
79
  map: serverResult.map,
100
80
  };
101
81
  }
102
- process.env.VERBOSE && log("No transformation applied for id=%s", id);
82
+ // Removed: too noisy even in verbose mode
103
83
  },
104
84
  configEnvironment(env, config) {
105
- log("Configuring environment: env=%s", env);
85
+ if (isBuild &&
86
+ env === "worker" &&
87
+ process.env.RWSDK_BUILD_PASS !== "worker") {
88
+ return;
89
+ }
90
+ process.env.VERBOSE && log("Configuring environment: env=%s", env);
106
91
  config.optimizeDeps ??= {};
107
92
  config.optimizeDeps.esbuildOptions ??= {};
108
93
  config.optimizeDeps.esbuildOptions.plugins ??= [];
@@ -120,7 +105,6 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
120
105
  // dependency discovery, so we can skip transform work
121
106
  // and use heuristics instead - see below inside if block
122
107
  if (!args.path.includes("node_modules")) {
123
- log("Esbuild onLoad found app code, path=%s", args.path);
124
108
  if (clientFiles.has(normalizedPath)) {
125
109
  // context(justinvdm,2025-06-15): If this is a client file:
126
110
  // * for ssr and client envs we can skip so esbuild looks at the
@@ -171,10 +155,10 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
171
155
  environmentName: env,
172
156
  clientFiles,
173
157
  isEsbuild: true,
174
- addClientModule,
175
158
  });
176
159
  if (clientResult) {
177
- log("Esbuild client component transformation successful for environment=%s, path=%s", env, args.path);
160
+ process.env.VERBOSE &&
161
+ log("Esbuild client component transformation successful for environment=%s, path=%s", env, args.path);
178
162
  process.env.VERBOSE &&
179
163
  log("Esbuild client component transformation for environment=%s, path=%s, code: %j", env, args.path, clientResult.code);
180
164
  return {
@@ -182,9 +166,10 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
182
166
  loader: getLoader(args.path),
183
167
  };
184
168
  }
185
- const serverResult = transformServerFunctions(code, normalizedPath, env, serverFiles, addServerModule);
169
+ const serverResult = transformServerFunctions(code, normalizedPath, env, serverFiles);
186
170
  if (serverResult) {
187
- log("Esbuild server function transformation successful for environment=%s, path=%s", env, args.path);
171
+ process.env.VERBOSE &&
172
+ log("Esbuild server function transformation successful for environment=%s, path=%s", env, args.path);
188
173
  return {
189
174
  contents: serverResult.code,
190
175
  loader: getLoader(args.path),
@@ -195,7 +180,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
195
180
  });
196
181
  },
197
182
  });
198
- log("Environment configuration complete for env=%s", env);
183
+ process.env.VERBOSE &&
184
+ log("Environment configuration complete for env=%s", env);
199
185
  },
200
186
  };
201
187
  };
@@ -0,0 +1 @@
1
+ export declare function getViteEsbuild(projectRootDir: string): Promise<any>;
@@ -0,0 +1,12 @@
1
+ import path from "node:path";
2
+ import { createRequire } from "node:module";
3
+ const require = createRequire(import.meta.url);
4
+ export async function getViteEsbuild(projectRootDir) {
5
+ const vitePath = require.resolve("vite/package.json", {
6
+ paths: [projectRootDir],
7
+ });
8
+ const viteDir = path.dirname(vitePath);
9
+ const esbuildPath = require.resolve("esbuild", { paths: [viteDir] });
10
+ const esbuildModule = await import(esbuildPath);
11
+ return esbuildModule.default || esbuildModule;
12
+ }
@@ -1,4 +1,5 @@
1
1
  import { type Plugin } from "vite";
2
- export declare const injectVitePreamble: ({ clientEntryPathnames, }: {
3
- clientEntryPathnames: string[];
2
+ export declare const injectVitePreamble: ({ clientEntryPoints, projectRootDir, }: {
3
+ clientEntryPoints: Set<string>;
4
+ projectRootDir: string;
4
5
  }) => Plugin;
@@ -1,12 +1,14 @@
1
1
  import MagicString from "magic-string";
2
- export const injectVitePreamble = ({ clientEntryPathnames, }) => ({
2
+ import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
3
+ export const injectVitePreamble = ({ clientEntryPoints, projectRootDir, }) => ({
3
4
  name: "rwsdk:inject-vite-preamble",
4
5
  apply: "serve",
5
6
  transform(code, id) {
6
7
  if (this.environment.name !== "client") {
7
8
  return;
8
9
  }
9
- if (!clientEntryPathnames.includes(id)) {
10
+ const normalizedId = normalizeModulePath(id, projectRootDir);
11
+ if (!clientEntryPoints.has(normalizedId)) {
10
12
  return;
11
13
  }
12
14
  // Only inject preamble in development mode
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from "vite";
2
+ export declare const linkerPlugin: ({ projectRootDir, }: {
3
+ projectRootDir: string;
4
+ }) => Plugin;
@@ -0,0 +1,41 @@
1
+ import path from "node:path";
2
+ import fsp from "node:fs/promises";
3
+ import { CLIENT_MANIFEST_RELATIVE_PATH } from "../lib/constants.mjs";
4
+ import debug from "debug";
5
+ import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
6
+ const log = debug("rwsdk:vite:linker-plugin");
7
+ export const linkerPlugin = ({ projectRootDir, }) => {
8
+ return {
9
+ name: "rwsdk:linker",
10
+ async renderChunk(code) {
11
+ if (this.environment.name !== "worker" ||
12
+ process.env.RWSDK_BUILD_PASS !== "linker") {
13
+ return null;
14
+ }
15
+ log("Rendering final worker chunk");
16
+ let newCode = code;
17
+ // Read the manifest from the filesystem.
18
+ const manifestContent = await fsp.readFile(path.resolve(projectRootDir, CLIENT_MANIFEST_RELATIVE_PATH), "utf-8");
19
+ const manifest = JSON.parse(manifestContent);
20
+ // 1. Replace the manifest placeholder with the actual manifest content.
21
+ log("Injecting manifest into worker bundle");
22
+ newCode = newCode.replace('"__RWSDK_MANIFEST_PLACEHOLDER__"', manifestContent);
23
+ // 2. Replace asset placeholders with their final hashed paths.
24
+ log("Replacing asset placeholders in final worker bundle");
25
+ for (const [key, value] of Object.entries(manifest)) {
26
+ const normalizedKey = normalizeModulePath(key, projectRootDir, {
27
+ isViteStyle: false,
28
+ });
29
+ newCode = newCode.replaceAll(`rwsdk_asset:${normalizedKey}`, `/${value.file}`);
30
+ }
31
+ // 3. Deprefix any remaining placeholders that were not in the manifest.
32
+ // This handles public assets that don't go through the bundler.
33
+ log("Deprefixing remaining asset placeholders");
34
+ newCode = newCode.replaceAll("rwsdk_asset:", "");
35
+ return {
36
+ code: newCode,
37
+ map: null,
38
+ };
39
+ },
40
+ };
41
+ };
@@ -1,4 +1,4 @@
1
1
  import { type Plugin } from "vite";
2
- export declare const manifestPlugin: ({ manifestPath, }: {
3
- manifestPath: string;
2
+ export declare const manifestPlugin: ({ projectRootDir, }: {
3
+ projectRootDir: string;
4
4
  }) => Plugin;
@@ -1,57 +1,32 @@
1
- import { readFile } from "node:fs/promises";
2
1
  import debug from "debug";
3
- import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
4
2
  const log = debug("rwsdk:vite:manifest-plugin");
5
3
  const virtualModuleId = "virtual:rwsdk:manifest.js";
6
4
  const resolvedVirtualModuleId = "\0" + virtualModuleId;
7
- export const manifestPlugin = ({ manifestPath, }) => {
5
+ export const manifestPlugin = ({ projectRootDir, }) => {
8
6
  let isBuild = false;
9
- let root;
10
7
  return {
11
- name: "rwsdk:manifest",
8
+ name: "rwsdk:vite:manifest-plugin",
9
+ enforce: "pre",
12
10
  configResolved(config) {
13
- log("Config resolved, command=%s", config.command);
14
11
  isBuild = config.command === "build";
15
- root = config.root;
16
12
  },
17
13
  resolveId(id) {
18
14
  if (id === virtualModuleId) {
19
- process.env.VERBOSE && log("Resolving virtual module id=%s", id);
20
15
  return resolvedVirtualModuleId;
21
16
  }
22
17
  },
23
18
  async load(id) {
24
19
  if (id === resolvedVirtualModuleId) {
25
- process.env.VERBOSE && log("Loading virtual module id=%s", id);
26
- if (!isBuild) {
27
- process.env.VERBOSE && log("Not a build, returning empty manifest");
28
- return `export default {}`;
20
+ if (isBuild) {
21
+ // context(justinvdm, 28 Aug 2025): During the build, we don't have
22
+ // the manifest yet. We insert a placeholder that the linker plugin
23
+ // will replace in the final phase.
24
+ log("Returning manifest placeholder for build");
25
+ return `export default "__RWSDK_MANIFEST_PLACEHOLDER__"`;
29
26
  }
30
- log("Reading manifest from %s", manifestPath);
31
- const manifestContent = await readFile(manifestPath, "utf-8");
32
- const manifest = JSON.parse(manifestContent);
33
- const normalizedManifest = {};
34
- for (const key in manifest) {
35
- const normalizedKey = normalizeModulePath(key, root, {
36
- isViteStyle: false,
37
- });
38
- const entry = manifest[key];
39
- delete manifest[key];
40
- normalizedManifest[normalizedKey] = entry;
41
- entry.file = normalizeModulePath(entry.file, root, {
42
- isViteStyle: false,
43
- });
44
- const normalizedCss = [];
45
- if (entry.css) {
46
- for (const css of entry.css) {
47
- normalizedCss.push(normalizeModulePath(css, root, {
48
- isViteStyle: false,
49
- }));
50
- }
51
- entry.css = normalizedCss;
52
- }
53
- }
54
- return `export default ${JSON.stringify(normalizedManifest)}`;
27
+ // In dev, we can return an empty object.
28
+ log("Not a build, returning empty manifest");
29
+ return `export default {}`;
55
30
  }
56
31
  },
57
32
  configEnvironment(name, config) {
@@ -3,7 +3,8 @@ export const moveStaticAssetsPlugin = ({ rootDir, }) => ({
3
3
  name: "rwsdk:move-static-assets",
4
4
  apply: "build",
5
5
  async closeBundle() {
6
- if (this.environment.name === "worker") {
6
+ if (this.environment.name === "worker" &&
7
+ process.env.RWSDK_BUILD_PASS === "linker") {
7
8
  await $sh({
8
9
  cwd: rootDir,
9
10
  }) `mv dist/worker/assets/*.css dist/client/assets/ || true`;
@@ -17,7 +17,7 @@ export const prismaPlugin = async ({ projectRootDir, }) => {
17
17
  return {
18
18
  name: "rwsdk:prisma",
19
19
  configEnvironment(name, config) {
20
- if (name !== "worker") {
20
+ if (name !== "worker" || !process.env.VITE_IS_DEV_SERVER) {
21
21
  return;
22
22
  }
23
23
  const wasmPath = resolve(projectRootDir, "node_modules/.prisma/client/wasm.js");
@@ -79,10 +79,12 @@ function resolveEnvImportMappings(env, projectRootDir) {
79
79
  const resolved = resolveReactImport(importRequest, env, projectRootDir, true);
80
80
  if (resolved) {
81
81
  mappings.set(importRequest, resolved);
82
- log("Added mapping for %s -> %s in env=%s", importRequest, resolved, env);
82
+ process.env.VERBOSE &&
83
+ log("Added mapping for %s -> %s in env=%s", importRequest, resolved, env);
83
84
  }
84
85
  }
85
- log("Environment import mappings complete for env=%s: %d mappings", env, mappings.size);
86
+ process.env.VERBOSE &&
87
+ log("Environment import mappings complete for env=%s: %d mappings", env, mappings.size);
86
88
  return mappings;
87
89
  }
88
90
  export const reactConditionsResolverPlugin = ({ projectRootDir, }) => {
@@ -92,6 +94,9 @@ export const reactConditionsResolverPlugin = ({ projectRootDir, }) => {
92
94
  env,
93
95
  resolveEnvImportMappings(env, projectRootDir),
94
96
  ]));
97
+ // Log a clean summary instead of all the individual mappings
98
+ const totalMappings = Object.values(ENV_IMPORT_MAPPINGS).reduce((sum, mappings) => sum + mappings.size, 0);
99
+ log("React conditions resolver configured with %d total mappings across %d environments", totalMappings, Object.keys(ENV_IMPORT_MAPPINGS).length);
95
100
  function createEsbuildResolverPlugin(envName, mappings) {
96
101
  if (!mappings) {
97
102
  return null;
@@ -100,15 +105,11 @@ export const reactConditionsResolverPlugin = ({ projectRootDir, }) => {
100
105
  name: `rwsdk:react-conditions-resolver-esbuild-${envName}`,
101
106
  setup(build) {
102
107
  build.onResolve({ filter: /.*/ }, (args) => {
103
- process.env.VERBOSE &&
104
- log("ESBuild resolving %s for env=%s, args=%O", args.path, envName, args);
105
108
  let resolved = mappings.get(args.path);
106
109
  if (!resolved) {
107
110
  resolved = resolveReactImport(args.path, envName, projectRootDir);
108
111
  }
109
112
  if (resolved && args.importer !== "") {
110
- process.env.VERBOSE &&
111
- log("ESBuild resolving %s -> %s for env=%s", args.path, resolved, envName);
112
113
  if (args.path === "react-server-dom-webpack/client.edge") {
113
114
  return;
114
115
  }
@@ -116,10 +117,6 @@ export const reactConditionsResolverPlugin = ({ projectRootDir, }) => {
116
117
  path: resolved,
117
118
  };
118
119
  }
119
- else {
120
- process.env.VERBOSE &&
121
- log("ESBuild no resolution found for %s for env=%s", args.path, envName);
122
- }
123
120
  });
124
121
  },
125
122
  };
@@ -161,7 +158,8 @@ export const reactConditionsResolverPlugin = ({ projectRootDir, }) => {
161
158
  for (const [find, replacement] of mappings) {
162
159
  const findRegex = new RegExp(`^${find.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")}$`);
163
160
  aliases.push({ find: findRegex, replacement });
164
- log("Added alias for env=%s: %s -> %s", envName, find, replacement);
161
+ process.env.VERBOSE &&
162
+ log("Added alias for env=%s: %s -> %s", envName, find, replacement);
165
163
  }
166
164
  log("Environment %s configured with %d aliases and %d optimizeDeps includes", envName, mappings.size, reactImports.length);
167
165
  }
@@ -178,8 +176,6 @@ export const reactConditionsResolverPlugin = ({ projectRootDir, }) => {
178
176
  if (!envName) {
179
177
  return;
180
178
  }
181
- process.env.VERBOSE &&
182
- log("Resolving id=%s, environment=%s, importer=%s", id, envName, importer);
183
179
  const mappings = ENV_IMPORT_MAPPINGS[envName];
184
180
  if (!mappings) {
185
181
  process.env.VERBOSE &&
@@ -191,11 +187,10 @@ export const reactConditionsResolverPlugin = ({ projectRootDir, }) => {
191
187
  resolved = resolveReactImport(id, envName, projectRootDir);
192
188
  }
193
189
  if (resolved) {
194
- log("Resolved %s -> %s for env=%s", id, resolved, envName);
190
+ process.env.VERBOSE &&
191
+ log("Resolved %s -> %s for env=%s", id, resolved, envName);
195
192
  return resolved;
196
193
  }
197
- process.env.VERBOSE &&
198
- log("No resolution found for id=%s in env=%s", id, envName);
199
194
  },
200
195
  },
201
196
  ];
@@ -6,7 +6,6 @@ export type RedwoodPluginOptions = {
6
6
  includeReactPlugin?: boolean;
7
7
  configPath?: string;
8
8
  entry?: {
9
- client?: string | string[];
10
9
  worker?: string;
11
10
  };
12
11
  };
@@ -24,6 +24,9 @@ import { ssrBridgePlugin } from "./ssrBridgePlugin.mjs";
24
24
  import { hasPkgScript } from "../lib/hasPkgScript.mjs";
25
25
  import { devServerTimingPlugin } from "./devServerTimingPlugin.mjs";
26
26
  import { manifestPlugin } from "./manifestPlugin.mjs";
27
+ import { linkerPlugin } from "./linkerPlugin.mjs";
28
+ import { directiveModulesDevPlugin } from "./directiveModulesDevPlugin.mjs";
29
+ import { directivesFilteringPlugin } from "./directivesFilteringPlugin.mjs";
27
30
  const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, options) => {
28
31
  if (options.entry?.worker) {
29
32
  return resolve(projectRootDir, options.entry.worker);
@@ -31,6 +34,9 @@ const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, op
31
34
  const workerConfig = unstable_readConfig({ config: workerConfigPath });
32
35
  return resolve(projectRootDir, workerConfig.main ?? "src/worker.tsx");
33
36
  };
37
+ const clientFiles = new Set();
38
+ const serverFiles = new Set();
39
+ const clientEntryPoints = new Set();
34
40
  export const redwoodPlugin = async (options = {}) => {
35
41
  const projectRootDir = process.cwd();
36
42
  const workerConfigPath = options.configPath ??
@@ -38,11 +44,6 @@ export const redwoodPlugin = async (options = {}) => {
38
44
  ? resolve(projectRootDir, process.env.RWSDK_WRANGLER_CONFIG)
39
45
  : await findWranglerConfig(projectRootDir));
40
46
  const workerEntryPathname = await determineWorkerEntryPathname(projectRootDir, workerConfigPath, options);
41
- const clientEntryPathnames = (Array.isArray(options.entry?.client)
42
- ? options.entry.client
43
- : [options.entry?.client ?? "src/client.tsx"]).map((entry) => resolve(projectRootDir, entry));
44
- const clientFiles = new Set();
45
- const serverFiles = new Set();
46
47
  const shouldIncludeCloudflarePlugin = options.includeCloudflarePlugin ??
47
48
  !(await hasOwnCloudflareVitePlugin({ rootProjectDir: projectRootDir }));
48
49
  const shouldIncludeReactPlugin = options.includeReactPlugin ??
@@ -62,12 +63,19 @@ export const redwoodPlugin = async (options = {}) => {
62
63
  }
63
64
  return [
64
65
  devServerTimingPlugin(),
66
+ directiveModulesDevPlugin({
67
+ clientFiles,
68
+ serverFiles,
69
+ projectRootDir,
70
+ }),
65
71
  devServerConstantPlugin(),
66
72
  configPlugin({
67
73
  silent: options.silent ?? false,
68
74
  projectRootDir,
69
- clientEntryPathnames,
70
75
  workerEntryPathname,
76
+ clientFiles,
77
+ serverFiles,
78
+ clientEntryPoints,
71
79
  }),
72
80
  ssrBridgePlugin({
73
81
  clientFiles,
@@ -96,7 +104,10 @@ export const redwoodPlugin = async (options = {}) => {
96
104
  serverFiles,
97
105
  }),
98
106
  vitePreamblePlugin(),
99
- injectVitePreamble({ clientEntryPathnames }),
107
+ injectVitePreamble({
108
+ clientEntryPoints,
109
+ projectRootDir,
110
+ }),
100
111
  useClientLookupPlugin({
101
112
  projectRootDir,
102
113
  clientFiles,
@@ -106,12 +117,19 @@ export const redwoodPlugin = async (options = {}) => {
106
117
  serverFiles,
107
118
  }),
108
119
  transformJsxScriptTagsPlugin({
109
- manifestPath: resolve(projectRootDir, "dist", "client", ".vite", "manifest.json"),
120
+ clientEntryPoints,
121
+ projectRootDir,
110
122
  }),
111
123
  manifestPlugin({
112
- manifestPath: resolve(projectRootDir, "dist", "client", ".vite", "manifest.json"),
124
+ projectRootDir,
113
125
  }),
114
126
  moveStaticAssetsPlugin({ rootDir: projectRootDir }),
115
127
  prismaPlugin({ projectRootDir }),
128
+ linkerPlugin({ projectRootDir }),
129
+ directivesFilteringPlugin({
130
+ clientFiles,
131
+ serverFiles,
132
+ projectRootDir,
133
+ }),
116
134
  ];
117
135
  };
@@ -0,0 +1,7 @@
1
+ import { ResolvedConfig } from "vite";
2
+ export declare function runDirectivesScan({ rootConfig, envName, clientFiles, serverFiles, }: {
3
+ rootConfig: ResolvedConfig;
4
+ envName: string;
5
+ clientFiles: Set<string>;
6
+ serverFiles: Set<string>;
7
+ }): Promise<any>;