@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.19 → 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 (35) hide show
  1. package/dist/cjs/build-config/remote-address.js +12 -10
  2. package/dist/cjs/cloudflare-builder.js +5 -30
  3. package/dist/cjs/config.js +4 -0
  4. package/dist/cjs/deploy-output/plugin.js +8 -7
  5. package/dist/cjs/deploy-output/target.js +57 -1
  6. package/dist/cjs/release-envelope/plugin.js +5 -10
  7. package/dist/esm/build-config/remote-address.mjs +12 -10
  8. package/dist/esm/cloudflare-builder.mjs +6 -28
  9. package/dist/esm/config.mjs +1 -0
  10. package/dist/esm/deploy-output/plugin.mjs +9 -8
  11. package/dist/esm/deploy-output/target.mjs +50 -3
  12. package/dist/esm/release-envelope/plugin.mjs +5 -10
  13. package/dist/esm-node/build-config/remote-address.mjs +12 -10
  14. package/dist/esm-node/cloudflare-builder.mjs +6 -28
  15. package/dist/esm-node/config.mjs +1 -0
  16. package/dist/esm-node/deploy-output/plugin.mjs +9 -8
  17. package/dist/esm-node/deploy-output/target.mjs +50 -3
  18. package/dist/esm-node/release-envelope/plugin.mjs +5 -10
  19. package/dist/types/cloudflare-builder.d.ts +4 -8
  20. package/dist/types/config.d.ts +2 -1
  21. package/dist/types/deploy-output/plugin.d.ts +12 -18
  22. package/dist/types/deploy-output/target.d.ts +28 -5
  23. package/dist/types/release-envelope/plugin.d.ts +3 -7
  24. package/package.json +17 -16
  25. package/src/build-config/remote-address.ts +11 -9
  26. package/src/cloudflare-builder.ts +11 -55
  27. package/src/config.ts +2 -7
  28. package/src/deploy-output/plugin.ts +20 -37
  29. package/src/deploy-output/target.ts +97 -14
  30. package/src/release-envelope/plugin.ts +10 -40
  31. package/dist/cjs/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  32. package/dist/esm/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  33. package/dist/esm-node/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
  34. package/dist/types/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +0 -13
  35. package/src/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +0 -14
@@ -4,7 +4,6 @@ import { createRequire, isBuiltin } from "node:module";
4
4
  import node_path from "node:path";
5
5
  import { SERVICE_WORKER_ENVIRONMENT_NAME } from "@modern-js/builder";
6
6
  import { isProd } from "@modern-js/utils";
7
- import { provider } from "std-env";
8
7
  import { CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT, CLOUDFLARE_WORKER_NODE_BUILTINS, CLOUDFLARE_WORKER_PLATFORM_MODULES, getCloudflareWorkerRouteDataEntryName } from "./cloudflare-output-contract.mjs";
9
8
  import { getTemplatePath } from "./read-template.mjs";
10
9
  const moduleRequire = createRequire(import.meta.url);
@@ -15,8 +14,6 @@ const ROUTE_SERVER_LOADERS_FILE = 'route-server-loaders.js';
15
14
  const WORKER_ROUTE_DATA_FILE = 'cloudflare-worker-route-data.js';
16
15
  const WORKER_ROUTE_DATA_TEMPLATE = 'cloudflare-worker-route-data.mjs';
17
16
  const DATA_LOADER_CLIENT_TRANSFORM = /plugin-data-loader[\\/](?:.+[\\/])?loader\.[cm]?js$/u;
18
- const MF_SSR_DATA_FETCH_RUNTIME_PLUGIN = '@module-federation/modern-js-v3/ssr-inject-data-fetch-function-plugin';
19
- const MF_SSR_DEV_RUNTIME_PLUGIN = '@module-federation/modern-js-v3/ssr-dev-plugin';
20
17
  const WORKER_DEPENDENCY_CONDITIONS = [
21
18
  [
22
19
  'esm',
@@ -310,12 +307,6 @@ function applyCloudflareWorkerRspackConfig(chain, workerEntryNames) {
310
307
  function removeCloudflareWorkerDataLoaderClientTransform(chain) {
311
308
  for (const [name, rule] of Object.entries(chain.module.rules.entries() ?? {}))if (rule.uses.values().some((use)=>DATA_LOADER_CLIENT_TRANSFORM.test(String(use.get('loader'))))) chain.module.rules.delete(name);
312
309
  }
313
- function applyCloudflareWorkerMfRuntimeBoundary(chain) {
314
- const runtimePlugin = getTemplatePath('cloudflare-worker-mf-ssr-runtime-plugin.mjs');
315
- chain.plugins.delete('plugin-module-federation');
316
- chain.resolve.alias.set(`${MF_SSR_DATA_FETCH_RUNTIME_PLUGIN}$`, runtimePlugin);
317
- chain.resolve.alias.set(`${MF_SSR_DEV_RUNTIME_PLUGIN}$`, runtimePlugin);
318
- }
319
310
  const getEffectBffEntry = (normalizedConfig, appContext)=>{
320
311
  if (!normalizedConfig.bff || 'hono' === normalizedConfig.bff.runtimeFramework) return;
321
312
  const configuredEntry = normalizedConfig.bff.effect?.entry;
@@ -325,18 +316,6 @@ const getEffectBffEntry = (normalizedConfig, appContext)=>{
325
316
  }
326
317
  return resolveJsOrTsEntry(node_path.resolve(appContext.apiDirectory, 'index'));
327
318
  };
328
- const CLOUDFLARE_DEPLOY_PROVIDERS = new Set([
329
- 'cloudflare',
330
- 'cloudflare_pages',
331
- 'cloudflare_workers'
332
- ]);
333
- const resolveStdEnvDeployProvider = ()=>provider;
334
- const isCloudflareWorkerDeploy = (normalizedConfig, resolveDeployProvider)=>{
335
- const explicitTarget = normalizedConfig.deploy?.target || process.env.MODERNJS_DEPLOY;
336
- if (explicitTarget) return 'cloudflare' === explicitTarget;
337
- const detectedProvider = resolveDeployProvider();
338
- return detectedProvider ? CLOUDFLARE_DEPLOY_PROVIDERS.has(detectedProvider) : false;
339
- };
340
319
  const rewriteWorkerEntryPath = (entry)=>entry.replace('index.jsx', 'index.server.jsx').replace('bootstrap.server.jsx', 'index.server.jsx').replace('bootstrap.jsx', 'index.server.jsx');
341
320
  const rewriteWorkerEntryDescription = (description)=>{
342
321
  const entryImport = description.import;
@@ -459,7 +438,7 @@ const createCloudflareBundlerChain = (appContext, workerEntryNames)=>{
459
438
  ]
460
439
  });
461
440
  chain.plugin('cloudflare-worker-absent-optional-dependencies').use(AbsentOptionalDependencyPlugin);
462
- applyCloudflareWorkerMfRuntimeBoundary(chain);
441
+ chain.plugins.delete('plugin-module-federation');
463
442
  setAliasIfPresent(chain.resolve.alias, 'react$', reactFile);
464
443
  setAliasIfPresent(chain.resolve.alias, 'react/jsx-runtime$', reactJsxRuntimeFile);
465
444
  setAliasIfPresent(chain.resolve.alias, 'react/jsx-dev-runtime$', reactJsxDevRuntimeFile);
@@ -468,8 +447,8 @@ const createCloudflareBundlerChain = (appContext, workerEntryNames)=>{
468
447
  setAliasIfPresent(chain.resolve.alias, '@loadable/component$', loadableComponentFile);
469
448
  };
470
449
  };
471
- function getCloudflareBuilderEnvironments({ appContext, environments, normalizedConfig, resolveDeployProvider = resolveStdEnvDeployProvider }) {
472
- if (!isCloudflareWorkerDeploy(normalizedConfig, resolveDeployProvider)) return environments;
450
+ function getCloudflareBuilderEnvironments({ appContext, environments, normalizedConfig }) {
451
+ if (appContext.deployTarget?.target !== 'cloudflare') return environments;
473
452
  const workerEnvironment = environments[SERVICE_WORKER_ENVIRONMENT_NAME] ?? (appContext.apiOnly ? {
474
453
  output: {
475
454
  target: 'web-worker'
@@ -506,15 +485,14 @@ function applyCloudflareBuilderEnvironments(options) {
506
485
  environments: getCloudflareBuilderEnvironments(options)
507
486
  };
508
487
  }
509
- const createCloudflareBuilderPlugin = (resolveDeployProvider = resolveStdEnvDeployProvider)=>({
488
+ const createCloudflareBuilderPlugin = ()=>({
510
489
  name: '@modern-js/cloudflare-builder',
511
490
  setup (api) {
512
491
  api.modifyBuilderEnvironments(({ environments })=>applyCloudflareBuilderEnvironments({
513
492
  appContext: api.getAppContext(),
514
493
  environments,
515
- normalizedConfig: api.getNormalizedConfig(),
516
- resolveDeployProvider
494
+ normalizedConfig: api.getNormalizedConfig()
517
495
  }));
518
496
  }
519
497
  });
520
- export { applyCloudflareBuilderEnvironments, applyCloudflareWorkerMfRuntimeBoundary, applyCloudflareWorkerRspackConfig, claimsByFunctionExternal, createAbsentOptionalDependencyFilter, createCloudflareBuilderPlugin, createRequestRedirectMatcher, getCloudflareBuilderEnvironments, getCloudflareWorkerRspackConfig };
498
+ export { applyCloudflareBuilderEnvironments, applyCloudflareWorkerRspackConfig, claimsByFunctionExternal, createAbsentOptionalDependencyFilter, createCloudflareBuilderPlugin, createRequestRedirectMatcher, getCloudflareBuilderEnvironments, getCloudflareWorkerRspackConfig };
@@ -1,3 +1,4 @@
1
1
  import "node:module";
2
2
  export { getBuildConfigEnvironment, resolveEffectTsgoCompiler } from "./build-config/public.mjs";
3
3
  export { createRemoteManifestUrl } from "./build-config/remote-address.mjs";
4
+ export { resolveDeployTarget } from "./deploy-output/target.mjs";
@@ -3,16 +3,16 @@ import { createRequire } from "node:module";
3
3
  import node_path from "node:path";
4
4
  import { preserveNpmAliases, readPackageIdentity } from "./npmAliases.mjs";
5
5
  import { NODE_PUBLIC_ASSET_SCOPE, normalizeDeclaredPublicAssets, stageDeclaredPublicAssets } from "./public-assets.mjs";
6
- import { resolveDeployTarget as external_target_mjs_resolveDeployTarget } from "./target.mjs";
6
+ import { getDeployingTarget } from "./target.mjs";
7
7
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
8
8
  var __rspack_import_meta_filename__ = __rspack_fileURLToPath(import.meta.url);
9
- const createDeployOutputAliasesPlugin = ({ resolveDeployTarget = external_target_mjs_resolveDeployTarget } = {})=>({
9
+ const createDeployOutputAliasesPlugin = ()=>({
10
10
  name: '@modern-js/deploy-output-aliases',
11
11
  setup (api) {
12
12
  api.onAfterDeploy(async ()=>{
13
- const { appDirectory, metaName } = api.getAppContext();
14
- const config = api.getNormalizedConfig();
15
- if ('modern-js' !== metaName && !config.deploy?.target && !process.env.MODERNJS_DEPLOY || 'node' !== resolveDeployTarget(config)) return;
13
+ const appContext = api.getAppContext();
14
+ if ('node' !== getDeployingTarget(appContext)) return;
15
+ const { appDirectory } = appContext;
16
16
  const entry = createRequire(__rspack_import_meta_filename__).resolve('@modern-js/prod-server');
17
17
  const identity = await readPackageIdentity(entry);
18
18
  await preserveNpmAliases({
@@ -29,13 +29,14 @@ const createDeployOutputAliasesPlugin = ({ resolveDeployTarget = external_target
29
29
  });
30
30
  }
31
31
  });
32
- const createDeployOutputPublicAssetsPlugin = ({ resolveDeployTarget = external_target_mjs_resolveDeployTarget } = {})=>({
32
+ const createDeployOutputPublicAssetsPlugin = ()=>({
33
33
  name: '@modern-js/deploy-output-public-assets',
34
34
  setup (api) {
35
35
  api.onAfterDeploy(async ()=>{
36
- const { appDirectory, metaName } = api.getAppContext();
36
+ const appContext = api.getAppContext();
37
+ if ('node' !== getDeployingTarget(appContext)) return;
38
+ const { appDirectory } = appContext;
37
39
  const config = api.getNormalizedConfig();
38
- if ('modern-js' !== metaName && !config.deploy?.target && !process.env.MODERNJS_DEPLOY || 'node' !== resolveDeployTarget(config)) return;
39
40
  await stageDeclaredPublicAssets({
40
41
  appDirectory,
41
42
  outputDirectory: node_path.join(appDirectory, '.output'),
@@ -1,5 +1,14 @@
1
1
  import "node:module";
2
- import { provider } from "std-env";
2
+ import { getArgv } from "@modern-js/utils";
3
+ import { provider as external_std_env_provider } from "std-env";
4
+ const DEPLOY_TARGETS = [
5
+ 'node',
6
+ 'vercel',
7
+ 'netlify',
8
+ 'ghPages',
9
+ 'cloudflare'
10
+ ];
11
+ const DEPLOY_TARGET_FLAG = '--deploy-target';
3
12
  const providerDeployTargets = {
4
13
  vercel: 'vercel',
5
14
  netlify: 'netlify',
@@ -7,5 +16,43 @@ const providerDeployTargets = {
7
16
  cloudflare_pages: 'cloudflare',
8
17
  cloudflare_workers: 'cloudflare'
9
18
  };
10
- const resolveDeployTarget = (config, envDeployTarget = process.env.MODERNJS_DEPLOY, detectedProvider = provider)=>config.deploy?.target || envDeployTarget || (detectedProvider ? providerDeployTargets[detectedProvider] : void 0) || 'node';
11
- export { resolveDeployTarget };
19
+ const readDeployTargetFlag = (argv)=>{
20
+ for (const [index, arg] of argv.entries()){
21
+ if (arg === DEPLOY_TARGET_FLAG) {
22
+ const value = argv[index + 1];
23
+ if (void 0 === value || value.startsWith('-')) throw new Error(`${DEPLOY_TARGET_FLAG} needs a value.`);
24
+ return value;
25
+ }
26
+ if (arg.startsWith(`${DEPLOY_TARGET_FLAG}=`)) return arg.slice(DEPLOY_TARGET_FLAG.length + 1);
27
+ }
28
+ };
29
+ const assertDeployTarget = (target, source)=>{
30
+ if (!DEPLOY_TARGETS.includes(target)) throw new Error(`Unknown deploy target '${target}' from ${source}. Use one of: ${DEPLOY_TARGETS.join(', ')}.`);
31
+ return target;
32
+ };
33
+ const resolveDeployTarget = ({ argv = getArgv(), configTarget, env = process.env.MODERNJS_DEPLOY, provider = external_std_env_provider } = {})=>{
34
+ const explicit = [
35
+ [
36
+ readDeployTargetFlag(argv),
37
+ DEPLOY_TARGET_FLAG
38
+ ],
39
+ [
40
+ configTarget,
41
+ 'deploy.target'
42
+ ],
43
+ [
44
+ env,
45
+ 'MODERNJS_DEPLOY'
46
+ ]
47
+ ].find(([target])=>target);
48
+ if (explicit?.[0]) return {
49
+ target: assertDeployTarget(explicit[0], explicit[1]),
50
+ explicit: true
51
+ };
52
+ return {
53
+ target: provider && providerDeployTargets[provider] || 'node',
54
+ explicit: false
55
+ };
56
+ };
57
+ const getDeployingTarget = ({ deployTarget, metaName })=>deployTarget && ('modern-js' === metaName || deployTarget.explicit) ? deployTarget.target : void 0;
58
+ export { DEPLOY_TARGETS, DEPLOY_TARGET_FLAG, getDeployingTarget, resolveDeployTarget };
@@ -1,14 +1,9 @@
1
1
  import "node:module";
2
2
  import node_path from "node:path";
3
3
  import { NODE_PUBLIC_ASSET_SCOPE, normalizeDeclaredPublicAssets, resolveAddedDeclaredPublicAssetPaths } from "../deploy-output/public-assets.mjs";
4
+ import { getDeployingTarget } from "../deploy-output/target.mjs";
4
5
  import { emitFrameworkMicroVerticalReleaseEnvelope, emitNodeStagedReleaseEnvelope, verifyBuildOutputReleaseEnvelope, verifyNodeReleaseEnvelopeStaging } from "./framework-output.mjs";
5
- const resolveActiveDeployTarget = (api, resolveDeployTarget)=>{
6
- const { metaName } = api.getAppContext();
7
- const config = api.getNormalizedConfig();
8
- if ('modern-js' !== metaName && !config.deploy?.target && !process.env.MODERNJS_DEPLOY) return;
9
- return resolveDeployTarget(config);
10
- };
11
- const createUltramodernReleaseEnvelopePlugin = ({ resolveDeployTarget })=>({
6
+ const createUltramodernReleaseEnvelopePlugin = ()=>({
12
7
  name: '@modern-js/ultramodern-release-envelope',
13
8
  pre: [
14
9
  '@modern-js/backend-federation-build',
@@ -30,19 +25,19 @@ const createUltramodernReleaseEnvelopePlugin = ({ resolveDeployTarget })=>({
30
25
  });
31
26
  };
32
27
  api.onAfterBuild(async ()=>{
33
- const configuredTarget = resolveDeployTarget(api.getNormalizedConfig());
28
+ const configuredTarget = api.getAppContext().deployTarget?.target;
34
29
  if ('node' !== configuredTarget && 'cloudflare' !== configuredTarget) return;
35
30
  await emitBuildEnvelope(configuredTarget, false);
36
31
  });
37
32
  api.onBeforeDeploy(async ()=>{
38
- const configuredTarget = resolveActiveDeployTarget(api, resolveDeployTarget);
33
+ const configuredTarget = getDeployingTarget(api.getAppContext());
39
34
  if ('node' !== configuredTarget) return;
40
35
  await emitBuildEnvelope(configuredTarget);
41
36
  const { distDirectory } = api.getAppContext();
42
37
  await verifyBuildOutputReleaseEnvelope(distDirectory, configuredTarget);
43
38
  });
44
39
  api.onAfterDeploy(async ()=>{
45
- const configuredTarget = resolveActiveDeployTarget(api, resolveDeployTarget);
40
+ const configuredTarget = getDeployingTarget(api.getAppContext());
46
41
  if ('node' !== configuredTarget) return;
47
42
  const { appDirectory, distDirectory } = api.getAppContext();
48
43
  const outputDirectory = node_path.join(appDirectory, '.output');
@@ -1,13 +1,12 @@
1
1
  import type { BffUserConfig } from '@modern-js/server-core';
2
2
  import type { EnvironmentConfig, ModifyBundlerChainFn, Rspack } from '@rsbuild/core';
3
+ import type { ResolvedDeployTarget } from './deploy-output/target.js';
3
4
  export interface CloudflareBuilderNormalizedConfig {
4
5
  bff?: BffUserConfig;
5
- deploy?: {
6
- target?: string;
7
- };
8
6
  }
9
7
  export interface CloudflareBuilderAppContext {
10
8
  apiOnly?: boolean;
9
+ deployTarget?: ResolvedDeployTarget;
11
10
  apiDirectory: string;
12
11
  appDirectory: string;
13
12
  entrypoints?: ReadonlyArray<{
@@ -19,9 +18,7 @@ export interface CloudflareBuilderEnvironmentsOptions {
19
18
  appContext: CloudflareBuilderAppContext;
20
19
  environments: Record<string, EnvironmentConfig>;
21
20
  normalizedConfig: CloudflareBuilderNormalizedConfig;
22
- resolveDeployProvider?: ResolveCloudflareDeployProvider;
23
21
  }
24
- export type ResolveCloudflareDeployProvider = () => string | undefined;
25
22
  export interface CloudflareWorkerRspackConfig {
26
23
  externals: Record<string, string>;
27
24
  externalsType: 'module-import';
@@ -96,8 +93,7 @@ type FunctionExternal = (data: Rspack.ExternalItemFunctionData, callback: (error
96
93
  export declare const claimsByFunctionExternal: (externals: readonly FunctionExternal[], data: Rspack.ExternalItemFunctionData) => Promise<boolean>;
97
94
  export declare function getCloudflareWorkerRspackConfig(workerEntryNames: Iterable<string>): CloudflareWorkerRspackConfig;
98
95
  export declare function applyCloudflareWorkerRspackConfig(chain: Parameters<ModifyBundlerChainFn>[0], workerEntryNames: Iterable<string>): void;
99
- export declare function applyCloudflareWorkerMfRuntimeBoundary(chain: Parameters<ModifyBundlerChainFn>[0]): void;
100
- export declare function getCloudflareBuilderEnvironments({ appContext, environments, normalizedConfig, resolveDeployProvider, }: CloudflareBuilderEnvironmentsOptions): Record<string, EnvironmentConfig>;
96
+ export declare function getCloudflareBuilderEnvironments({ appContext, environments, normalizedConfig, }: CloudflareBuilderEnvironmentsOptions): Record<string, EnvironmentConfig>;
101
97
  export declare function applyCloudflareBuilderEnvironments(options: CloudflareBuilderEnvironmentsOptions): CloudflareBuilderEnvironmentsResult;
102
- export declare const createCloudflareBuilderPlugin: (resolveDeployProvider?: ResolveCloudflareDeployProvider) => CloudflareBuilderPlugin;
98
+ export declare const createCloudflareBuilderPlugin: () => CloudflareBuilderPlugin;
103
99
  export {};
@@ -1,7 +1,8 @@
1
1
  export type { ResolveEffectTsgoCompilerOptions } from './build-config/public.js';
2
2
  export { getBuildConfigEnvironment, resolveEffectTsgoCompiler, } from './build-config/public.js';
3
3
  export { createRemoteManifestUrl } from './build-config/remote-address.js';
4
- export type DeployTarget = 'node' | 'vercel' | 'netlify' | 'ghPages' | 'cloudflare';
4
+ export type { DeployTarget } from './deploy-output/target.js';
5
+ export { resolveDeployTarget } from './deploy-output/target.js';
5
6
  export type CloudflareWorkerSecurityCspMode = 'enforce' | 'report-only' | 'off';
6
7
  export type JsonValue = string | number | boolean | null | JsonValue[] | {
7
8
  [key: string]: JsonValue;
@@ -1,31 +1,27 @@
1
1
  import type { NodePublicAssetConfig } from '../config.js';
2
- import { type DeployOutputConfig } from './target.js';
2
+ import { type ResolvedDeployTarget } from './target.js';
3
+ export interface DeployOutputAppContext {
4
+ appDirectory: string;
5
+ metaName: string;
6
+ deployTarget?: ResolvedDeployTarget;
7
+ }
3
8
  export interface DeployOutputPluginApi {
4
- getAppContext(): {
5
- appDirectory: string;
6
- metaName: string;
7
- };
8
- getNormalizedConfig(): DeployOutputConfig;
9
+ getAppContext(): DeployOutputAppContext;
9
10
  onAfterDeploy(handler: () => Promise<void>): void;
10
11
  }
11
- export declare const createDeployOutputAliasesPlugin: ({ resolveDeployTarget, }?: {
12
- resolveDeployTarget?: (config: DeployOutputConfig) => string;
13
- }) => {
12
+ export declare const createDeployOutputAliasesPlugin: () => {
14
13
  name: string;
15
14
  setup(api: DeployOutputPluginApi): void;
16
15
  };
17
- export interface DeployOutputPublicAssetsConfig extends DeployOutputConfig {
18
- deploy?: DeployOutputConfig['deploy'] & {
16
+ export interface DeployOutputPublicAssetsConfig {
17
+ deploy?: {
19
18
  node?: {
20
19
  publicAssets?: NodePublicAssetConfig[];
21
20
  };
22
21
  };
23
22
  }
24
23
  export interface DeployOutputPublicAssetsPluginApi {
25
- getAppContext(): {
26
- appDirectory: string;
27
- metaName: string;
28
- };
24
+ getAppContext(): DeployOutputAppContext;
29
25
  getNormalizedConfig(): DeployOutputPublicAssetsConfig;
30
26
  onAfterDeploy(handler: () => Promise<void>): void;
31
27
  }
@@ -33,9 +29,7 @@ export interface DeployOutputPublicAssetsPluginApi {
33
29
  * Stage `deploy.node.publicAssets` into the Node deploy output. Cloudflare
34
30
  * stages `deploy.worker.publicAssets` inside its deploy preset.
35
31
  */
36
- export declare const createDeployOutputPublicAssetsPlugin: ({ resolveDeployTarget, }?: {
37
- resolveDeployTarget?: (config: DeployOutputConfig) => string;
38
- }) => {
32
+ export declare const createDeployOutputPublicAssetsPlugin: () => {
39
33
  name: string;
40
34
  setup(api: DeployOutputPublicAssetsPluginApi): void;
41
35
  };
@@ -1,6 +1,29 @@
1
- export interface DeployOutputConfig {
2
- deploy?: {
3
- target?: string;
4
- };
1
+ export declare const DEPLOY_TARGETS: readonly ['node', 'vercel', 'netlify', 'ghPages', 'cloudflare'];
2
+ export type DeployTarget = (typeof DEPLOY_TARGETS)[number];
3
+ export declare const DEPLOY_TARGET_FLAG = "--deploy-target";
4
+ export interface ResolvedDeployTarget {
5
+ target: DeployTarget;
6
+ /** The flag, `deploy.target` or `MODERNJS_DEPLOY` chose the target. */
7
+ explicit: boolean;
5
8
  }
6
- export declare const resolveDeployTarget: (config: DeployOutputConfig, envDeployTarget?: string | undefined, detectedProvider?: import("std-env").ProviderName) => string;
9
+ export interface ResolveDeployTargetOptions {
10
+ argv?: readonly string[];
11
+ configTarget?: string;
12
+ env?: string;
13
+ provider?: string;
14
+ }
15
+ /**
16
+ * The one deploy-target resolver: `--deploy-target` > `deploy.target` >
17
+ * `MODERNJS_DEPLOY` > detected CI provider > `node`. app-tools stores the
18
+ * result in the app context once; config files that branch on the target call
19
+ * it without `configTarget`.
20
+ */
21
+ export declare const resolveDeployTarget: ({ argv, configTarget, env, provider, }?: ResolveDeployTargetOptions) => ResolvedDeployTarget;
22
+ /**
23
+ * The target `modern deploy` stages. Apps under another CLI meta name deploy
24
+ * only when a flag, config or env chose the target explicitly.
25
+ */
26
+ export declare const getDeployingTarget: ({ deployTarget, metaName, }: {
27
+ deployTarget?: ResolvedDeployTarget;
28
+ metaName: string;
29
+ }) => DeployTarget | undefined;
@@ -1,8 +1,7 @@
1
1
  import type { NodePublicAssetConfig } from '../config.js';
2
- type ReleaseEnvelopeTarget = 'cloudflare' | 'node' | string;
2
+ import { type ResolvedDeployTarget } from '../deploy-output/target.js';
3
3
  export interface ReleaseEnvelopeConfig {
4
4
  deploy?: {
5
- target?: string;
6
5
  node?: {
7
6
  publicAssets?: NodePublicAssetConfig[];
8
7
  };
@@ -13,6 +12,7 @@ export interface ReleaseEnvelopeAppContext {
13
12
  appDirectory: string;
14
13
  distDirectory: string;
15
14
  metaName: string;
15
+ deployTarget?: ResolvedDeployTarget;
16
16
  }
17
17
  export interface ReleaseEnvelopePluginApi<Config extends ReleaseEnvelopeConfig = ReleaseEnvelopeConfig> {
18
18
  getAppContext(): ReleaseEnvelopeAppContext;
@@ -27,8 +27,4 @@ export interface ReleaseEnvelopePlugin<Config extends ReleaseEnvelopeConfig = Re
27
27
  post: string[];
28
28
  setup(api: ReleaseEnvelopePluginApi<Config>): void;
29
29
  }
30
- export type ResolveDeployTarget<Config extends ReleaseEnvelopeConfig = ReleaseEnvelopeConfig> = (config: Config) => ReleaseEnvelopeTarget;
31
- export declare const createUltramodernReleaseEnvelopePlugin: <Config extends ReleaseEnvelopeConfig>({ resolveDeployTarget, }: {
32
- resolveDeployTarget: ResolveDeployTarget<Config>;
33
- }) => ReleaseEnvelopePlugin<Config>;
34
- export {};
30
+ export declare const createUltramodernReleaseEnvelopePlugin: <Config extends ReleaseEnvelopeConfig>() => ReleaseEnvelopePlugin<Config>;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "directory": "packages/solutions/app-tools-extensions"
12
12
  },
13
13
  "license": "MIT",
14
- "version": "3.9.0-ultramodern.19",
14
+ "version": "3.9.0-ultramodern.20",
15
15
  "files": [
16
16
  "dist",
17
17
  "src"
@@ -153,16 +153,16 @@
153
153
  "@babel/parser": "^8.0.6",
154
154
  "@babel/traverse": "^8.0.6",
155
155
  "@loadable/component": "5.16.7",
156
- "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.0-ultramodern.19",
157
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.19",
158
- "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.0-ultramodern.19",
159
- "@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.0-ultramodern.19",
160
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.0-ultramodern.19",
161
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.19",
162
- "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.19",
163
- "@modern-js/surface-resolution": "npm:@bleedingdev/modern-js-surface-resolution@3.9.0-ultramodern.19",
164
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.19",
165
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.19",
156
+ "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.0-ultramodern.20",
157
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.20",
158
+ "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.0-ultramodern.20",
159
+ "@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.0-ultramodern.20",
160
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.0-ultramodern.20",
161
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.20",
162
+ "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.20",
163
+ "@modern-js/surface-resolution": "npm:@bleedingdev/modern-js-surface-resolution@3.9.0-ultramodern.20",
164
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.20",
165
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.20",
166
166
  "@swc/helpers": "^0.5.23",
167
167
  "@vercel/nft": "^1.11.0",
168
168
  "compression-webpack-plugin": "^12.0.0",
@@ -179,11 +179,12 @@
179
179
  }
180
180
  },
181
181
  "devDependencies": {
182
- "@modern-js/bff-effect": "npm:@bleedingdev/modern-js-bff-effect@3.9.0-ultramodern.19",
183
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.19",
184
- "@modern-js/plugin-bff-extensions": "npm:@bleedingdev/modern-js-plugin-bff-extensions@3.9.0-ultramodern.19",
185
- "@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.9.0-ultramodern.19",
186
- "@module-federation/runtime-tools": "npm:@bleedingdev/mf-runtime-tools@2.9.1",
182
+ "@modern-js/bff-effect": "npm:@bleedingdev/modern-js-bff-effect@3.9.0-ultramodern.20",
183
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.20",
184
+ "@modern-js/plugin-bff-extensions": "npm:@bleedingdev/modern-js-plugin-bff-extensions@3.9.0-ultramodern.20",
185
+ "@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.9.0-ultramodern.20",
186
+ "@module-federation/modern-js-v3": "2.9.2",
187
+ "@module-federation/runtime-tools": "2.9.2",
187
188
  "@rsbuild/core": "2.2.9",
188
189
  "@rslib/core": "1.0.2",
189
190
  "@scripts/rstest-config": "2.66.0",
@@ -2,21 +2,23 @@ import {
2
2
  type BrowserManifestAddressOptions,
3
3
  resolveBrowserManifestAddress,
4
4
  } from '@modern-js/surface-resolution';
5
+ import { resolveDeployTarget } from '../deploy-output/target';
5
6
  import { getBuildConfigEnvironment } from './build-environment';
6
7
 
7
8
  /** Adapt build environment leases and MF's name@URL syntax to discovery policy. */
8
9
  export function createRemoteManifestUrl(
9
10
  options: BrowserManifestAddressOptions,
10
11
  ): string {
11
- const env = Object.fromEntries(
12
- [
13
- options.manifestEnv,
14
- options.publicUrlEnv,
15
- 'MODERNJS_DEPLOY',
16
- 'ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN',
17
- 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS',
18
- ].map(name => [name, getBuildConfigEnvironment(name)]),
19
- );
12
+ const env: Record<string, string | undefined> = {
13
+ ...Object.fromEntries(
14
+ [
15
+ options.manifestEnv,
16
+ options.publicUrlEnv,
17
+ 'ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN',
18
+ ].map(name => [name, getBuildConfigEnvironment(name)]),
19
+ ),
20
+ MODERNJS_DEPLOY: resolveDeployTarget().target,
21
+ };
20
22
  const address = resolveBrowserManifestAddress(
21
23
  env,
22
24
  options,
@@ -12,13 +12,13 @@ import type {
12
12
  RsbuildEntryDescription,
13
13
  Rspack,
14
14
  } from '@rsbuild/core';
15
- import { provider } from 'std-env';
16
15
  import {
17
16
  CLOUDFLARE_ROUTE_DATA_HANDLER_EXPORT,
18
17
  CLOUDFLARE_WORKER_NODE_BUILTINS,
19
18
  CLOUDFLARE_WORKER_PLATFORM_MODULES,
20
19
  getCloudflareWorkerRouteDataEntryName,
21
20
  } from './cloudflare-output-contract';
21
+ import type { ResolvedDeployTarget } from './deploy-output/target';
22
22
  import { getTemplatePath } from './read-template';
23
23
 
24
24
  const moduleRequire = createRequire(import.meta.url);
@@ -39,10 +39,6 @@ const WORKER_ROUTE_DATA_TEMPLATE = 'cloudflare-worker-route-data.mjs';
39
39
  // the workspace package and the published `@bleedingdev/modern-js-*` name.
40
40
  const DATA_LOADER_CLIENT_TRANSFORM =
41
41
  /plugin-data-loader[\\/](?:.+[\\/])?loader\.[cm]?js$/u;
42
- const MF_SSR_DATA_FETCH_RUNTIME_PLUGIN =
43
- '@module-federation/modern-js-v3/ssr-inject-data-fetch-function-plugin';
44
- const MF_SSR_DEV_RUNTIME_PLUGIN =
45
- '@module-federation/modern-js-v3/ssr-dev-plugin';
46
42
  // Rspack's default dependency-type conditions (`resolve.byDependency`).
47
43
  const WORKER_DEPENDENCY_CONDITIONS = [
48
44
  ['esm', 'import'],
@@ -67,11 +63,11 @@ const JS_OR_TS_EXTENSIONS = new Set([
67
63
 
68
64
  export interface CloudflareBuilderNormalizedConfig {
69
65
  bff?: BffUserConfig;
70
- deploy?: { target?: string };
71
66
  }
72
67
 
73
68
  export interface CloudflareBuilderAppContext {
74
69
  apiOnly?: boolean;
70
+ deployTarget?: ResolvedDeployTarget;
75
71
  apiDirectory: string;
76
72
  appDirectory: string;
77
73
  entrypoints?: ReadonlyArray<{ entryName: string }>;
@@ -82,11 +78,8 @@ export interface CloudflareBuilderEnvironmentsOptions {
82
78
  appContext: CloudflareBuilderAppContext;
83
79
  environments: Record<string, EnvironmentConfig>;
84
80
  normalizedConfig: CloudflareBuilderNormalizedConfig;
85
- resolveDeployProvider?: ResolveCloudflareDeployProvider;
86
81
  }
87
82
 
88
- export type ResolveCloudflareDeployProvider = () => string | undefined;
89
-
90
83
  export interface CloudflareWorkerRspackConfig {
91
84
  externals: Record<string, string>;
92
85
  externalsType: 'module-import';
@@ -654,20 +647,6 @@ function removeCloudflareWorkerDataLoaderClientTransform(
654
647
  }
655
648
  }
656
649
 
657
- export function applyCloudflareWorkerMfRuntimeBoundary(
658
- chain: Parameters<ModifyBundlerChainFn>[0],
659
- ) {
660
- const runtimePlugin = getTemplatePath(
661
- 'cloudflare-worker-mf-ssr-runtime-plugin.mjs',
662
- );
663
- chain.plugins.delete('plugin-module-federation');
664
- chain.resolve.alias.set(
665
- `${MF_SSR_DATA_FETCH_RUNTIME_PLUGIN}$`,
666
- runtimePlugin,
667
- );
668
- chain.resolve.alias.set(`${MF_SSR_DEV_RUNTIME_PLUGIN}$`, runtimePlugin);
669
- }
670
-
671
650
  const getEffectBffEntry = (
672
651
  normalizedConfig: CloudflareBuilderNormalizedConfig,
673
652
  appContext: CloudflareBuilderAppContext,
@@ -690,31 +669,6 @@ const getEffectBffEntry = (
690
669
  return resolveJsOrTsEntry(path.resolve(appContext.apiDirectory, 'index'));
691
670
  };
692
671
 
693
- const CLOUDFLARE_DEPLOY_PROVIDERS = new Set([
694
- 'cloudflare',
695
- 'cloudflare_pages',
696
- 'cloudflare_workers',
697
- ]);
698
-
699
- const resolveStdEnvDeployProvider: ResolveCloudflareDeployProvider = () =>
700
- provider;
701
-
702
- const isCloudflareWorkerDeploy = (
703
- normalizedConfig: CloudflareBuilderNormalizedConfig,
704
- resolveDeployProvider: ResolveCloudflareDeployProvider,
705
- ) => {
706
- const explicitTarget =
707
- normalizedConfig.deploy?.target || process.env.MODERNJS_DEPLOY;
708
- if (explicitTarget) {
709
- return explicitTarget === 'cloudflare';
710
- }
711
-
712
- const detectedProvider = resolveDeployProvider();
713
- return detectedProvider
714
- ? CLOUDFLARE_DEPLOY_PROVIDERS.has(detectedProvider)
715
- : false;
716
- };
717
-
718
672
  const rewriteWorkerEntryPath = (entry: string) =>
719
673
  entry
720
674
  .replace('index.jsx', 'index.server.jsx')
@@ -912,7 +866,13 @@ const createCloudflareBundlerChain = (
912
866
  .plugin('cloudflare-worker-absent-optional-dependencies')
913
867
  .use(AbsentOptionalDependencyPlugin);
914
868
 
915
- applyCloudflareWorkerMfRuntimeBoundary(chain);
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');
916
876
  setAliasIfPresent(chain.resolve.alias, 'react$', reactFile);
917
877
  setAliasIfPresent(
918
878
  chain.resolve.alias,
@@ -942,9 +902,8 @@ export function getCloudflareBuilderEnvironments({
942
902
  appContext,
943
903
  environments,
944
904
  normalizedConfig,
945
- resolveDeployProvider = resolveStdEnvDeployProvider,
946
905
  }: CloudflareBuilderEnvironmentsOptions): Record<string, EnvironmentConfig> {
947
- if (!isCloudflareWorkerDeploy(normalizedConfig, resolveDeployProvider)) {
906
+ if (appContext.deployTarget?.target !== 'cloudflare') {
948
907
  return environments;
949
908
  }
950
909
 
@@ -1001,9 +960,7 @@ export function applyCloudflareBuilderEnvironments(
1001
960
  return { environments: getCloudflareBuilderEnvironments(options) };
1002
961
  }
1003
962
 
1004
- export const createCloudflareBuilderPlugin = (
1005
- resolveDeployProvider = resolveStdEnvDeployProvider,
1006
- ): CloudflareBuilderPlugin => ({
963
+ export const createCloudflareBuilderPlugin = (): CloudflareBuilderPlugin => ({
1007
964
  name: '@modern-js/cloudflare-builder',
1008
965
  setup(api) {
1009
966
  api.modifyBuilderEnvironments(({ environments }) =>
@@ -1011,7 +968,6 @@ export const createCloudflareBuilderPlugin = (
1011
968
  appContext: api.getAppContext(),
1012
969
  environments,
1013
970
  normalizedConfig: api.getNormalizedConfig(),
1014
- resolveDeployProvider,
1015
971
  }),
1016
972
  );
1017
973
  },