@bleedingdev/modern-js-create 3.5.0-ultramodern.12 → 3.5.0-ultramodern.14

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.
@@ -54,6 +54,7 @@ const external_create_package_root_cjs_namespaceObject = require("../create-pack
54
54
  const external_ultramodern_package_source_cjs_namespaceObject = require("../ultramodern-package-source.cjs");
55
55
  const app_files_cjs_namespaceObject = require("../ultramodern-workspace/app-files.cjs");
56
56
  const mf_validation_cjs_namespaceObject = require("../ultramodern-workspace/mf-validation.cjs");
57
+ const module_federation_cjs_namespaceObject = require("../ultramodern-workspace/module-federation.cjs");
57
58
  const package_json_cjs_namespaceObject = require("../ultramodern-workspace/package-json.cjs");
58
59
  const versions_cjs_namespaceObject = require("../ultramodern-workspace/versions.cjs");
59
60
  const workspace_scripts_cjs_namespaceObject = require("../ultramodern-workspace/workspace-scripts.cjs");
@@ -235,6 +236,8 @@ const strictEffectPackageVersionPolicyExclusions = [
235
236
  `effect@${versions_cjs_namespaceObject.EFFECT_VERSION}`,
236
237
  `@effect/opentelemetry@${versions_cjs_namespaceObject.EFFECT_VERSION}`
237
238
  ];
239
+ const moduleFederationModernJsPatchPath = `patches/@module-federation__modern-js-v3@${versions_cjs_namespaceObject.MODULE_FEDERATION_VERSION}.patch`;
240
+ const moduleFederationModernJsPatchSourcePath = external_node_path_default().join(createPackageRoot, 'template-workspace', moduleFederationModernJsPatchPath);
238
241
  const effectDeclarationPatchPath = 'patches/effect-schema-error-type-id.patch';
239
242
  const effectDeclarationPatchSourcePath = external_node_path_default().join(createPackageRoot, 'template-workspace', effectDeclarationPatchPath);
240
243
  const drizzleOrmDeclarationPatchPath = 'patches/drizzle-orm-ts7-strict-declarations.patch';
@@ -266,9 +269,14 @@ function updateGeneratedPackageScripts(packageJson) {
266
269
  if (!scripts || 'object' != typeof scripts || Array.isArray(scripts)) return false;
267
270
  let changed = false;
268
271
  const cloudflareBuild = scripts['cloudflare:build'];
269
- if ('string' == typeof cloudflareBuild && cloudflareBuild.includes(cloudflareModernDeployCommand) && !cloudflareBuild.includes(cloudflareModernDeploySkipBuildCommand)) {
270
- scripts['cloudflare:build'] = cloudflareBuild.replace(cloudflareModernDeployCommand, cloudflareModernDeploySkipBuildCommand);
271
- changed = true;
272
+ if ('string' == typeof cloudflareBuild) {
273
+ let nextCloudflareBuild = cloudflareBuild;
274
+ if (nextCloudflareBuild.includes(cloudflareModernDeployCommand) && !nextCloudflareBuild.includes(cloudflareModernDeploySkipBuildCommand)) nextCloudflareBuild = nextCloudflareBuild.replace(cloudflareModernDeployCommand, cloudflareModernDeploySkipBuildCommand);
275
+ nextCloudflareBuild = nextCloudflareBuild.replace(/ && node \S*scripts\/generate-public-surface-assets\.m[ct]s --app [^&]+ --target dist(?= && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build)/u, '');
276
+ if (nextCloudflareBuild !== cloudflareBuild) {
277
+ scripts['cloudflare:build'] = nextCloudflareBuild;
278
+ changed = true;
279
+ }
272
280
  }
273
281
  const cloudflareDeploy = scripts['cloudflare:deploy'];
274
282
  if ('string' == typeof cloudflareDeploy && cloudflareDeploy.includes(cloudflareWranglerDeployInvalidSkipBuildCommand)) {
@@ -475,6 +483,7 @@ function workspaceUsesDependency(workspaceRoot, packageName) {
475
483
  }
476
484
  function ensureGeneratedDeclarationPatches(workspaceRoot, options) {
477
485
  let changed = false;
486
+ changed = ensureGeneratedPatchFile(workspaceRoot, moduleFederationModernJsPatchPath, moduleFederationModernJsPatchSourcePath) || changed;
478
487
  changed = ensureGeneratedPatchFile(workspaceRoot, effectDeclarationPatchPath, effectDeclarationPatchSourcePath) || changed;
479
488
  changed = options.includeDrizzleOrmPatch ? ensureGeneratedPatchFile(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed : removeGeneratedPatchFileIfUnchanged(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed;
480
489
  return changed;
@@ -522,6 +531,9 @@ function updateGeneratedPnpmWorkspacePolicy(workspaceRoot) {
522
531
  const effectPatch = ensureYamlMapEntry(source, 'patchedDependencies', `effect@${versions_cjs_namespaceObject.EFFECT_VERSION}`, effectDeclarationPatchPath);
523
532
  source = effectPatch.source;
524
533
  changed = effectPatch.changed || changed;
534
+ const moduleFederationModernJsPatch = ensureYamlMapEntry(source, 'patchedDependencies', `@module-federation/modern-js-v3@${versions_cjs_namespaceObject.MODULE_FEDERATION_VERSION}`, moduleFederationModernJsPatchPath);
535
+ source = moduleFederationModernJsPatch.source;
536
+ changed = moduleFederationModernJsPatch.changed || changed;
525
537
  const drizzleOrmPatch = usesDrizzleOrm ? ensureYamlMapEntry(source, 'patchedDependencies', `drizzle-orm@${versions_cjs_namespaceObject.DRIZZLE_ORM_VERSION}`, drizzleOrmDeclarationPatchPath) : removeYamlMapEntry(source, `drizzle-orm@${versions_cjs_namespaceObject.DRIZZLE_ORM_VERSION}`);
526
538
  source = drizzleOrmPatch.source;
527
539
  changed = drizzleOrmPatch.changed || changed;
@@ -571,7 +583,8 @@ function ensureGeneratedIgnoreRules(workspaceRoot) {
571
583
  let changed = false;
572
584
  for (const rule of [
573
585
  '.mf/',
574
- '**/.mf/'
586
+ '**/.mf/',
587
+ 'dist-cloudflare/'
575
588
  ])if (!lines.includes(rule)) {
576
589
  lines.push(rule);
577
590
  changed = true;
@@ -598,6 +611,12 @@ function updateGeneratedTypeScriptSurfaces(workspaceRoot, config) {
598
611
  }
599
612
  return changed;
600
613
  }
614
+ function updateGeneratedModernConfigs(workspaceRoot, config) {
615
+ let changed = false;
616
+ const apps = (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)(config);
617
+ for (const app of apps)changed = writeTextIfChanged(external_node_path_default().join(workspaceRoot, app.directory, 'modern.config.ts'), (0, module_federation_cjs_namespaceObject.createAppModernConfig)(config.workspace.packageScope, app)) || changed;
618
+ return changed;
619
+ }
601
620
  function updateReferenceTopology(workspaceRoot) {
602
621
  const topologyPath = external_node_path_default().join(workspaceRoot, 'topology/reference-topology.json');
603
622
  if (!external_node_fs_default().existsSync(topologyPath)) return false;
@@ -671,7 +690,9 @@ and pnpm contract:check.
671
690
  const packageSource = createMigrationPackageSource(args, current);
672
691
  updateUltramodernConfig(context.workspaceRoot, packageSource);
673
692
  updateReferenceTopology(context.workspaceRoot);
674
- updateGeneratedTypeScriptSurfaces(context.workspaceRoot, current);
693
+ const migrated = (0, external_config_cjs_namespaceObject.readUltramodernConfig)(context.workspaceRoot);
694
+ updateGeneratedTypeScriptSurfaces(context.workspaceRoot, migrated);
695
+ updateGeneratedModernConfigs(context.workspaceRoot, migrated);
675
696
  for (const relativePackageFile of listWorkspacePackageFiles(context.workspaceRoot)){
676
697
  const packageFile = external_node_path_default().join(context.workspaceRoot, relativePackageFile);
677
698
  const packageJson = readJsonFile(packageFile);
@@ -144,8 +144,10 @@ ${defaultAssetPrefixSource}
144
144
  // load remoteEntry.js and exposed chunks from the remote origin, not the host.
145
145
  const assetPrefix =
146
146
  configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix;
147
- const buildCacheTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';
148
- const buildCacheDirectory = \`node_modules/.cache/rspack-\${appId}-\${buildCacheTarget}\`;
147
+ const buildTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';
148
+ const buildOutputRoot = cloudflareDeployEnabled ? 'dist-cloudflare' : 'dist';
149
+ const buildTempDirectory = \`node_modules/.modern-js-\${appId}-\${buildTarget}\`;
150
+ const buildCacheDirectory = \`node_modules/.cache/rspack-\${appId}-\${buildTarget}\`;
149
151
 
150
152
  if (
151
153
  cloudflareDeployEnabled &&
@@ -187,13 +189,15 @@ ${bffConfig} ...(cloudflareDeployEnabled
187
189
  disableTsChecker: false,
188
190
  distPath: {
189
191
  html: './',
192
+ root: buildOutputRoot,
190
193
  },
191
194
  polyfill: 'off',
192
195
  splitRouteChunks: true,
196
+ tempDir: buildTempDirectory,
193
197
  },
194
198
  performance: {
195
199
  buildCache: {
196
- cacheDigest: [appId, buildCacheTarget],
200
+ cacheDigest: [appId, buildTarget],
197
201
  cacheDirectory: buildCacheDirectory,
198
202
  },
199
203
  rsdoctor: {
@@ -412,7 +412,6 @@ function createRootTsConfig(apps = []) {
412
412
  }
413
413
  function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [], bridge) {
414
414
  const publicSurfaceBuildCommand = (0, external_public_surface_cjs_namespaceObject.createPublicSurfaceGenerationCommand)(app, 'dist');
415
- const publicSurfaceCloudflareBuildCommand = (0, external_public_surface_cjs_namespaceObject.createPublicSurfaceGenerationCommand)(app, 'dist');
416
415
  const publicSurfaceCloudflareOutputCommand = (0, external_public_surface_cjs_namespaceObject.createPublicSurfaceGenerationCommand)(app, 'cloudflare');
417
416
  const packageExports = Object.fromEntries(Object.entries(app.exposes ?? {}).map(([expose, source])=>[
418
417
  expose,
@@ -425,7 +424,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
425
424
  scripts: {
426
425
  dev: 'modern dev',
427
426
  build: app.exposes ? `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand} && node ${(0, external_naming_cjs_namespaceObject.relativeRootFor)(app.directory)}/scripts/assert-mf-types.mts` : `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand}`,
428
- 'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ${publicSurfaceCloudflareBuildCommand} && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build && ${publicSurfaceCloudflareOutputCommand}`,
427
+ 'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build && ${publicSurfaceCloudflareOutputCommand}`,
429
428
  'cloudflare:deploy': 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS=true pnpm run cloudflare:build && wrangler deploy --config .output/wrangler.json',
430
429
  'cloudflare:preview': 'pnpm run cloudflare:build && wrangler dev --config .output/wrangler.json',
431
430
  'cloudflare:proof': `node ${(0, external_naming_cjs_namespaceObject.relativeRootFor)(app.directory)}/scripts/proof-cloudflare-version.mts --app ${app.id}`,
@@ -175,6 +175,7 @@ function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
175
175
  return (0, external_fs_io_cjs_namespaceObject.renderFileTemplate)("workspace-scripts/validate-ultramodern-workspace.mjs", {
176
176
  packageScope: scope,
177
177
  effectVersion: external_versions_cjs_namespaceObject.EFFECT_VERSION,
178
+ moduleFederationVersion: external_versions_cjs_namespaceObject.MODULE_FEDERATION_VERSION,
178
179
  nodeVersion: external_versions_cjs_namespaceObject.NODE_VERSION,
179
180
  pnpmVersion: external_versions_cjs_namespaceObject.PNPM_VERSION,
180
181
  tailwindEnabledJson: JSON.stringify(enableTailwind),
@@ -178,6 +178,7 @@ function generateUltramodernWorkspace(options) {
178
178
  drizzleOrmVersion: external_versions_cjs_namespaceObject.DRIZZLE_ORM_VERSION,
179
179
  effectVersion: external_versions_cjs_namespaceObject.EFFECT_VERSION,
180
180
  effectVitestVersion: external_versions_cjs_namespaceObject.EFFECT_VITEST_VERSION,
181
+ moduleFederationVersion: external_versions_cjs_namespaceObject.MODULE_FEDERATION_VERSION,
181
182
  tanstackRouterCoreVersion: external_versions_cjs_namespaceObject.TANSTACK_ROUTER_CORE_VERSION,
182
183
  tanstackRouterVersion: external_versions_cjs_namespaceObject.TANSTACK_ROUTER_VERSION,
183
184
  typescriptVersion: external_versions_cjs_namespaceObject.TYPESCRIPT_VERSION,
@@ -7,8 +7,9 @@ import { resolveCreatePackageRoot } from "../create-package-root.js";
7
7
  import { BLEEDINGDEV_PACKAGE_NAME_PREFIX, BLEEDINGDEV_PACKAGE_SCOPE, ULTRAMODERN_SINGLE_APP_MODERN_PACKAGES, ULTRAMODERN_WORKSPACE_MODERN_PACKAGES, WORKSPACE_PACKAGE_VERSION, modernPackageSpecifier } from "../ultramodern-package-source.js";
8
8
  import { createAppEnvDts } from "../ultramodern-workspace/app-files.js";
9
9
  import { validateModuleFederationTypes } from "../ultramodern-workspace/mf-validation.js";
10
+ import { createAppModernConfig } from "../ultramodern-workspace/module-federation.js";
10
11
  import { createAppMfTypesTsConfig, createAppTsConfig, createSharedPackageTsConfig, createTsConfigBase } from "../ultramodern-workspace/package-json.js";
11
- import { DRIZZLE_ORM_VERSION, EFFECT_TSGO_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, OXFMT_VERSION, OXLINT_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION } from "../ultramodern-workspace/versions.js";
12
+ import { DRIZZLE_ORM_VERSION, EFFECT_TSGO_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, MODULE_FEDERATION_VERSION, OXFMT_VERSION, OXLINT_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION } from "../ultramodern-workspace/versions.js";
12
13
  import { createWorkspaceValidationScript } from "../ultramodern-workspace/workspace-scripts.js";
13
14
  import { readUltramodernConfig, workspaceAppsFromToolingConfig } from "./config.js";
14
15
  const commands_dirname = node_path.dirname(fileURLToPath(import.meta.url));
@@ -188,6 +189,8 @@ const strictEffectPackageVersionPolicyExclusions = [
188
189
  `effect@${EFFECT_VERSION}`,
189
190
  `@effect/opentelemetry@${EFFECT_VERSION}`
190
191
  ];
192
+ const moduleFederationModernJsPatchPath = `patches/@module-federation__modern-js-v3@${MODULE_FEDERATION_VERSION}.patch`;
193
+ const moduleFederationModernJsPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', moduleFederationModernJsPatchPath);
191
194
  const effectDeclarationPatchPath = 'patches/effect-schema-error-type-id.patch';
192
195
  const effectDeclarationPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', effectDeclarationPatchPath);
193
196
  const drizzleOrmDeclarationPatchPath = 'patches/drizzle-orm-ts7-strict-declarations.patch';
@@ -219,9 +222,14 @@ function updateGeneratedPackageScripts(packageJson) {
219
222
  if (!scripts || 'object' != typeof scripts || Array.isArray(scripts)) return false;
220
223
  let changed = false;
221
224
  const cloudflareBuild = scripts['cloudflare:build'];
222
- if ('string' == typeof cloudflareBuild && cloudflareBuild.includes(cloudflareModernDeployCommand) && !cloudflareBuild.includes(cloudflareModernDeploySkipBuildCommand)) {
223
- scripts['cloudflare:build'] = cloudflareBuild.replace(cloudflareModernDeployCommand, cloudflareModernDeploySkipBuildCommand);
224
- changed = true;
225
+ if ('string' == typeof cloudflareBuild) {
226
+ let nextCloudflareBuild = cloudflareBuild;
227
+ if (nextCloudflareBuild.includes(cloudflareModernDeployCommand) && !nextCloudflareBuild.includes(cloudflareModernDeploySkipBuildCommand)) nextCloudflareBuild = nextCloudflareBuild.replace(cloudflareModernDeployCommand, cloudflareModernDeploySkipBuildCommand);
228
+ nextCloudflareBuild = nextCloudflareBuild.replace(/ && node \S*scripts\/generate-public-surface-assets\.m[ct]s --app [^&]+ --target dist(?= && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build)/u, '');
229
+ if (nextCloudflareBuild !== cloudflareBuild) {
230
+ scripts['cloudflare:build'] = nextCloudflareBuild;
231
+ changed = true;
232
+ }
225
233
  }
226
234
  const cloudflareDeploy = scripts['cloudflare:deploy'];
227
235
  if ('string' == typeof cloudflareDeploy && cloudflareDeploy.includes(cloudflareWranglerDeployInvalidSkipBuildCommand)) {
@@ -428,6 +436,7 @@ function workspaceUsesDependency(workspaceRoot, packageName) {
428
436
  }
429
437
  function ensureGeneratedDeclarationPatches(workspaceRoot, options) {
430
438
  let changed = false;
439
+ changed = ensureGeneratedPatchFile(workspaceRoot, moduleFederationModernJsPatchPath, moduleFederationModernJsPatchSourcePath) || changed;
431
440
  changed = ensureGeneratedPatchFile(workspaceRoot, effectDeclarationPatchPath, effectDeclarationPatchSourcePath) || changed;
432
441
  changed = options.includeDrizzleOrmPatch ? ensureGeneratedPatchFile(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed : removeGeneratedPatchFileIfUnchanged(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed;
433
442
  return changed;
@@ -475,6 +484,9 @@ function updateGeneratedPnpmWorkspacePolicy(workspaceRoot) {
475
484
  const effectPatch = ensureYamlMapEntry(source, 'patchedDependencies', `effect@${EFFECT_VERSION}`, effectDeclarationPatchPath);
476
485
  source = effectPatch.source;
477
486
  changed = effectPatch.changed || changed;
487
+ const moduleFederationModernJsPatch = ensureYamlMapEntry(source, 'patchedDependencies', `@module-federation/modern-js-v3@${MODULE_FEDERATION_VERSION}`, moduleFederationModernJsPatchPath);
488
+ source = moduleFederationModernJsPatch.source;
489
+ changed = moduleFederationModernJsPatch.changed || changed;
478
490
  const drizzleOrmPatch = usesDrizzleOrm ? ensureYamlMapEntry(source, 'patchedDependencies', `drizzle-orm@${DRIZZLE_ORM_VERSION}`, drizzleOrmDeclarationPatchPath) : removeYamlMapEntry(source, `drizzle-orm@${DRIZZLE_ORM_VERSION}`);
479
491
  source = drizzleOrmPatch.source;
480
492
  changed = drizzleOrmPatch.changed || changed;
@@ -524,7 +536,8 @@ function ensureGeneratedIgnoreRules(workspaceRoot) {
524
536
  let changed = false;
525
537
  for (const rule of [
526
538
  '.mf/',
527
- '**/.mf/'
539
+ '**/.mf/',
540
+ 'dist-cloudflare/'
528
541
  ])if (!lines.includes(rule)) {
529
542
  lines.push(rule);
530
543
  changed = true;
@@ -551,6 +564,12 @@ function updateGeneratedTypeScriptSurfaces(workspaceRoot, config) {
551
564
  }
552
565
  return changed;
553
566
  }
567
+ function updateGeneratedModernConfigs(workspaceRoot, config) {
568
+ let changed = false;
569
+ const apps = workspaceAppsFromToolingConfig(config);
570
+ for (const app of apps)changed = writeTextIfChanged(node_path.join(workspaceRoot, app.directory, 'modern.config.ts'), createAppModernConfig(config.workspace.packageScope, app)) || changed;
571
+ return changed;
572
+ }
554
573
  function updateReferenceTopology(workspaceRoot) {
555
574
  const topologyPath = node_path.join(workspaceRoot, 'topology/reference-topology.json');
556
575
  if (!node_fs.existsSync(topologyPath)) return false;
@@ -624,7 +643,9 @@ and pnpm contract:check.
624
643
  const packageSource = createMigrationPackageSource(args, current);
625
644
  updateUltramodernConfig(context.workspaceRoot, packageSource);
626
645
  updateReferenceTopology(context.workspaceRoot);
627
- updateGeneratedTypeScriptSurfaces(context.workspaceRoot, current);
646
+ const migrated = readUltramodernConfig(context.workspaceRoot);
647
+ updateGeneratedTypeScriptSurfaces(context.workspaceRoot, migrated);
648
+ updateGeneratedModernConfigs(context.workspaceRoot, migrated);
628
649
  for (const relativePackageFile of listWorkspacePackageFiles(context.workspaceRoot)){
629
650
  const packageFile = node_path.join(context.workspaceRoot, relativePackageFile);
630
651
  const packageJson = readJsonFile(packageFile);
@@ -93,8 +93,10 @@ ${defaultAssetPrefixSource}
93
93
  // load remoteEntry.js and exposed chunks from the remote origin, not the host.
94
94
  const assetPrefix =
95
95
  configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix;
96
- const buildCacheTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';
97
- const buildCacheDirectory = \`node_modules/.cache/rspack-\${appId}-\${buildCacheTarget}\`;
96
+ const buildTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';
97
+ const buildOutputRoot = cloudflareDeployEnabled ? 'dist-cloudflare' : 'dist';
98
+ const buildTempDirectory = \`node_modules/.modern-js-\${appId}-\${buildTarget}\`;
99
+ const buildCacheDirectory = \`node_modules/.cache/rspack-\${appId}-\${buildTarget}\`;
98
100
 
99
101
  if (
100
102
  cloudflareDeployEnabled &&
@@ -136,13 +138,15 @@ ${bffConfig} ...(cloudflareDeployEnabled
136
138
  disableTsChecker: false,
137
139
  distPath: {
138
140
  html: './',
141
+ root: buildOutputRoot,
139
142
  },
140
143
  polyfill: 'off',
141
144
  splitRouteChunks: true,
145
+ tempDir: buildTempDirectory,
142
146
  },
143
147
  performance: {
144
148
  buildCache: {
145
- cacheDigest: [appId, buildCacheTarget],
149
+ cacheDigest: [appId, buildTarget],
146
150
  cacheDirectory: buildCacheDirectory,
147
151
  },
148
152
  rsdoctor: {
@@ -356,7 +356,6 @@ function createRootTsConfig(apps = []) {
356
356
  }
357
357
  function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [], bridge) {
358
358
  const publicSurfaceBuildCommand = createPublicSurfaceGenerationCommand(app, 'dist');
359
- const publicSurfaceCloudflareBuildCommand = createPublicSurfaceGenerationCommand(app, 'dist');
360
359
  const publicSurfaceCloudflareOutputCommand = createPublicSurfaceGenerationCommand(app, 'cloudflare');
361
360
  const packageExports = Object.fromEntries(Object.entries(app.exposes ?? {}).map(([expose, source])=>[
362
361
  expose,
@@ -369,7 +368,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
369
368
  scripts: {
370
369
  dev: 'modern dev',
371
370
  build: app.exposes ? `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand} && node ${relativeRootFor(app.directory)}/scripts/assert-mf-types.mts` : `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand}`,
372
- 'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ${publicSurfaceCloudflareBuildCommand} && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build && ${publicSurfaceCloudflareOutputCommand}`,
371
+ 'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build && ${publicSurfaceCloudflareOutputCommand}`,
373
372
  'cloudflare:deploy': 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS=true pnpm run cloudflare:build && wrangler deploy --config .output/wrangler.json',
374
373
  'cloudflare:preview': 'pnpm run cloudflare:build && wrangler dev --config .output/wrangler.json',
375
374
  'cloudflare:proof': `node ${relativeRootFor(app.directory)}/scripts/proof-cloudflare-version.mts --app ${app.id}`,
@@ -8,7 +8,7 @@ import { packageName, tailwindPrefixForApp } from "./naming.js";
8
8
  import { createCloudflareSecurityContract } from "./policy.js";
9
9
  import { publicSurfaceManagedSourceAssetPaths } from "./public-surface.js";
10
10
  import { createLocalisedUrlsMap, createRouteMetaFilePath, createRouteOwnedI18nPaths, createRoutePageFilePath } from "./routes.js";
11
- import { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_VERSION, NODE_VERSION, PNPM_VERSION } from "./versions.js";
11
+ import { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_VERSION, MODULE_FEDERATION_VERSION, NODE_VERSION, PNPM_VERSION } from "./versions.js";
12
12
  function createToolWrapperScript(command, extraArgs = []) {
13
13
  const commandJson = JSON.stringify(command);
14
14
  const extraArgsJson = JSON.stringify(extraArgs);
@@ -128,6 +128,7 @@ function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
128
128
  return renderFileTemplate("workspace-scripts/validate-ultramodern-workspace.mjs", {
129
129
  packageScope: scope,
130
130
  effectVersion: EFFECT_VERSION,
131
+ moduleFederationVersion: MODULE_FEDERATION_VERSION,
131
132
  nodeVersion: NODE_VERSION,
132
133
  pnpmVersion: PNPM_VERSION,
133
134
  tailwindEnabledJson: JSON.stringify(enableTailwind),
@@ -14,7 +14,7 @@ import { runCodeSmithOverlays } from "./overlays.js";
14
14
  import { createAppMfTypesTsConfig, createAppPackage, createAppTsConfig, createRootPackageJson, createRootTsConfig, createSharedContractsIndex, createSharedPackage, createSharedPackageTsConfig, createTsConfigBase } from "./package-json.js";
15
15
  import { resolvePackageSource } from "./package-source.js";
16
16
  import { createPublicWebAppArtifacts } from "./public-surface.js";
17
- import { DRIZZLE_ORM_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_VERSION } from "./versions.js";
17
+ import { DRIZZLE_ORM_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, MODULE_FEDERATION_VERSION, NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_VERSION } from "./versions.js";
18
18
  import { writeGeneratedWorkspaceScripts } from "./workspace-scripts.js";
19
19
  function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = [], bridge) {
20
20
  const resolvedApp = 'shell' === app.kind ? createShellHost(remotes) : app;
@@ -133,6 +133,7 @@ function generateUltramodernWorkspace(options) {
133
133
  drizzleOrmVersion: DRIZZLE_ORM_VERSION,
134
134
  effectVersion: EFFECT_VERSION,
135
135
  effectVitestVersion: EFFECT_VITEST_VERSION,
136
+ moduleFederationVersion: MODULE_FEDERATION_VERSION,
136
137
  tanstackRouterCoreVersion: TANSTACK_ROUTER_CORE_VERSION,
137
138
  tanstackRouterVersion: TANSTACK_ROUTER_VERSION,
138
139
  typescriptVersion: TYPESCRIPT_VERSION,
@@ -8,8 +8,9 @@ import { resolveCreatePackageRoot } from "../create-package-root.js";
8
8
  import { BLEEDINGDEV_PACKAGE_NAME_PREFIX, BLEEDINGDEV_PACKAGE_SCOPE, ULTRAMODERN_SINGLE_APP_MODERN_PACKAGES, ULTRAMODERN_WORKSPACE_MODERN_PACKAGES, WORKSPACE_PACKAGE_VERSION, modernPackageSpecifier } from "../ultramodern-package-source.js";
9
9
  import { createAppEnvDts } from "../ultramodern-workspace/app-files.js";
10
10
  import { validateModuleFederationTypes } from "../ultramodern-workspace/mf-validation.js";
11
+ import { createAppModernConfig } from "../ultramodern-workspace/module-federation.js";
11
12
  import { createAppMfTypesTsConfig, createAppTsConfig, createSharedPackageTsConfig, createTsConfigBase } from "../ultramodern-workspace/package-json.js";
12
- import { DRIZZLE_ORM_VERSION, EFFECT_TSGO_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, OXFMT_VERSION, OXLINT_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION } from "../ultramodern-workspace/versions.js";
13
+ import { DRIZZLE_ORM_VERSION, EFFECT_TSGO_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, MODULE_FEDERATION_VERSION, OXFMT_VERSION, OXLINT_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION } from "../ultramodern-workspace/versions.js";
13
14
  import { createWorkspaceValidationScript } from "../ultramodern-workspace/workspace-scripts.js";
14
15
  import { readUltramodernConfig, workspaceAppsFromToolingConfig } from "./config.js";
15
16
  const commands_dirname = node_path.dirname(fileURLToPath(import.meta.url));
@@ -189,6 +190,8 @@ const strictEffectPackageVersionPolicyExclusions = [
189
190
  `effect@${EFFECT_VERSION}`,
190
191
  `@effect/opentelemetry@${EFFECT_VERSION}`
191
192
  ];
193
+ const moduleFederationModernJsPatchPath = `patches/@module-federation__modern-js-v3@${MODULE_FEDERATION_VERSION}.patch`;
194
+ const moduleFederationModernJsPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', moduleFederationModernJsPatchPath);
192
195
  const effectDeclarationPatchPath = 'patches/effect-schema-error-type-id.patch';
193
196
  const effectDeclarationPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', effectDeclarationPatchPath);
194
197
  const drizzleOrmDeclarationPatchPath = 'patches/drizzle-orm-ts7-strict-declarations.patch';
@@ -220,9 +223,14 @@ function updateGeneratedPackageScripts(packageJson) {
220
223
  if (!scripts || 'object' != typeof scripts || Array.isArray(scripts)) return false;
221
224
  let changed = false;
222
225
  const cloudflareBuild = scripts['cloudflare:build'];
223
- if ('string' == typeof cloudflareBuild && cloudflareBuild.includes(cloudflareModernDeployCommand) && !cloudflareBuild.includes(cloudflareModernDeploySkipBuildCommand)) {
224
- scripts['cloudflare:build'] = cloudflareBuild.replace(cloudflareModernDeployCommand, cloudflareModernDeploySkipBuildCommand);
225
- changed = true;
226
+ if ('string' == typeof cloudflareBuild) {
227
+ let nextCloudflareBuild = cloudflareBuild;
228
+ if (nextCloudflareBuild.includes(cloudflareModernDeployCommand) && !nextCloudflareBuild.includes(cloudflareModernDeploySkipBuildCommand)) nextCloudflareBuild = nextCloudflareBuild.replace(cloudflareModernDeployCommand, cloudflareModernDeploySkipBuildCommand);
229
+ nextCloudflareBuild = nextCloudflareBuild.replace(/ && node \S*scripts\/generate-public-surface-assets\.m[ct]s --app [^&]+ --target dist(?= && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build)/u, '');
230
+ if (nextCloudflareBuild !== cloudflareBuild) {
231
+ scripts['cloudflare:build'] = nextCloudflareBuild;
232
+ changed = true;
233
+ }
226
234
  }
227
235
  const cloudflareDeploy = scripts['cloudflare:deploy'];
228
236
  if ('string' == typeof cloudflareDeploy && cloudflareDeploy.includes(cloudflareWranglerDeployInvalidSkipBuildCommand)) {
@@ -429,6 +437,7 @@ function workspaceUsesDependency(workspaceRoot, packageName) {
429
437
  }
430
438
  function ensureGeneratedDeclarationPatches(workspaceRoot, options) {
431
439
  let changed = false;
440
+ changed = ensureGeneratedPatchFile(workspaceRoot, moduleFederationModernJsPatchPath, moduleFederationModernJsPatchSourcePath) || changed;
432
441
  changed = ensureGeneratedPatchFile(workspaceRoot, effectDeclarationPatchPath, effectDeclarationPatchSourcePath) || changed;
433
442
  changed = options.includeDrizzleOrmPatch ? ensureGeneratedPatchFile(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed : removeGeneratedPatchFileIfUnchanged(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed;
434
443
  return changed;
@@ -476,6 +485,9 @@ function updateGeneratedPnpmWorkspacePolicy(workspaceRoot) {
476
485
  const effectPatch = ensureYamlMapEntry(source, 'patchedDependencies', `effect@${EFFECT_VERSION}`, effectDeclarationPatchPath);
477
486
  source = effectPatch.source;
478
487
  changed = effectPatch.changed || changed;
488
+ const moduleFederationModernJsPatch = ensureYamlMapEntry(source, 'patchedDependencies', `@module-federation/modern-js-v3@${MODULE_FEDERATION_VERSION}`, moduleFederationModernJsPatchPath);
489
+ source = moduleFederationModernJsPatch.source;
490
+ changed = moduleFederationModernJsPatch.changed || changed;
479
491
  const drizzleOrmPatch = usesDrizzleOrm ? ensureYamlMapEntry(source, 'patchedDependencies', `drizzle-orm@${DRIZZLE_ORM_VERSION}`, drizzleOrmDeclarationPatchPath) : removeYamlMapEntry(source, `drizzle-orm@${DRIZZLE_ORM_VERSION}`);
480
492
  source = drizzleOrmPatch.source;
481
493
  changed = drizzleOrmPatch.changed || changed;
@@ -525,7 +537,8 @@ function ensureGeneratedIgnoreRules(workspaceRoot) {
525
537
  let changed = false;
526
538
  for (const rule of [
527
539
  '.mf/',
528
- '**/.mf/'
540
+ '**/.mf/',
541
+ 'dist-cloudflare/'
529
542
  ])if (!lines.includes(rule)) {
530
543
  lines.push(rule);
531
544
  changed = true;
@@ -552,6 +565,12 @@ function updateGeneratedTypeScriptSurfaces(workspaceRoot, config) {
552
565
  }
553
566
  return changed;
554
567
  }
568
+ function updateGeneratedModernConfigs(workspaceRoot, config) {
569
+ let changed = false;
570
+ const apps = workspaceAppsFromToolingConfig(config);
571
+ for (const app of apps)changed = writeTextIfChanged(node_path.join(workspaceRoot, app.directory, 'modern.config.ts'), createAppModernConfig(config.workspace.packageScope, app)) || changed;
572
+ return changed;
573
+ }
555
574
  function updateReferenceTopology(workspaceRoot) {
556
575
  const topologyPath = node_path.join(workspaceRoot, 'topology/reference-topology.json');
557
576
  if (!node_fs.existsSync(topologyPath)) return false;
@@ -625,7 +644,9 @@ and pnpm contract:check.
625
644
  const packageSource = createMigrationPackageSource(args, current);
626
645
  updateUltramodernConfig(context.workspaceRoot, packageSource);
627
646
  updateReferenceTopology(context.workspaceRoot);
628
- updateGeneratedTypeScriptSurfaces(context.workspaceRoot, current);
647
+ const migrated = readUltramodernConfig(context.workspaceRoot);
648
+ updateGeneratedTypeScriptSurfaces(context.workspaceRoot, migrated);
649
+ updateGeneratedModernConfigs(context.workspaceRoot, migrated);
629
650
  for (const relativePackageFile of listWorkspacePackageFiles(context.workspaceRoot)){
630
651
  const packageFile = node_path.join(context.workspaceRoot, relativePackageFile);
631
652
  const packageJson = readJsonFile(packageFile);
@@ -94,8 +94,10 @@ ${defaultAssetPrefixSource}
94
94
  // load remoteEntry.js and exposed chunks from the remote origin, not the host.
95
95
  const assetPrefix =
96
96
  configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix;
97
- const buildCacheTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';
98
- const buildCacheDirectory = \`node_modules/.cache/rspack-\${appId}-\${buildCacheTarget}\`;
97
+ const buildTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';
98
+ const buildOutputRoot = cloudflareDeployEnabled ? 'dist-cloudflare' : 'dist';
99
+ const buildTempDirectory = \`node_modules/.modern-js-\${appId}-\${buildTarget}\`;
100
+ const buildCacheDirectory = \`node_modules/.cache/rspack-\${appId}-\${buildTarget}\`;
99
101
 
100
102
  if (
101
103
  cloudflareDeployEnabled &&
@@ -137,13 +139,15 @@ ${bffConfig} ...(cloudflareDeployEnabled
137
139
  disableTsChecker: false,
138
140
  distPath: {
139
141
  html: './',
142
+ root: buildOutputRoot,
140
143
  },
141
144
  polyfill: 'off',
142
145
  splitRouteChunks: true,
146
+ tempDir: buildTempDirectory,
143
147
  },
144
148
  performance: {
145
149
  buildCache: {
146
- cacheDigest: [appId, buildCacheTarget],
150
+ cacheDigest: [appId, buildTarget],
147
151
  cacheDirectory: buildCacheDirectory,
148
152
  },
149
153
  rsdoctor: {
@@ -357,7 +357,6 @@ function createRootTsConfig(apps = []) {
357
357
  }
358
358
  function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [], bridge) {
359
359
  const publicSurfaceBuildCommand = createPublicSurfaceGenerationCommand(app, 'dist');
360
- const publicSurfaceCloudflareBuildCommand = createPublicSurfaceGenerationCommand(app, 'dist');
361
360
  const publicSurfaceCloudflareOutputCommand = createPublicSurfaceGenerationCommand(app, 'cloudflare');
362
361
  const packageExports = Object.fromEntries(Object.entries(app.exposes ?? {}).map(([expose, source])=>[
363
362
  expose,
@@ -370,7 +369,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
370
369
  scripts: {
371
370
  dev: 'modern dev',
372
371
  build: app.exposes ? `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand} && node ${relativeRootFor(app.directory)}/scripts/assert-mf-types.mts` : `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand}`,
373
- 'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ${publicSurfaceCloudflareBuildCommand} && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build && ${publicSurfaceCloudflareOutputCommand}`,
372
+ 'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build && ${publicSurfaceCloudflareOutputCommand}`,
374
373
  'cloudflare:deploy': 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS=true pnpm run cloudflare:build && wrangler deploy --config .output/wrangler.json',
375
374
  'cloudflare:preview': 'pnpm run cloudflare:build && wrangler dev --config .output/wrangler.json',
376
375
  'cloudflare:proof': `node ${relativeRootFor(app.directory)}/scripts/proof-cloudflare-version.mts --app ${app.id}`,
@@ -9,7 +9,7 @@ import { packageName, tailwindPrefixForApp } from "./naming.js";
9
9
  import { createCloudflareSecurityContract } from "./policy.js";
10
10
  import { publicSurfaceManagedSourceAssetPaths } from "./public-surface.js";
11
11
  import { createLocalisedUrlsMap, createRouteMetaFilePath, createRouteOwnedI18nPaths, createRoutePageFilePath } from "./routes.js";
12
- import { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_VERSION, NODE_VERSION, PNPM_VERSION } from "./versions.js";
12
+ import { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_VERSION, MODULE_FEDERATION_VERSION, NODE_VERSION, PNPM_VERSION } from "./versions.js";
13
13
  function createToolWrapperScript(command, extraArgs = []) {
14
14
  const commandJson = JSON.stringify(command);
15
15
  const extraArgsJson = JSON.stringify(extraArgs);
@@ -129,6 +129,7 @@ function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
129
129
  return renderFileTemplate("workspace-scripts/validate-ultramodern-workspace.mjs", {
130
130
  packageScope: scope,
131
131
  effectVersion: EFFECT_VERSION,
132
+ moduleFederationVersion: MODULE_FEDERATION_VERSION,
132
133
  nodeVersion: NODE_VERSION,
133
134
  pnpmVersion: PNPM_VERSION,
134
135
  tailwindEnabledJson: JSON.stringify(enableTailwind),
@@ -15,7 +15,7 @@ import { runCodeSmithOverlays } from "./overlays.js";
15
15
  import { createAppMfTypesTsConfig, createAppPackage, createAppTsConfig, createRootPackageJson, createRootTsConfig, createSharedContractsIndex, createSharedPackage, createSharedPackageTsConfig, createTsConfigBase } from "./package-json.js";
16
16
  import { resolvePackageSource } from "./package-source.js";
17
17
  import { createPublicWebAppArtifacts } from "./public-surface.js";
18
- import { DRIZZLE_ORM_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_VERSION } from "./versions.js";
18
+ import { DRIZZLE_ORM_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, MODULE_FEDERATION_VERSION, NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_VERSION } from "./versions.js";
19
19
  import { writeGeneratedWorkspaceScripts } from "./workspace-scripts.js";
20
20
  function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = [], bridge) {
21
21
  const resolvedApp = 'shell' === app.kind ? createShellHost(remotes) : app;
@@ -134,6 +134,7 @@ function generateUltramodernWorkspace(options) {
134
134
  drizzleOrmVersion: DRIZZLE_ORM_VERSION,
135
135
  effectVersion: EFFECT_VERSION,
136
136
  effectVitestVersion: EFFECT_VITEST_VERSION,
137
+ moduleFederationVersion: MODULE_FEDERATION_VERSION,
137
138
  tanstackRouterCoreVersion: TANSTACK_ROUTER_CORE_VERSION,
138
139
  tanstackRouterVersion: TANSTACK_ROUTER_VERSION,
139
140
  typescriptVersion: TYPESCRIPT_VERSION,
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "engines": {
22
22
  "node": ">=20"
23
23
  },
24
- "version": "3.5.0-ultramodern.12",
24
+ "version": "3.5.0-ultramodern.14",
25
25
  "types": "./dist/types/index.d.ts",
26
26
  "main": "./dist/esm-node/index.js",
27
27
  "bin": {
@@ -77,7 +77,7 @@
77
77
  "@modern-js/codesmith": "2.6.9",
78
78
  "oxfmt": "0.56.0",
79
79
  "ultracite": "7.8.3",
80
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.5.0-ultramodern.12"
80
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.5.0-ultramodern.14"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@rslib/core": "0.23.1",
@@ -99,6 +99,6 @@
99
99
  "test": "rm -rf dist && rslib build -c rslibconfig.mts && rstest --passWithNoTests"
100
100
  },
101
101
  "ultramodern": {
102
- "frameworkVersion": "3.5.0-ultramodern.12"
102
+ "frameworkVersion": "3.5.0-ultramodern.14"
103
103
  }
104
104
  }
@@ -1,5 +1,6 @@
1
1
  node_modules/
2
2
  dist/
3
+ dist-cloudflare/
3
4
  build/
4
5
  .modernjs/cache/
5
6
  .modern-js/
@@ -0,0 +1,57 @@
1
+ diff --git a/dist/cjs/cli/configPlugin.js b/dist/cjs/cli/configPlugin.js
2
+ index 0d01ad0..e5485a2 100644
3
+ --- a/dist/cjs/cli/configPlugin.js
4
+ +++ b/dist/cjs/cli/configPlugin.js
5
+ @@ -212,9 +212,12 @@ var __webpack_exports__ = {};
6
+ if (!chain.output.get('uniqueName')) chain.output.uniqueName(mfConfig.name);
7
+ const splitChunkConfig = chain.optimization.splitChunks.entries();
8
+ if (!isServer) (0, utils_namespaceObject.autoDeleteSplitChunkCacheGroups)(mfConfig, splitChunkConfig);
9
+ - if (!isServer && enableSSR && splitChunkConfig && 'object' == typeof splitChunkConfig && splitChunkConfig.cacheGroups) {
10
+ + if (!isServer && enableSSR && splitChunkConfig && 'object' == typeof splitChunkConfig && splitChunkConfig.cacheGroups && splitChunkConfig.chunks !== undefined && splitChunkConfig.chunks !== 'async') {
11
+ + const previousChunks = splitChunkConfig.chunks;
12
+ splitChunkConfig.chunks = 'async';
13
+ - external_logger_js_default().warn('splitChunks.chunks = async is not allowed with stream SSR mode, it will auto changed to "async"');
14
+ + if (void 0 !== previousChunks) {
15
+ + external_logger_js_default().warn(`splitChunks.chunks = ${previousChunks} is not allowed with stream SSR mode, it will auto changed to "async"`);
16
+ + }
17
+ }
18
+ if ((0, external_utils_js_namespaceObject.isDev)() && 'auto' === chain.output.get('publicPath')) {
19
+ var _modernjsConfig_server;
20
+ diff --git a/dist/esm/cli/configPlugin.mjs b/dist/esm/cli/configPlugin.mjs
21
+ index 3e880c8..93e4290 100644
22
+ --- a/dist/esm/cli/configPlugin.mjs
23
+ +++ b/dist/esm/cli/configPlugin.mjs
24
+ @@ -194,9 +194,12 @@ function patchBundlerConfig(options) {
25
+ if (!chain.output.get('uniqueName')) chain.output.uniqueName(mfConfig.name);
26
+ var splitChunkConfig = chain.optimization.splitChunks.entries();
27
+ if (!isServer) autoDeleteSplitChunkCacheGroups(mfConfig, splitChunkConfig);
28
+ - if (!isServer && enableSSR && splitChunkConfig && (void 0 === splitChunkConfig ? "undefined" : _type_of__(splitChunkConfig)) === 'object' && splitChunkConfig.cacheGroups) {
29
+ + if (!isServer && enableSSR && splitChunkConfig && (void 0 === splitChunkConfig ? "undefined" : _type_of__(splitChunkConfig)) === 'object' && splitChunkConfig.cacheGroups && void 0 !== splitChunkConfig.chunks && splitChunkConfig.chunks !== 'async') {
30
+ + var previousChunks = splitChunkConfig.chunks;
31
+ splitChunkConfig.chunks = 'async';
32
+ - logger.warn('splitChunks.chunks = async is not allowed with stream SSR mode, it will auto changed to "async"');
33
+ + if (void 0 !== previousChunks) {
34
+ + logger.warn("splitChunks.chunks = ".concat(previousChunks, " is not allowed with stream SSR mode, it will auto changed to \"async\""));
35
+ + }
36
+ }
37
+ if (isDev() && 'auto' === chain.output.get('publicPath')) {
38
+ var _modernjsConfig_server;
39
+ diff --git a/dist/esm-node/cli/configPlugin.mjs b/dist/esm-node/cli/configPlugin.mjs
40
+ index 722f1bb..dcac7ec 100644
41
+ --- a/dist/esm-node/cli/configPlugin.mjs
42
+ +++ b/dist/esm-node/cli/configPlugin.mjs
43
+ @@ -165,9 +165,12 @@ function patchBundlerConfig(options) {
44
+ if (!chain.output.get('uniqueName')) chain.output.uniqueName(mfConfig.name);
45
+ const splitChunkConfig = chain.optimization.splitChunks.entries();
46
+ if (!isServer) autoDeleteSplitChunkCacheGroups(mfConfig, splitChunkConfig);
47
+ - if (!isServer && enableSSR && splitChunkConfig && 'object' == typeof splitChunkConfig && splitChunkConfig.cacheGroups) {
48
+ + if (!isServer && enableSSR && splitChunkConfig && 'object' == typeof splitChunkConfig && splitChunkConfig.cacheGroups && splitChunkConfig.chunks !== undefined && splitChunkConfig.chunks !== 'async') {
49
+ + const previousChunks = splitChunkConfig.chunks;
50
+ splitChunkConfig.chunks = 'async';
51
+ - logger.warn('splitChunks.chunks = async is not allowed with stream SSR mode, it will auto changed to "async"');
52
+ + if (void 0 !== previousChunks) {
53
+ + logger.warn(`splitChunks.chunks = ${previousChunks} is not allowed with stream SSR mode, it will auto changed to "async"`);
54
+ + }
55
+ }
56
+ if (isDev() && 'auto' === chain.output.get('publicPath')) {
57
+ var _modernjsConfig_server;
@@ -62,5 +62,6 @@ allowBuilds:
62
62
  workerd: true
63
63
 
64
64
  patchedDependencies:
65
+ '@module-federation/modern-js-v3@{{moduleFederationVersion}}': patches/@module-federation__modern-js-v3@{{moduleFederationVersion}}.patch
65
66
  '@tanstack/router-core@{{tanstackRouterCoreVersion}}': patches/@tanstack__router-core@{{tanstackRouterCoreVersion}}.patch
66
67
  'effect@{{effectVersion}}': patches/effect-schema-error-type-id.patch
@@ -1363,12 +1363,17 @@ const extractAssetPrefixExpression = modernConfig => {
1363
1363
  assert(match?.groups?.expression, 'modern.config.ts must assign assetPrefix');
1364
1364
  return match.groups.expression;
1365
1365
  };
1366
- const assertBuildCacheBase = (appId, modernConfig) => {
1366
+ const assertTargetIsolatedBuildArtifacts = (appId, modernConfig) => {
1367
1367
  assert(
1368
- modernConfig.includes("const buildCacheTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';") &&
1369
- modernConfig.includes('const buildCacheDirectory = `node_modules/.cache/rspack-${appId}-${buildCacheTarget}`;') &&
1368
+ modernConfig.includes("const buildTarget = cloudflareDeployEnabled ? 'cloudflare' : 'web';") &&
1369
+ modernConfig.includes("const buildOutputRoot = cloudflareDeployEnabled ? 'dist-cloudflare' : 'dist';") &&
1370
+ modernConfig.includes('const buildTempDirectory = `node_modules/.modern-js-${appId}-${buildTarget}`;') &&
1371
+ modernConfig.includes('const buildCacheDirectory = `node_modules/.cache/rspack-${appId}-${buildTarget}`;') &&
1372
+ modernConfig.includes('root: buildOutputRoot,') &&
1373
+ modernConfig.includes('tempDir: buildTempDirectory,') &&
1374
+ modernConfig.includes('cacheDigest: [appId, buildTarget],') &&
1370
1375
  modernConfig.includes('cacheDirectory: buildCacheDirectory,'),
1371
- `${appId} must provide a per-app/per-target Rspack cache base directory`,
1376
+ `${appId} must isolate build output, Modern temp files, and Rspack cache by app and build target`,
1372
1377
  );
1373
1378
  };
1374
1379
  const assertCloudflareBuildSkipsDeployRebuild = (appId, packageJson) => {
@@ -1378,6 +1383,12 @@ const assertCloudflareBuildSkipsDeployRebuild = (appId, packageJson) => {
1378
1383
  ),
1379
1384
  `${appId} cloudflare:build must deploy with --skip-build after the explicit Cloudflare build`,
1380
1385
  );
1386
+ assert(
1387
+ !packageJson.scripts?.['cloudflare:build']?.includes(
1388
+ '--target dist && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy',
1389
+ ),
1390
+ `${appId} cloudflare:build must not write public-surface assets into the normal web dist before deploy`,
1391
+ );
1381
1392
  };
1382
1393
  const stripYamlInlineComment = value => {
1383
1394
  let quote = undefined;
@@ -1492,6 +1503,7 @@ const requiredPaths = [
1492
1503
  '.gitignore',
1493
1504
  'package.json',
1494
1505
  'pnpm-workspace.yaml',
1506
+ 'patches/@module-federation__modern-js-v3@{{moduleFederationVersion}}.patch',
1495
1507
  'patches/effect-schema-error-type-id.patch',
1496
1508
  'tsconfig.json',
1497
1509
  'tsconfig.base.json',
@@ -1569,6 +1581,12 @@ for (const requiredPath of requiredPaths) {
1569
1581
  assertExists(requiredPath);
1570
1582
  }
1571
1583
  const pnpmWorkspace = readText('pnpm-workspace.yaml');
1584
+ assert(
1585
+ pnpmWorkspace.includes(
1586
+ "'@module-federation/modern-js-v3@{{moduleFederationVersion}}': patches/@module-federation__modern-js-v3@{{moduleFederationVersion}}.patch",
1587
+ ),
1588
+ 'pnpm-workspace.yaml must patch the generated Module Federation Modern.js integration cohort',
1589
+ );
1572
1590
  assert(
1573
1591
  pnpmWorkspace.includes(
1574
1592
  "'effect@{{effectVersion}}': patches/effect-schema-error-type-id.patch",
@@ -1795,6 +1813,7 @@ const shellRouteHead = readText('apps/shell-super-app/src/routes/ultramodern-rou
1795
1813
  const shellRouteMetadata = readText('apps/shell-super-app/src/routes/ultramodern-route-metadata.ts');
1796
1814
  assert(/^\.mf\/$/mu.test(gitignore), 'Generated .gitignore must ignore root Module Federation diagnostics');
1797
1815
  assert(/^\*\*\/\.mf\/$/mu.test(gitignore), 'Generated .gitignore must ignore per-app Module Federation diagnostics');
1816
+ assert(/^dist-cloudflare\/$/mu.test(gitignore), 'Generated .gitignore must ignore Cloudflare build output');
1798
1817
  assert(shellModernAppEnv.includes("import '@modern-js/app-tools/types';"), 'Shell app env must import the framework-owned app ambient type bundle through module resolution');
1799
1818
  assert(/declare global \{\s*const ULTRAMODERN_SITE_URL: string;\s*\}/u.test(shellModernAppEnv), 'Shell app env must keep generated globals explicit after importing app ambient types');
1800
1819
  assert(!shellModernAppEnv.includes("declare module '*.svg'"), 'Shell app env must not redeclare framework-owned svg asset modules');
@@ -1818,7 +1837,7 @@ assert(shellPackage.dependencies?.['@modern-js/plugin-i18n'] === expectedModernP
1818
1837
  assert(shellPackage.dependencies?.['@modern-js/plugin-tanstack'] === expectedModernPackageSpecifier('@modern-js/plugin-tanstack'), 'Shell plugin-tanstack dependency must match package source metadata');
1819
1838
  assert(shellPackage.dependencies?.['@modern-js/runtime'] === expectedModernPackageSpecifier('@modern-js/runtime'), 'Shell runtime dependency must match package source metadata');
1820
1839
  assert(shellPackage.scripts?.['cloudflare:deploy'] === 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS=true pnpm run cloudflare:build && wrangler deploy --config .output/wrangler.json', 'Shell must expose cloudflare:deploy');
1821
- assertBuildCacheBase('shell-super-app', shellModernConfig);
1840
+ assertTargetIsolatedBuildArtifacts('shell-super-app', shellModernConfig);
1822
1841
  assertCloudflareBuildSkipsDeployRebuild('shell-super-app', shellPackage);
1823
1842
  const shellContract = generatedContract.apps?.find(app => app.id === 'shell-super-app');
1824
1843
  assert(shellContract?.deploy?.cloudflare?.workerName === expectedWorkerName('shell-super-app'), 'Shell Cloudflare workerName is incorrect');
@@ -1901,7 +1920,7 @@ for (const vertical of fullStackVerticals) {
1901
1920
  assert(routeMetadata.includes("authoring: 'colocated-route-meta'"), `${vertical.id} route metadata manifest must advertise colocated authoring`);
1902
1921
  assert(packageJson.name === vertical.packageName, `${vertical.id} package name is incorrect`);
1903
1922
  assert(packageJson.scripts?.['cloudflare:deploy'] === 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS=true pnpm run cloudflare:build && wrangler deploy --config .output/wrangler.json', `${vertical.id} must expose cloudflare:deploy`);
1904
- assertBuildCacheBase(vertical.id, modernConfig);
1923
+ assertTargetIsolatedBuildArtifacts(vertical.id, modernConfig);
1905
1924
  assertCloudflareBuildSkipsDeployRebuild(vertical.id, packageJson);
1906
1925
  assert(packageJson.scripts?.['cloudflare:proof']?.includes(`--app ${vertical.id}`), `${vertical.id} must expose cloudflare:proof`);
1907
1926
  assert(packageJson.devDependencies?.['@modern-js/app-tools'] === expectedModernPackageSpecifier('@modern-js/app-tools'), `${vertical.id} app-tools dependency must match package source metadata`);