@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.2 → 3.9.0-ultramodern.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.
Files changed (213) hide show
  1. package/dist/cjs/backend-federation-build/codegen.js +267 -0
  2. package/dist/cjs/backend-federation-build/config.js +239 -0
  3. package/dist/cjs/backend-federation-build/emit.js +154 -0
  4. package/dist/cjs/backend-federation-build/index.js +53 -0
  5. package/dist/cjs/build-config/build-environment.js +129 -0
  6. package/dist/cjs/build-config/precompress/plugin.js +124 -0
  7. package/dist/cjs/build-config/precompress/types.js +18 -0
  8. package/dist/cjs/build-config/public.js +43 -0
  9. package/dist/cjs/build-config/remote-address.js +58 -0
  10. package/dist/cjs/cloudflare/artifacts.js +8 -19
  11. package/dist/cjs/cloudflare/constants.js +1 -1
  12. package/dist/cjs/cloudflare/delivery-unit.js +23 -42
  13. package/dist/cjs/cloudflare/index.js +10 -2
  14. package/dist/cjs/cloudflare/worker-manifest.js +13 -4
  15. package/dist/cjs/cloudflare/wrangler-config.js +35 -7
  16. package/dist/cjs/cloudflare-builder.js +251 -75
  17. package/dist/cjs/cloudflare-output-contract.js +69 -3
  18. package/dist/cjs/cloudflare-output-verifier/identity.js +29 -27
  19. package/dist/cjs/cloudflare-output-verifier/index.js +10 -0
  20. package/dist/cjs/cloudflare-output-verifier/manifest.js +46 -0
  21. package/dist/cjs/cloudflare-output-verifier/mutation-policy.js +7 -1
  22. package/dist/cjs/cloudflare-output-verifier/worker-bundles.js +14 -6
  23. package/dist/cjs/config.js +34 -1
  24. package/dist/cjs/deploy-output/npmAliases.js +251 -0
  25. package/dist/cjs/deploy-output/plugin.js +97 -0
  26. package/dist/cjs/deploy-output/public-assets.js +146 -0
  27. package/dist/cjs/deploy-output/target.js +104 -0
  28. package/dist/cjs/deploy-output/trace-files.js +90 -0
  29. package/dist/cjs/native-type-checker.js +193 -0
  30. package/dist/cjs/policy-defaults.js +101 -0
  31. package/dist/cjs/release-envelope/framework-output.js +153 -79
  32. package/dist/cjs/release-envelope/index.js +10 -4
  33. package/dist/cjs/release-envelope/plugin.js +18 -13
  34. package/dist/cjs/release-identity.js +5 -6
  35. package/dist/cjs/runtime-package-resolution.js +118 -0
  36. package/dist/cjs/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
  37. package/dist/cjs/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
  38. package/dist/cjs/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
  39. package/dist/cjs/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  40. package/dist/cjs/templates/cloudflare-worker-route-data.mjs +1069 -0
  41. package/dist/esm/backend-federation-build/codegen.mjs +216 -0
  42. package/dist/esm/backend-federation-build/config.mjs +163 -0
  43. package/dist/esm/backend-federation-build/emit.mjs +103 -0
  44. package/dist/esm/backend-federation-build/index.mjs +1 -0
  45. package/dist/esm/build-config/build-environment.mjs +88 -0
  46. package/dist/esm/build-config/precompress/plugin.mjs +76 -0
  47. package/dist/esm/build-config/precompress/types.mjs +0 -0
  48. package/dist/esm/build-config/public.mjs +1 -0
  49. package/dist/esm/build-config/remote-address.mjs +20 -0
  50. package/dist/esm/cloudflare/artifacts.mjs +8 -19
  51. package/dist/esm/cloudflare/constants.mjs +1 -1
  52. package/dist/esm/cloudflare/delivery-unit.mjs +17 -36
  53. package/dist/esm/cloudflare/index.mjs +10 -2
  54. package/dist/esm/cloudflare/worker-manifest.mjs +13 -4
  55. package/dist/esm/cloudflare/wrangler-config.mjs +35 -7
  56. package/dist/esm/cloudflare-builder.mjs +245 -75
  57. package/dist/esm/cloudflare-output-contract.mjs +59 -2
  58. package/dist/esm/cloudflare-output-verifier/identity.mjs +27 -25
  59. package/dist/esm/cloudflare-output-verifier/index.mjs +10 -0
  60. package/dist/esm/cloudflare-output-verifier/manifest.mjs +46 -0
  61. package/dist/esm/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  62. package/dist/esm/cloudflare-output-verifier/worker-bundles.mjs +15 -7
  63. package/dist/esm/config.mjs +3 -0
  64. package/dist/esm/deploy-output/npmAliases.mjs +199 -0
  65. package/dist/esm/deploy-output/plugin.mjs +46 -0
  66. package/dist/esm/deploy-output/public-assets.mjs +82 -0
  67. package/dist/esm/deploy-output/target.mjs +57 -0
  68. package/dist/esm/deploy-output/trace-files.mjs +38 -0
  69. package/dist/esm/native-type-checker.mjs +142 -0
  70. package/dist/esm/policy-defaults.mjs +45 -0
  71. package/dist/esm/release-envelope/framework-output.mjs +130 -56
  72. package/dist/esm/release-envelope/index.mjs +10 -4
  73. package/dist/esm/release-envelope/plugin.mjs +18 -13
  74. package/dist/esm/release-identity.mjs +5 -6
  75. package/dist/esm/runtime-package-resolution.mjs +60 -0
  76. package/dist/esm/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
  77. package/dist/esm/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
  78. package/dist/esm/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
  79. package/dist/esm/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  80. package/dist/esm/templates/cloudflare-worker-route-data.mjs +1069 -0
  81. package/dist/esm-node/backend-federation-build/codegen.mjs +217 -0
  82. package/dist/esm-node/backend-federation-build/config.mjs +164 -0
  83. package/dist/esm-node/backend-federation-build/emit.mjs +104 -0
  84. package/dist/esm-node/backend-federation-build/index.mjs +2 -0
  85. package/dist/esm-node/build-config/build-environment.mjs +89 -0
  86. package/dist/esm-node/build-config/precompress/plugin.mjs +77 -0
  87. package/dist/esm-node/build-config/precompress/types.mjs +1 -0
  88. package/dist/esm-node/build-config/public.mjs +2 -0
  89. package/dist/esm-node/build-config/remote-address.mjs +21 -0
  90. package/dist/esm-node/cloudflare/artifacts.mjs +8 -19
  91. package/dist/esm-node/cloudflare/constants.mjs +1 -1
  92. package/dist/esm-node/cloudflare/delivery-unit.mjs +17 -36
  93. package/dist/esm-node/cloudflare/index.mjs +10 -2
  94. package/dist/esm-node/cloudflare/worker-manifest.mjs +13 -4
  95. package/dist/esm-node/cloudflare/wrangler-config.mjs +35 -7
  96. package/dist/esm-node/cloudflare-builder.mjs +245 -75
  97. package/dist/esm-node/cloudflare-output-contract.mjs +59 -2
  98. package/dist/esm-node/cloudflare-output-verifier/identity.mjs +27 -25
  99. package/dist/esm-node/cloudflare-output-verifier/index.mjs +10 -0
  100. package/dist/esm-node/cloudflare-output-verifier/manifest.mjs +46 -0
  101. package/dist/esm-node/cloudflare-output-verifier/mutation-policy.mjs +7 -1
  102. package/dist/esm-node/cloudflare-output-verifier/worker-bundles.mjs +15 -7
  103. package/dist/esm-node/config.mjs +3 -0
  104. package/dist/esm-node/deploy-output/npmAliases.mjs +200 -0
  105. package/dist/esm-node/deploy-output/plugin.mjs +49 -0
  106. package/dist/esm-node/deploy-output/public-assets.mjs +83 -0
  107. package/dist/esm-node/deploy-output/target.mjs +58 -0
  108. package/dist/esm-node/deploy-output/trace-files.mjs +39 -0
  109. package/dist/esm-node/native-type-checker.mjs +143 -0
  110. package/dist/esm-node/policy-defaults.mjs +46 -0
  111. package/dist/esm-node/release-envelope/framework-output.mjs +130 -56
  112. package/dist/esm-node/release-envelope/index.mjs +10 -4
  113. package/dist/esm-node/release-envelope/plugin.mjs +18 -13
  114. package/dist/esm-node/release-identity.mjs +5 -6
  115. package/dist/esm-node/runtime-package-resolution.mjs +61 -0
  116. package/dist/esm-node/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
  117. package/dist/esm-node/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
  118. package/dist/esm-node/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
  119. package/dist/esm-node/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  120. package/dist/esm-node/templates/cloudflare-worker-route-data.mjs +1069 -0
  121. package/dist/types/backend-federation-build/codegen.d.ts +116 -0
  122. package/dist/types/backend-federation-build/config.d.ts +121 -0
  123. package/dist/types/backend-federation-build/emit.d.ts +21 -0
  124. package/dist/types/backend-federation-build/index.d.ts +2 -0
  125. package/dist/types/build-config/build-environment.d.ts +14 -0
  126. package/dist/types/build-config/precompress/plugin.d.ts +4 -0
  127. package/dist/types/build-config/precompress/types.d.ts +19 -0
  128. package/dist/types/build-config/public.d.ts +2 -0
  129. package/dist/types/build-config/remote-address.d.ts +3 -0
  130. package/dist/types/cloudflare/artifacts.d.ts +7 -6
  131. package/dist/types/cloudflare/constants.d.ts +1 -1
  132. package/dist/types/cloudflare/delivery-unit.d.ts +3 -3
  133. package/dist/types/cloudflare/worker-manifest.d.ts +2 -2
  134. package/dist/types/cloudflare/wrangler-config.d.ts +6 -0
  135. package/dist/types/cloudflare-builder.d.ts +49 -9
  136. package/dist/types/cloudflare-output-contract.d.ts +4 -1
  137. package/dist/types/cloudflare-output-verifier/identity.d.ts +1 -1
  138. package/dist/types/cloudflare-output-verifier/worker-bundles.d.ts +2 -2
  139. package/dist/types/config.d.ts +29 -1
  140. package/dist/types/deploy-output/npmAliases.d.ts +14 -0
  141. package/dist/types/deploy-output/plugin.d.ts +35 -0
  142. package/dist/types/deploy-output/public-assets.d.ts +51 -0
  143. package/dist/types/deploy-output/target.d.ts +29 -0
  144. package/dist/types/deploy-output/trace-files.d.ts +17 -0
  145. package/dist/types/native-type-checker.d.ts +15 -0
  146. package/dist/types/policy-defaults.d.ts +46 -0
  147. package/dist/types/precompress/LICENSE +20 -0
  148. package/dist/types/precompress/index.d.ts +76 -0
  149. package/dist/types/release-envelope/framework-output.d.ts +8 -3
  150. package/dist/types/release-envelope/plugin.d.ts +7 -7
  151. package/dist/types/runtime-package-resolution.d.ts +28 -0
  152. package/dist/types/templates/cloudflare-worker-route-data.d.mts +14 -0
  153. package/package.json +97 -15
  154. package/src/backend-federation-build/codegen.ts +254 -0
  155. package/src/backend-federation-build/config.ts +492 -0
  156. package/src/backend-federation-build/emit.ts +213 -0
  157. package/src/backend-federation-build/index.ts +2 -0
  158. package/src/build-config/build-environment.ts +160 -0
  159. package/src/build-config/precompress/plugin.ts +140 -0
  160. package/src/build-config/precompress/types.ts +26 -0
  161. package/src/build-config/public.ts +5 -0
  162. package/src/build-config/remote-address.ts +33 -0
  163. package/src/cloudflare/artifacts.ts +22 -43
  164. package/src/cloudflare/constants.ts +1 -1
  165. package/src/cloudflare/delivery-unit.ts +42 -53
  166. package/src/cloudflare/index.ts +24 -11
  167. package/src/cloudflare/worker-manifest.ts +20 -3
  168. package/src/cloudflare/wrangler-config.ts +86 -10
  169. package/src/cloudflare-builder.ts +472 -151
  170. package/src/cloudflare-output-contract.ts +70 -0
  171. package/src/cloudflare-output-verifier/identity.ts +5 -1
  172. package/src/cloudflare-output-verifier/index.ts +20 -0
  173. package/src/cloudflare-output-verifier/manifest.ts +77 -0
  174. package/src/cloudflare-output-verifier/mutation-policy.ts +11 -1
  175. package/src/cloudflare-output-verifier/worker-bundles.ts +32 -14
  176. package/src/config.ts +34 -6
  177. package/src/deploy-output/npmAliases.ts +382 -0
  178. package/src/deploy-output/plugin.ts +86 -0
  179. package/src/deploy-output/public-assets.ts +224 -0
  180. package/src/deploy-output/target.ts +106 -0
  181. package/src/deploy-output/trace-files.ts +67 -0
  182. package/src/native-type-checker.ts +183 -0
  183. package/src/policy-defaults.ts +127 -0
  184. package/src/release-envelope/framework-output.ts +346 -94
  185. package/src/release-envelope/index.ts +26 -5
  186. package/src/release-envelope/plugin.ts +43 -40
  187. package/src/release-identity.ts +13 -2
  188. package/src/runtime-package-resolution.ts +115 -0
  189. package/src/templates/cloudflare-entry.002-assets-routes.mjs +1 -1
  190. package/src/templates/cloudflare-entry.004-rendering-css.mjs +5 -1
  191. package/src/templates/cloudflare-entry.005-worker-dispatch.mjs +98 -10
  192. package/src/templates/cloudflare-entry.006-fetch-handler.mjs +9 -2
  193. package/src/templates/cloudflare-worker-route-data.mjs +1069 -0
  194. package/dist/cjs/templates/cloudflare-worker-fs-promises.mjs +0 -11
  195. package/dist/cjs/templates/cloudflare-worker-loadable-server.mjs +0 -281
  196. package/dist/cjs/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  197. package/dist/cjs/templates/cloudflare-worker-path.mjs +0 -98
  198. package/dist/esm/templates/cloudflare-worker-fs-promises.mjs +0 -11
  199. package/dist/esm/templates/cloudflare-worker-loadable-server.mjs +0 -281
  200. package/dist/esm/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  201. package/dist/esm/templates/cloudflare-worker-path.mjs +0 -98
  202. package/dist/esm-node/templates/cloudflare-worker-fs-promises.mjs +0 -11
  203. package/dist/esm-node/templates/cloudflare-worker-loadable-server.mjs +0 -281
  204. package/dist/esm-node/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  205. package/dist/esm-node/templates/cloudflare-worker-path.mjs +0 -98
  206. package/dist/types/templates/cloudflare-worker-fs-promises.d.mts +0 -5
  207. package/dist/types/templates/cloudflare-worker-loadable-server.d.mts +0 -48
  208. package/dist/types/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +0 -13
  209. package/dist/types/templates/cloudflare-worker-path.d.mts +0 -21
  210. package/src/templates/cloudflare-worker-fs-promises.mjs +0 -11
  211. package/src/templates/cloudflare-worker-loadable-server.mjs +0 -281
  212. package/src/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  213. package/src/templates/cloudflare-worker-path.mjs +0 -98
@@ -1,26 +1,55 @@
1
1
  import fs from 'node:fs';
2
- import { createRequire } from 'node:module';
2
+ import { createRequire, isBuiltin } from 'node:module';
3
3
  import path from 'node:path';
4
4
  import { SERVICE_WORKER_ENVIRONMENT_NAME } from '@modern-js/builder';
5
5
  import type { BffUserConfig } from '@modern-js/server-core';
6
+ import type {} from '@modern-js/server-runtime-extensions/server-config';
6
7
  import { isProd } from '@modern-js/utils';
7
8
  import type {
8
9
  EnvironmentConfig,
9
10
  ModifyBundlerChainFn,
10
11
  RsbuildEntry,
11
12
  RsbuildEntryDescription,
13
+ Rspack,
12
14
  } from '@rsbuild/core';
13
- import { provider } from 'std-env';
14
- import { CLOUDFLARE_WORKER_NODE_BUILTINS } from './cloudflare-output-contract';
15
+ import {
16
+ CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT,
17
+ CLOUDFLARE_WORKER_NODE_BUILTINS,
18
+ CLOUDFLARE_WORKER_PLATFORM_MODULES,
19
+ getCloudflareWorkerRouteDataEntryName,
20
+ } from './cloudflare-output-contract';
21
+ import type { ResolvedDeployTarget } from './deploy-output/target';
15
22
  import { getTemplatePath } from './read-template';
16
23
 
17
24
  const moduleRequire = createRequire(import.meta.url);
18
25
  const BFF_EFFECT_WORKER_ENTRY_NAME = '__modern_bff_effect';
19
26
  const BFF_EFFECT_WORKER_RUNTIME_QUERY = 'modern-bff-runtime';
20
- const MF_SSR_DATA_FETCH_RUNTIME_PLUGIN =
21
- '@module-federation/modern-js-v3/ssr-inject-data-fetch-function-plugin';
22
- const MF_SSR_DEV_RUNTIME_PLUGIN =
23
- '@module-federation/modern-js-v3/ssr-dev-plugin';
27
+ // Generated by the router code generator for SSR entries with nested route
28
+ // data loaders; the Node server loads this module as its loader bundle. It
29
+ // re-exports the data loader runtime next to the entry's route loaders.
30
+ const SERVER_LOADER_COMBINED_FILE = 'server-loader-combined.js';
31
+ // The entry's route loaders (`routes`), which the loader bundle re-exports.
32
+ const ROUTE_SERVER_LOADERS_FILE = 'route-server-loaders.js';
33
+ const WORKER_ROUTE_DATA_FILE = 'cloudflare-worker-route-data.js';
34
+ const WORKER_ROUTE_DATA_TEMPLATE = 'cloudflare-worker-route-data.mjs';
35
+ // Client builds rewrite `*.data.*` modules into `?__loader=` fetch clients
36
+ // through the data loader plugin's webpack loader. The worker is a server
37
+ // runtime and must execute route loaders in-process. The rule is matched by
38
+ // that loader module, not by the rule name the SSR adapter registers, in both
39
+ // the workspace package and the published `@bleedingdev/modern-js-*` name.
40
+ const DATA_LOADER_CLIENT_TRANSFORM =
41
+ /plugin-data-loader[\\/](?:.+[\\/])?loader\.[cm]?js$/u;
42
+ // Rspack's default dependency-type conditions (`resolve.byDependency`).
43
+ const WORKER_DEPENDENCY_CONDITIONS = [
44
+ ['esm', 'import'],
45
+ ['wasm', 'import'],
46
+ ['loaderImport', 'import'],
47
+ ['worker', 'import'],
48
+ ['commonjs', 'require'],
49
+ ['amd', 'require'],
50
+ ['loader', 'require'],
51
+ ['unknown', 'require'],
52
+ ] as const;
24
53
  const JS_OR_TS_EXTENSIONS = new Set([
25
54
  '.js',
26
55
  '.jsx',
@@ -34,23 +63,23 @@ const JS_OR_TS_EXTENSIONS = new Set([
34
63
 
35
64
  export interface CloudflareBuilderNormalizedConfig {
36
65
  bff?: BffUserConfig;
37
- deploy?: { target?: string };
38
66
  }
39
67
 
40
68
  export interface CloudflareBuilderAppContext {
69
+ apiOnly?: boolean;
70
+ deployTarget?: ResolvedDeployTarget;
41
71
  apiDirectory: string;
42
72
  appDirectory: string;
73
+ entrypoints?: ReadonlyArray<{ entryName: string }>;
74
+ internalDirectory?: string;
43
75
  }
44
76
 
45
77
  export interface CloudflareBuilderEnvironmentsOptions {
46
78
  appContext: CloudflareBuilderAppContext;
47
79
  environments: Record<string, EnvironmentConfig>;
48
80
  normalizedConfig: CloudflareBuilderNormalizedConfig;
49
- resolveDeployProvider?: ResolveCloudflareDeployProvider;
50
81
  }
51
82
 
52
- export type ResolveCloudflareDeployProvider = () => string | undefined;
53
-
54
83
  export interface CloudflareWorkerRspackConfig {
55
84
  externals: Record<string, string>;
56
85
  externalsType: 'module-import';
@@ -189,16 +218,329 @@ const setAliasIfPresent = (
189
218
  }
190
219
  };
191
220
 
221
+ // Node accepts a bare specifier only for built-ins that are not prefix-only
222
+ // (`sqlite` and `test` are ordinary npm package names without `node:`).
192
223
  const getCloudflareWorkerNodeExternals = () =>
193
- Object.fromEntries(
194
- CLOUDFLARE_WORKER_NODE_BUILTINS.flatMap(builtin => {
224
+ Object.fromEntries([
225
+ ...CLOUDFLARE_WORKER_NODE_BUILTINS.flatMap(builtin => {
195
226
  const nodeBuiltin = `node:${builtin}`;
196
- return [
197
- [builtin, `module-import ${nodeBuiltin}`],
198
- [nodeBuiltin, `module-import ${nodeBuiltin}`],
199
- ];
227
+ const external = `module-import ${nodeBuiltin}`;
228
+ return isBuiltin(builtin)
229
+ ? [
230
+ [builtin, external],
231
+ [nodeBuiltin, external],
232
+ ]
233
+ : [[nodeBuiltin, external]];
200
234
  }),
201
- );
235
+ ...CLOUDFLARE_WORKER_PLATFORM_MODULES.map(platformModule => [
236
+ platformModule,
237
+ `module-import ${platformModule}`,
238
+ ]),
239
+ ]);
240
+
241
+ const getPackageNameFromRequest = (request: string) => {
242
+ if (
243
+ request.startsWith('.') ||
244
+ request.startsWith('/') ||
245
+ request.includes(':') ||
246
+ path.isAbsolute(request)
247
+ ) {
248
+ return undefined;
249
+ }
250
+ const segments = request.split('/');
251
+ return request.startsWith('@')
252
+ ? segments.length > 1
253
+ ? `${segments[0]}/${segments[1]}`
254
+ : undefined
255
+ : segments[0];
256
+ };
257
+
258
+ interface OptionalDependencyManifest {
259
+ optionalDependencies?: Record<string, string>;
260
+ peerDependenciesMeta?: Record<string, { optional?: boolean }>;
261
+ [field: string]: unknown;
262
+ }
263
+
264
+ type AliasField = string | readonly string[];
265
+
266
+ // Mirrors the resolver's `resolve.aliasFields` lookup: a field is a key or a
267
+ // nested key path into the importing package's manifest whose object maps
268
+ // exact requests to replacements (or to `false` for an empty module); an
269
+ // entry for a package name does not cover its subpaths.
270
+ const isRedirectedByAliasField = (
271
+ manifest: OptionalDependencyManifest,
272
+ aliasFields: readonly AliasField[],
273
+ request: string,
274
+ ) =>
275
+ aliasFields.some(field => {
276
+ let value: unknown = manifest;
277
+ for (const key of typeof field === 'string' ? [field] : field) {
278
+ value =
279
+ value && typeof value === 'object'
280
+ ? (value as Record<string, unknown>)[key]
281
+ : undefined;
282
+ }
283
+ return (
284
+ typeof value === 'object' &&
285
+ value !== null &&
286
+ Object.hasOwn(value, request)
287
+ );
288
+ });
289
+
290
+ const findOwningPackageManifest = (
291
+ directory: string,
292
+ cache: Map<string, OptionalDependencyManifest | undefined>,
293
+ ): OptionalDependencyManifest | undefined => {
294
+ if (cache.has(directory)) {
295
+ return cache.get(directory);
296
+ }
297
+ let manifest: OptionalDependencyManifest | undefined;
298
+ const packageJsonPath = path.join(directory, 'package.json');
299
+ if (fs.existsSync(packageJsonPath)) {
300
+ try {
301
+ manifest = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
302
+ } catch {
303
+ manifest = undefined;
304
+ }
305
+ } else if (path.dirname(directory) !== directory) {
306
+ manifest = findOwningPackageManifest(path.dirname(directory), cache);
307
+ }
308
+ cache.set(directory, manifest);
309
+ return manifest;
310
+ };
311
+
312
+ // Mirrors the resolver's `resolve.modules` lookup: absolute entries are
313
+ // searched directly, named entries in the context directory and each ancestor.
314
+ const isPackageInstalled = (
315
+ packageName: string,
316
+ directory: string,
317
+ moduleDirectories: readonly string[],
318
+ ) =>
319
+ moduleDirectories.some(moduleDirectory => {
320
+ if (path.isAbsolute(moduleDirectory)) {
321
+ return fs.existsSync(path.join(moduleDirectory, packageName));
322
+ }
323
+ let current = directory;
324
+ while (true) {
325
+ if (fs.existsSync(path.join(current, moduleDirectory, packageName))) {
326
+ return true;
327
+ }
328
+ const parent = path.dirname(current);
329
+ if (parent === current) {
330
+ return false;
331
+ }
332
+ current = parent;
333
+ }
334
+ });
335
+
336
+ /**
337
+ * Leaves an absent optional dependency missing at runtime, exactly as Node
338
+ * does, instead of failing the worker build. It applies only when the
339
+ * importing package itself declares the request as an optional peer
340
+ * (`peerDependenciesMeta.<name>.optional`) or an `optionalDependencies`
341
+ * entry, the package is not found in any `resolve.modules` directory, and
342
+ * neither the app (`resolve.alias`, `resolve.fallback`, `externals`) nor the
343
+ * importing package (an enabled `resolve.aliasFields` entry such as
344
+ * `browser`) redirects the request. The import
345
+ * then rejects with "Cannot find module" so the library's own fallback
346
+ * handles it (for example `@redis/client` guards `import('@node-rs/xxhash')`).
347
+ */
348
+ export const createAbsentOptionalDependencyFilter = (
349
+ isRedirected: (request: string) => boolean = () => false,
350
+ moduleDirectories: readonly string[] = ['node_modules'],
351
+ aliasFields: readonly AliasField[] = [],
352
+ ) => {
353
+ const manifests = new Map<string, OptionalDependencyManifest | undefined>();
354
+ return (request: string, context: string) => {
355
+ const packageName = getPackageNameFromRequest(request);
356
+ if (!packageName || !context || isRedirected(request)) {
357
+ return false;
358
+ }
359
+ const manifest = findOwningPackageManifest(context, manifests);
360
+ if (!manifest) {
361
+ return false;
362
+ }
363
+ const optional =
364
+ manifest.peerDependenciesMeta?.[packageName]?.optional === true ||
365
+ Object.hasOwn(manifest.optionalDependencies ?? {}, packageName);
366
+ return (
367
+ optional &&
368
+ !isRedirectedByAliasField(manifest, aliasFields, request) &&
369
+ !isPackageInstalled(packageName, context, moduleDirectories)
370
+ );
371
+ };
372
+ };
373
+
374
+ type AliasOption =
375
+ | Record<string, unknown>
376
+ | { name: string; onlyModule?: boolean }[]
377
+ | false
378
+ | undefined;
379
+
380
+ const getAliasNames = (alias: AliasOption) =>
381
+ !alias
382
+ ? []
383
+ : Array.isArray(alias)
384
+ ? alias.map(entry => (entry.onlyModule ? `${entry.name}$` : entry.name))
385
+ : Object.keys(alias);
386
+
387
+ type ExternalMatcher = (request: string) => boolean;
388
+
389
+ // String, RegExp and object-key externals are matched synchronously; function
390
+ // externals are consulted per request by `claimsByFunctionExternal`.
391
+ // An object entry mapped to `false` keeps the request bundled, so it is not
392
+ // a redirect.
393
+ const getExternalMatchers = (externals: unknown): ExternalMatcher[] => {
394
+ if (Array.isArray(externals)) {
395
+ return externals.flatMap(getExternalMatchers);
396
+ }
397
+ if (typeof externals === 'string') {
398
+ return [request => request === externals];
399
+ }
400
+ if (externals instanceof RegExp) {
401
+ return [
402
+ request => {
403
+ externals.lastIndex = 0;
404
+ return externals.test(request);
405
+ },
406
+ ];
407
+ }
408
+ if (externals && typeof externals === 'object') {
409
+ const names = new Set(
410
+ Object.entries(externals)
411
+ .filter(([, value]) => value !== false)
412
+ .map(([name]) => name),
413
+ );
414
+ return [request => names.has(request)];
415
+ }
416
+ return [];
417
+ };
418
+
419
+ /**
420
+ * Reads the final resolved `resolve.alias`, `resolve.fallback` and
421
+ * `externals` so an app's own
422
+ * replacement for an optional package still wins over the absent-module
423
+ * fallback (the fallback runs before resolution).
424
+ */
425
+ export const createRequestRedirectMatcher = (options: {
426
+ externals?: unknown;
427
+ resolve?: { alias?: AliasOption; fallback?: AliasOption };
428
+ }) => {
429
+ const aliasNames = [
430
+ ...getAliasNames(options.resolve?.alias),
431
+ ...getAliasNames(options.resolve?.fallback),
432
+ ];
433
+ const externalMatchers = getExternalMatchers(options.externals);
434
+ return (request: string) =>
435
+ externalMatchers.some(matches => matches(request)) ||
436
+ aliasNames.some(name =>
437
+ name.endsWith('$')
438
+ ? request === name.slice(0, -1)
439
+ : request === name || request.startsWith(`${name}/`),
440
+ );
441
+ };
442
+
443
+ type FunctionExternal = (
444
+ data: Rspack.ExternalItemFunctionData,
445
+ callback: (error?: Error | null, result?: unknown) => void,
446
+ ) => unknown;
447
+
448
+ const getFunctionExternals = (externals: unknown): FunctionExternal[] =>
449
+ Array.isArray(externals)
450
+ ? externals.flatMap(getFunctionExternals)
451
+ : typeof externals === 'function'
452
+ ? [externals as FunctionExternal]
453
+ : [];
454
+
455
+ // Calls a function external with the same callback, promise and synchronous
456
+ // return forms Rspack accepts. `undefined`, `null` and `false` decline.
457
+ const callFunctionExternal = (
458
+ external: FunctionExternal,
459
+ data: Rspack.ExternalItemFunctionData,
460
+ ) =>
461
+ new Promise<unknown>((resolve, reject) => {
462
+ const returned = external(data, (error, result) =>
463
+ error ? reject(error) : resolve(result),
464
+ );
465
+ if (
466
+ returned !== null &&
467
+ typeof returned === 'object' &&
468
+ typeof (returned as PromiseLike<unknown>).then === 'function'
469
+ ) {
470
+ (returned as PromiseLike<unknown>).then(resolve, reject);
471
+ } else if (external.length === 1) {
472
+ resolve(returned);
473
+ }
474
+ });
475
+
476
+ /**
477
+ * Reports whether any function external claims the request. A function that
478
+ * throws is treated as claiming it, so the request goes through ordinary
479
+ * external processing and surfaces that error instead of being ignored.
480
+ */
481
+ export const claimsByFunctionExternal = async (
482
+ externals: readonly FunctionExternal[],
483
+ data: Rspack.ExternalItemFunctionData,
484
+ ) => {
485
+ for (const external of externals) {
486
+ try {
487
+ const result = await callFunctionExternal(external, data);
488
+ if (result !== undefined && result !== null && result !== false) {
489
+ return true;
490
+ }
491
+ } catch {
492
+ return true;
493
+ }
494
+ }
495
+ return false;
496
+ };
497
+
498
+ const PLUGIN_NAME = 'AbsentOptionalDependencyPlugin';
499
+
500
+ class AbsentOptionalDependencyPlugin {
501
+ apply(compiler: Rspack.Compiler) {
502
+ const isAbsent = createAbsentOptionalDependencyFilter(
503
+ createRequestRedirectMatcher(compiler.options),
504
+ compiler.options.resolve.modules,
505
+ compiler.options.resolve.aliasFields,
506
+ );
507
+ const functionExternals = getFunctionExternals(compiler.options.externals);
508
+ compiler.hooks.normalModuleFactory.tap(PLUGIN_NAME, factory => {
509
+ factory.hooks.beforeResolve.tapPromise(PLUGIN_NAME, async data => {
510
+ if (!isAbsent(data.request, data.context)) {
511
+ return undefined;
512
+ }
513
+ const claimed = await claimsByFunctionExternal(functionExternals, {
514
+ context: data.context,
515
+ contextInfo: {
516
+ issuer: data.contextInfo.issuer,
517
+ issuerLayer: data.contextInfo.issuerLayer ?? null,
518
+ },
519
+ getResolve: options => {
520
+ const resolver = factory.getResolver('normal', options ?? {});
521
+ return (
522
+ context: string,
523
+ request: string,
524
+ callback?: Parameters<typeof resolver.resolve>[4],
525
+ ) => {
526
+ if (callback) {
527
+ resolver.resolve({}, context, request, {}, callback);
528
+ return undefined;
529
+ }
530
+ return new Promise<string | undefined>((resolve, reject) => {
531
+ resolver.resolve({}, context, request, {}, (error, result) =>
532
+ error ? reject(error) : resolve(result || undefined),
533
+ );
534
+ });
535
+ };
536
+ },
537
+ request: data.request,
538
+ });
539
+ return claimed ? undefined : false;
540
+ });
541
+ });
542
+ }
543
+ }
202
544
 
203
545
  const normalizeWorkerOutputName = (name: string) =>
204
546
  path.posix.normalize(name.replace(/\\/gu, '/')).toLowerCase();
@@ -281,18 +623,28 @@ export function applyCloudflareWorkerRspackConfig(
281
623
  chain.optimization.splitChunks(config.optimization.splitChunks);
282
624
  }
283
625
 
284
- export function applyCloudflareWorkerMfRuntimeBoundary(
626
+ /**
627
+ * The worker environment uses Rspack's web target for ESM output, which the
628
+ * data loader transform treats as a browser bundle. Remove every module rule
629
+ * that applies it, so SSR runs route loaders in-process as the Node server
630
+ * does instead of fetching the worker's own `?__loader=` URL.
631
+ */
632
+ function removeCloudflareWorkerDataLoaderClientTransform(
285
633
  chain: Parameters<ModifyBundlerChainFn>[0],
286
634
  ) {
287
- const runtimePlugin = getTemplatePath(
288
- 'cloudflare-worker-mf-ssr-runtime-plugin.mjs',
289
- );
290
- chain.plugins.delete('plugin-module-federation');
291
- chain.resolve.alias.set(
292
- `${MF_SSR_DATA_FETCH_RUNTIME_PLUGIN}$`,
293
- runtimePlugin,
294
- );
295
- chain.resolve.alias.set(`${MF_SSR_DEV_RUNTIME_PLUGIN}$`, runtimePlugin);
635
+ for (const [name, rule] of Object.entries(
636
+ chain.module.rules.entries() ?? {},
637
+ )) {
638
+ if (
639
+ rule.uses
640
+ .values()
641
+ .some(use =>
642
+ DATA_LOADER_CLIENT_TRANSFORM.test(String(use.get('loader'))),
643
+ )
644
+ ) {
645
+ chain.module.rules.delete(name);
646
+ }
647
+ }
296
648
  }
297
649
 
298
650
  const getEffectBffEntry = (
@@ -317,31 +669,6 @@ const getEffectBffEntry = (
317
669
  return resolveJsOrTsEntry(path.resolve(appContext.apiDirectory, 'index'));
318
670
  };
319
671
 
320
- const CLOUDFLARE_DEPLOY_PROVIDERS = new Set([
321
- 'cloudflare',
322
- 'cloudflare_pages',
323
- 'cloudflare_workers',
324
- ]);
325
-
326
- const resolveStdEnvDeployProvider: ResolveCloudflareDeployProvider = () =>
327
- provider;
328
-
329
- const isCloudflareWorkerDeploy = (
330
- normalizedConfig: CloudflareBuilderNormalizedConfig,
331
- resolveDeployProvider: ResolveCloudflareDeployProvider,
332
- ) => {
333
- const explicitTarget =
334
- normalizedConfig.deploy?.target || process.env.MODERNJS_DEPLOY;
335
- if (explicitTarget) {
336
- return explicitTarget === 'cloudflare';
337
- }
338
-
339
- const detectedProvider = resolveDeployProvider();
340
- return detectedProvider
341
- ? CLOUDFLARE_DEPLOY_PROVIDERS.has(detectedProvider)
342
- : false;
343
- };
344
-
345
672
  const rewriteWorkerEntryPath = (entry: string) =>
346
673
  entry
347
674
  .replace('index.jsx', 'index.server.jsx')
@@ -396,18 +723,72 @@ const prependBundlerChain = (
396
723
  };
397
724
  };
398
725
 
726
+ const createWorkerRouteDataModule = () =>
727
+ [
728
+ `import { routes } from './${ROUTE_SERVER_LOADERS_FILE}';`,
729
+ `import { createRouteDataRequestHandler } from ${JSON.stringify(
730
+ getTemplatePath(WORKER_ROUTE_DATA_TEMPLATE),
731
+ )};`,
732
+ '',
733
+ `export const ${CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT} =`,
734
+ ' createRouteDataRequestHandler(routes);',
735
+ '',
736
+ ].join('\n');
737
+
738
+ /**
739
+ * Route data requests reach the worker whenever the browser navigates to a
740
+ * route with a data loader. Bundle the route loaders of each entry that has a
741
+ * Node server loader bundle behind the worker route data handler, so the
742
+ * worker answers them instead of rendering the page. The worker imports the
743
+ * route loaders without the loader bundle's data loader runtime, which is
744
+ * built on react-router.
745
+ */
746
+ const getWorkerRouteDataEntries = (
747
+ appContext: CloudflareBuilderAppContext,
748
+ ): Record<string, string[]> => {
749
+ const { entrypoints, internalDirectory } = appContext;
750
+ if (!entrypoints || !internalDirectory) {
751
+ return {};
752
+ }
753
+
754
+ return Object.fromEntries(
755
+ entrypoints.flatMap(({ entryName }) => {
756
+ const entryDirectory = path.join(internalDirectory, entryName);
757
+ if (
758
+ !fs.existsSync(
759
+ path.join(entryDirectory, SERVER_LOADER_COMBINED_FILE),
760
+ ) ||
761
+ !fs.existsSync(path.join(entryDirectory, ROUTE_SERVER_LOADERS_FILE))
762
+ ) {
763
+ return [];
764
+ }
765
+
766
+ const routeDataFile = path.join(entryDirectory, WORKER_ROUTE_DATA_FILE);
767
+ fs.writeFileSync(routeDataFile, createWorkerRouteDataModule());
768
+ return [
769
+ [getCloudflareWorkerRouteDataEntryName(entryName), [routeDataFile]],
770
+ ];
771
+ }),
772
+ );
773
+ };
774
+
399
775
  const getWorkerEntries = (
400
776
  environment: EnvironmentConfig,
401
777
  normalizedConfig: CloudflareBuilderNormalizedConfig,
402
778
  appContext: CloudflareBuilderAppContext,
403
779
  ) => {
404
780
  const configuredEntries = environment.source?.entry;
405
- if (!configuredEntries) {
781
+ const effectApiEntry = getEffectBffEntry(normalizedConfig, appContext);
782
+ if (!configuredEntries && !effectApiEntry) {
406
783
  return undefined;
407
784
  }
408
785
 
409
- const entries = rewriteWorkerEntries(configuredEntries);
410
- const effectApiEntry = getEffectBffEntry(normalizedConfig, appContext);
786
+ const entries = configuredEntries
787
+ ? {
788
+ ...rewriteWorkerEntries(configuredEntries),
789
+ ...getWorkerRouteDataEntries(appContext),
790
+ }
791
+ : {};
411
792
  return effectApiEntry
412
793
  ? {
413
794
  ...entries,
@@ -423,21 +804,6 @@ const createCloudflareBundlerChain = (
423
804
  workerEntryNames: Iterable<string>,
424
805
  ): ModifyBundlerChainFn => {
425
806
  const resolvePaths = [appContext.appDirectory, process.cwd()];
426
- const tanstackRouterSsrServerFile = resolvePackageFile(
427
- '@tanstack/router-core',
428
- 'dist/esm/ssr/ssr-server.js',
429
- resolvePaths,
430
- );
431
- const runtimeRscWorkerFile = resolvePackageFile(
432
- '@modern-js/runtime',
433
- 'dist/esm/rsc/server.worker.mjs',
434
- resolvePaths,
435
- );
436
- const renderRscWorkerFile = resolvePackageFile(
437
- '@modern-js/render',
438
- 'dist/esm/rscWorker.mjs',
439
- resolvePaths,
440
- );
441
807
  const reactFile = resolvePackageFile('react', 'index.js', resolvePaths);
442
808
  const reactJsxRuntimeFile = resolvePackageFile(
443
809
  'react',
@@ -464,17 +830,11 @@ const createCloudflareBundlerChain = (
464
830
  'dist/esm/loadable.esm.mjs',
465
831
  [...resolvePaths, getTemplatePath('')],
466
832
  );
467
- const loadableServerWorkerFile = getTemplatePath(
468
- 'cloudflare-worker-loadable-server.mjs',
469
- );
470
- const fsPromisesWorkerFile = getTemplatePath(
471
- 'cloudflare-worker-fs-promises.mjs',
472
- );
473
- const pathWorkerFile = getTemplatePath('cloudflare-worker-path.mjs');
474
833
  const entryNames = [...workerEntryNames];
475
834
 
476
835
  return chain => {
477
836
  applyCloudflareWorkerRspackConfig(chain, entryNames);
837
+ removeCloudflareWorkerDataLoaderClientTransform(chain);
478
838
  chain.output
479
839
  .module(true)
480
840
  .library({ type: 'module' })
@@ -488,42 +848,31 @@ const createCloudflareBundlerChain = (
488
848
  'worker',
489
849
  'webpack',
490
850
  isProd() ? 'production' : 'development',
491
- 'import',
492
- 'require',
493
851
  'module',
494
852
  ]) {
495
853
  chain.resolve.conditionNames.add(condition);
496
854
  }
497
-
498
- applyCloudflareWorkerMfRuntimeBoundary(chain);
499
- if (tanstackRouterSsrServerFile) {
500
- chain.resolve.alias.set(
501
- '@tanstack/router-core/ssr/server$',
502
- tanstackRouterSsrServerFile,
503
- );
504
- chain.resolve.alias.set(
505
- '@tanstack/router-core/ssr/server',
506
- tanstackRouterSsrServerFile,
507
- );
508
- }
509
- if (runtimeRscWorkerFile) {
510
- chain.resolve.alias.set(
511
- '@modern-js/runtime/rsc/server$',
512
- runtimeRscWorkerFile,
513
- );
514
- chain.resolve.alias.set(
515
- '@modern-js/runtime/rsc/server',
516
- runtimeRscWorkerFile,
517
- );
518
- }
519
- if (renderRscWorkerFile) {
520
- chain.resolve.alias.set('@modern-js/render/rsc$', renderRscWorkerFile);
521
- chain.resolve.alias.set('@modern-js/render/rsc', renderRscWorkerFile);
522
- chain.resolve.alias.set(
523
- '@modern-js/render/rsc-worker$',
524
- renderRscWorkerFile,
525
- );
855
+ // Setting base conditions drops Rspack's per-dependency `import` /
856
+ // `require` defaults, and adding both globally lets a dual package's
857
+ // first-listed `import` branch win for `require()` (so `pg` received an
858
+ // ES module namespace for `pg-pool` and missed `pg-cloudflare`'s
859
+ // `workerd.require` entry). Restore Rspack's own per-dependency split.
860
+ for (const [dependencyType, condition] of WORKER_DEPENDENCY_CONDITIONS) {
861
+ chain.resolve.byDependency.set(dependencyType, {
862
+ conditionNames: [condition, '...'],
863
+ });
526
864
  }
865
+ chain
866
+ .plugin('cloudflare-worker-absent-optional-dependencies')
867
+ .use(AbsentOptionalDependencyPlugin);
868
+
869
+ // The worker environment still uses the web target, so
870
+ // @module-federation/modern-js-v3 registers its browser federation plugin
871
+ // on it; Cloudflare workers load no native remotes. The `worker` export
872
+ // condition keeps MF's SSR runtime plugins out of the bundle
873
+ // (module-federation/core#5155). This deletion goes with the web-worker
874
+ // target, which needs @rsbuild/core 2.2.10 (web-infra-dev/rsbuild#8557).
875
+ chain.plugins.delete('plugin-module-federation');
527
876
  setAliasIfPresent(chain.resolve.alias, 'react$', reactFile);
528
877
  setAliasIfPresent(
529
878
  chain.resolve.alias,
@@ -546,41 +895,6 @@ const createCloudflareBundlerChain = (
546
895
  '@loadable/component$',
547
896
  loadableComponentFile,
548
897
  );
549
- setAliasIfPresent(
550
- chain.resolve.alias,
551
- '@loadable/server$',
552
- loadableServerWorkerFile,
553
- );
554
- setAliasIfPresent(
555
- chain.resolve.alias,
556
- 'fs/promises$',
557
- fsPromisesWorkerFile,
558
- );
559
- setAliasIfPresent(
560
- chain.resolve.alias,
561
- 'node:fs/promises$',
562
- fsPromisesWorkerFile,
563
- );
564
- setAliasIfPresent(chain.resolve.alias, 'path$', pathWorkerFile);
565
- setAliasIfPresent(chain.resolve.alias, 'node:path$', pathWorkerFile);
566
- chain.resolve.alias.set(
567
- 'react-server-dom-rspack/server.node$',
568
- 'react-server-dom-rspack/server.edge',
569
- );
570
- chain.resolve.alias.set(
571
- 'react-server-dom-rspack/server.node',
572
- 'react-server-dom-rspack/server.edge',
573
- );
574
- chain.resolve.alias.set(
575
- 'react-server-dom-rspack/client.node$',
576
- 'react-server-dom-rspack/client.edge',
577
- );
578
- chain.resolve.alias.set(
579
- 'react-server-dom-rspack/client.node',
580
- 'react-server-dom-rspack/client.edge',
581
- );
582
- chain.resolve.fallback.set('fs', false);
583
- chain.resolve.fallback.set('node:fs', false);
584
898
  };
585
899
  };
586
900
 
@@ -588,13 +902,19 @@ export function getCloudflareBuilderEnvironments({
588
902
  appContext,
589
903
  environments,
590
904
  normalizedConfig,
591
- resolveDeployProvider = resolveStdEnvDeployProvider,
592
905
  }: CloudflareBuilderEnvironmentsOptions): Record<string, EnvironmentConfig> {
593
- if (!isCloudflareWorkerDeploy(normalizedConfig, resolveDeployProvider)) {
906
+ if (appContext.deployTarget?.target !== 'cloudflare') {
594
907
  return environments;
595
908
  }
596
909
 
597
- const workerEnvironment = environments[SERVICE_WORKER_ENVIRONMENT_NAME];
910
+ const workerEnvironment =
911
+ environments[SERVICE_WORKER_ENVIRONMENT_NAME] ??
912
+ (appContext.apiOnly
913
+ ? {
914
+ output: { target: 'web-worker' as const },
915
+ source: { entry: {} },
916
+ }
917
+ : undefined);
598
918
  if (!workerEnvironment) {
599
919
  return environments;
600
920
  }
@@ -624,6 +944,10 @@ export function getCloudflareBuilderEnvironments({
624
944
  createCloudflareBundlerChain(appContext, Object.keys(workerEntries)),
625
945
  );
626
946
 
947
+ if (appContext.apiOnly) {
948
+ return { [SERVICE_WORKER_ENVIRONMENT_NAME]: cloudflareWorkerEnvironment };
949
+ }
950
+
627
951
  return {
628
952
  ...environments,
629
953
  [SERVICE_WORKER_ENVIRONMENT_NAME]: cloudflareWorkerEnvironment,
@@ -636,9 +960,7 @@ export function applyCloudflareBuilderEnvironments(
636
960
  return { environments: getCloudflareBuilderEnvironments(options) };
637
961
  }
638
962
 
639
- export const createCloudflareBuilderPlugin = (
640
- resolveDeployProvider = resolveStdEnvDeployProvider,
641
- ): CloudflareBuilderPlugin => ({
963
+ export const createCloudflareBuilderPlugin = (): CloudflareBuilderPlugin => ({
642
964
  name: '@modern-js/cloudflare-builder',
643
965
  setup(api) {
644
966
  api.modifyBuilderEnvironments(({ environments }) =>
@@ -646,7 +968,6 @@ export const createCloudflareBuilderPlugin = (
646
968
  appContext: api.getAppContext(),
647
969
  environments,
648
970
  normalizedConfig: api.getNormalizedConfig(),
649
- resolveDeployProvider,
650
971
  }),
651
972
  );
652
973
  },