@bleedingdev/modern-js-ultramodern-app-tools 3.9.3-ultramodern.4 → 3.9.3-ultramodern.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -142,7 +142,9 @@ export default defineConfig(
142
142
  The workspace preset reads `topology/reference-topology.json` and
143
143
  `topology/local-overlays/development.json` relative to that config. Those records
144
144
  provide app identity, renderer, development ports, composed remote references
145
- and delivery unit identity. An authored `renderer` must match the topology.
145
+ and delivery unit identity. An authored `renderer` must match the topology. A
146
+ headless (API-only) unit declares renderer `none` and no Module Federation
147
+ name; its config selects no `renderer`.
146
148
  Adding a shell or vertical changes the records; existing application configs
147
149
  keep their authored contents.
148
150
 
@@ -50,8 +50,11 @@ function createRendererBuildIdentityResolver(renderer) {
50
50
  mode: context.mode ?? ('production' === process.env.NODE_ENV ? 'production' : 'development'),
51
51
  ...delivery ? {
52
52
  appId: delivery.appId,
53
- unitId: delivery.unitId,
54
- sourceRevision: delivery.sourceRevision
53
+ deliveryUnit: {
54
+ unitId: delivery.unitId,
55
+ buildMarker: delivery.buildMarker,
56
+ sourceRevision: delivery.sourceRevision
57
+ }
55
58
  } : {
56
59
  appId: context.packageName || void 0
57
60
  }
@@ -196,7 +196,8 @@ const resolveWorkspaceConfig = (config, options)=>{
196
196
  if (app.package !== packageManifest.name || app.deliveryUnit?.packageName !== packageManifest.name) throw new Error(`[ultramodern-workspace] Package identity for ${options.appId} does not match topology.`);
197
197
  if (app.deliveryUnit?.version !== packageManifest.version) throw new Error(`[ultramodern-workspace] Delivery unit version for ${options.appId} does not match package.json.`);
198
198
  const declaredRenderer = app.renderer;
199
- if (void 0 !== declaredRenderer && void 0 !== config.renderer && config.renderer !== declaredRenderer) throw new Error(`[ultramodern-workspace] Renderer for ${options.appId} does not match topology.`);
199
+ const headless = 'api-only' === app.surfaceProfile || 'none' === declaredRenderer;
200
+ if (headless && void 0 !== config.renderer || void 0 !== declaredRenderer && void 0 !== config.renderer && config.renderer !== declaredRenderer) throw new Error(`[ultramodern-workspace] Renderer for ${options.appId} does not match topology${headless ? ': a headless unit selects no renderer' : ''}.`);
200
201
  const portEnv = portEnvironment(app);
201
202
  const port = developmentPort(environment[portEnv] ?? overlay.ports[options.appId], options.appId);
202
203
  const allowedOrigins = Object.entries(overlay.ports).map(([id, defaultPort])=>{
@@ -243,9 +244,9 @@ const resolveWorkspaceConfig = (config, options)=>{
243
244
  binding
244
245
  ] : [];
245
246
  });
246
- const mfName = requiredString(app.moduleFederation?.name, `${options.appId}.moduleFederation.name`);
247
+ const mfName = headless ? void 0 : requiredString(app.moduleFederation?.name, `${options.appId}.moduleFederation.name`);
247
248
  const workspaceConfig = {
248
- ...void 0 !== declaredRenderer ? {
249
+ ...!headless && void 0 !== declaredRenderer ? {
249
250
  renderer: declaredRenderer
250
251
  } : {},
251
252
  ...cloudflare ? {
@@ -301,7 +302,7 @@ const resolveWorkspaceConfig = (config, options)=>{
301
302
  ...dynamicRemotes.size > 0 ? [
302
303
  dynamicCloudflareServicesPlugin(referencedRemotes, dynamicRemotes, workspaceRoot, environment, services)
303
304
  ] : [],
304
- ...'api-only' === app.surfaceProfile ? [] : [
305
+ ...headless ? [] : [
305
306
  zephyrBuildPlugin(configFilename, environment)
306
307
  ]
307
308
  ],
@@ -327,9 +328,11 @@ const resolveWorkspaceConfig = (config, options)=>{
327
328
  'defaults'
328
329
  ]
329
330
  },
330
- bundlerChain: (chain)=>{
331
- chain.output.uniqueName(mfName).chunkLoadingGlobal(`__ULTRAMODERN_${envSegment(mfName)}_LOADED_CHUNKS__`);
332
- },
331
+ ...mfName ? {
332
+ bundlerChain: (chain)=>{
333
+ chain.output.uniqueName(mfName).chunkLoadingGlobal(`__ULTRAMODERN_${envSegment(mfName)}_LOADED_CHUNKS__`);
334
+ }
335
+ } : {},
333
336
  devServer: {
334
337
  headers: {
335
338
  'Access-Control-Allow-Headers': 'Accept, Authorization, Content-Type, X-Requested-With',
@@ -18,8 +18,11 @@ function createRendererBuildIdentityResolver(renderer) {
18
18
  mode: context.mode ?? ('production' === process.env.NODE_ENV ? 'production' : 'development'),
19
19
  ...delivery ? {
20
20
  appId: delivery.appId,
21
- unitId: delivery.unitId,
22
- sourceRevision: delivery.sourceRevision
21
+ deliveryUnit: {
22
+ unitId: delivery.unitId,
23
+ buildMarker: delivery.buildMarker,
24
+ sourceRevision: delivery.sourceRevision
25
+ }
23
26
  } : {
24
27
  appId: context.packageName || void 0
25
28
  }
@@ -153,7 +153,8 @@ const resolveWorkspaceConfig = (config, options)=>{
153
153
  if (app.package !== packageManifest.name || app.deliveryUnit?.packageName !== packageManifest.name) throw new Error(`[ultramodern-workspace] Package identity for ${options.appId} does not match topology.`);
154
154
  if (app.deliveryUnit?.version !== packageManifest.version) throw new Error(`[ultramodern-workspace] Delivery unit version for ${options.appId} does not match package.json.`);
155
155
  const declaredRenderer = app.renderer;
156
- if (void 0 !== declaredRenderer && void 0 !== config.renderer && config.renderer !== declaredRenderer) throw new Error(`[ultramodern-workspace] Renderer for ${options.appId} does not match topology.`);
156
+ const headless = 'api-only' === app.surfaceProfile || 'none' === declaredRenderer;
157
+ if (headless && void 0 !== config.renderer || void 0 !== declaredRenderer && void 0 !== config.renderer && config.renderer !== declaredRenderer) throw new Error(`[ultramodern-workspace] Renderer for ${options.appId} does not match topology${headless ? ': a headless unit selects no renderer' : ''}.`);
157
158
  const portEnv = portEnvironment(app);
158
159
  const port = developmentPort(environment[portEnv] ?? overlay.ports[options.appId], options.appId);
159
160
  const allowedOrigins = Object.entries(overlay.ports).map(([id, defaultPort])=>{
@@ -200,9 +201,9 @@ const resolveWorkspaceConfig = (config, options)=>{
200
201
  binding
201
202
  ] : [];
202
203
  });
203
- const mfName = requiredString(app.moduleFederation?.name, `${options.appId}.moduleFederation.name`);
204
+ const mfName = headless ? void 0 : requiredString(app.moduleFederation?.name, `${options.appId}.moduleFederation.name`);
204
205
  const workspaceConfig = {
205
- ...void 0 !== declaredRenderer ? {
206
+ ...!headless && void 0 !== declaredRenderer ? {
206
207
  renderer: declaredRenderer
207
208
  } : {},
208
209
  ...cloudflare ? {
@@ -258,7 +259,7 @@ const resolveWorkspaceConfig = (config, options)=>{
258
259
  ...dynamicRemotes.size > 0 ? [
259
260
  dynamicCloudflareServicesPlugin(referencedRemotes, dynamicRemotes, workspaceRoot, environment, services)
260
261
  ] : [],
261
- ...'api-only' === app.surfaceProfile ? [] : [
262
+ ...headless ? [] : [
262
263
  zephyrBuildPlugin(configFilename, environment)
263
264
  ]
264
265
  ],
@@ -284,9 +285,11 @@ const resolveWorkspaceConfig = (config, options)=>{
284
285
  'defaults'
285
286
  ]
286
287
  },
287
- bundlerChain: (chain)=>{
288
- chain.output.uniqueName(mfName).chunkLoadingGlobal(`__ULTRAMODERN_${envSegment(mfName)}_LOADED_CHUNKS__`);
289
- },
288
+ ...mfName ? {
289
+ bundlerChain: (chain)=>{
290
+ chain.output.uniqueName(mfName).chunkLoadingGlobal(`__ULTRAMODERN_${envSegment(mfName)}_LOADED_CHUNKS__`);
291
+ }
292
+ } : {},
290
293
  devServer: {
291
294
  headers: {
292
295
  'Access-Control-Allow-Headers': 'Accept, Authorization, Content-Type, X-Requested-With',
@@ -19,8 +19,11 @@ function createRendererBuildIdentityResolver(renderer) {
19
19
  mode: context.mode ?? ('production' === process.env.NODE_ENV ? 'production' : 'development'),
20
20
  ...delivery ? {
21
21
  appId: delivery.appId,
22
- unitId: delivery.unitId,
23
- sourceRevision: delivery.sourceRevision
22
+ deliveryUnit: {
23
+ unitId: delivery.unitId,
24
+ buildMarker: delivery.buildMarker,
25
+ sourceRevision: delivery.sourceRevision
26
+ }
24
27
  } : {
25
28
  appId: context.packageName || void 0
26
29
  }
@@ -154,7 +154,8 @@ const resolveWorkspaceConfig = (config, options)=>{
154
154
  if (app.package !== packageManifest.name || app.deliveryUnit?.packageName !== packageManifest.name) throw new Error(`[ultramodern-workspace] Package identity for ${options.appId} does not match topology.`);
155
155
  if (app.deliveryUnit?.version !== packageManifest.version) throw new Error(`[ultramodern-workspace] Delivery unit version for ${options.appId} does not match package.json.`);
156
156
  const declaredRenderer = app.renderer;
157
- if (void 0 !== declaredRenderer && void 0 !== config.renderer && config.renderer !== declaredRenderer) throw new Error(`[ultramodern-workspace] Renderer for ${options.appId} does not match topology.`);
157
+ const headless = 'api-only' === app.surfaceProfile || 'none' === declaredRenderer;
158
+ if (headless && void 0 !== config.renderer || void 0 !== declaredRenderer && void 0 !== config.renderer && config.renderer !== declaredRenderer) throw new Error(`[ultramodern-workspace] Renderer for ${options.appId} does not match topology${headless ? ': a headless unit selects no renderer' : ''}.`);
158
159
  const portEnv = portEnvironment(app);
159
160
  const port = developmentPort(environment[portEnv] ?? overlay.ports[options.appId], options.appId);
160
161
  const allowedOrigins = Object.entries(overlay.ports).map(([id, defaultPort])=>{
@@ -201,9 +202,9 @@ const resolveWorkspaceConfig = (config, options)=>{
201
202
  binding
202
203
  ] : [];
203
204
  });
204
- const mfName = requiredString(app.moduleFederation?.name, `${options.appId}.moduleFederation.name`);
205
+ const mfName = headless ? void 0 : requiredString(app.moduleFederation?.name, `${options.appId}.moduleFederation.name`);
205
206
  const workspaceConfig = {
206
- ...void 0 !== declaredRenderer ? {
207
+ ...!headless && void 0 !== declaredRenderer ? {
207
208
  renderer: declaredRenderer
208
209
  } : {},
209
210
  ...cloudflare ? {
@@ -259,7 +260,7 @@ const resolveWorkspaceConfig = (config, options)=>{
259
260
  ...dynamicRemotes.size > 0 ? [
260
261
  dynamicCloudflareServicesPlugin(referencedRemotes, dynamicRemotes, workspaceRoot, environment, services)
261
262
  ] : [],
262
- ...'api-only' === app.surfaceProfile ? [] : [
263
+ ...headless ? [] : [
263
264
  zephyrBuildPlugin(configFilename, environment)
264
265
  ]
265
266
  ],
@@ -285,9 +286,11 @@ const resolveWorkspaceConfig = (config, options)=>{
285
286
  'defaults'
286
287
  ]
287
288
  },
288
- bundlerChain: (chain)=>{
289
- chain.output.uniqueName(mfName).chunkLoadingGlobal(`__ULTRAMODERN_${envSegment(mfName)}_LOADED_CHUNKS__`);
290
- },
289
+ ...mfName ? {
290
+ bundlerChain: (chain)=>{
291
+ chain.output.uniqueName(mfName).chunkLoadingGlobal(`__ULTRAMODERN_${envSegment(mfName)}_LOADED_CHUNKS__`);
292
+ }
293
+ } : {},
291
294
  devServer: {
292
295
  headers: {
293
296
  'Access-Control-Allow-Headers': 'Accept, Authorization, Content-Type, X-Requested-With',
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "directory": "packages/solutions/ultramodern-app-tools"
12
12
  },
13
13
  "license": "MIT",
14
- "version": "3.9.3-ultramodern.4",
14
+ "version": "3.9.3-ultramodern.5",
15
15
  "files": [
16
16
  "dist",
17
17
  "src",
@@ -149,35 +149,35 @@
149
149
  "node": ">=26.10.0"
150
150
  },
151
151
  "dependencies": {
152
- "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.3-ultramodern.4",
153
- "@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.3-ultramodern.4",
154
- "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.3-ultramodern.4",
155
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.3-ultramodern.4",
156
- "@modern-js/federation-runtime": "npm:@bleedingdev/modern-js-federation-runtime@3.9.3-ultramodern.4",
157
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.3-ultramodern.4",
158
- "@modern-js/plugin-bff-build-extensions": "npm:@bleedingdev/modern-js-plugin-bff-build-extensions@3.9.3-ultramodern.4",
159
- "@modern-js/renderer-core": "npm:@bleedingdev/modern-js-renderer-core@3.9.3-ultramodern.4",
160
- "@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.3-ultramodern.4",
161
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.3-ultramodern.4",
162
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.3-ultramodern.4",
163
- "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.3-ultramodern.4",
164
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.4",
165
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.4",
152
+ "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.3-ultramodern.5",
153
+ "@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.3-ultramodern.5",
154
+ "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.3-ultramodern.5",
155
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.3-ultramodern.5",
156
+ "@modern-js/federation-runtime": "npm:@bleedingdev/modern-js-federation-runtime@3.9.3-ultramodern.5",
157
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.3-ultramodern.5",
158
+ "@modern-js/plugin-bff-build-extensions": "npm:@bleedingdev/modern-js-plugin-bff-build-extensions@3.9.3-ultramodern.5",
159
+ "@modern-js/renderer-core": "npm:@bleedingdev/modern-js-renderer-core@3.9.3-ultramodern.5",
160
+ "@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.3-ultramodern.5",
161
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.3-ultramodern.5",
162
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.3-ultramodern.5",
163
+ "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.3-ultramodern.5",
164
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.5",
165
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.5",
166
166
  "@rsbuild/core": "2.2.11",
167
167
  "@types/babel__core": "^7.20.5",
168
168
  "prettier": "~3.9.9"
169
169
  },
170
170
  "devDependencies": {
171
- "@modern-js/i18n-integration": "npm:@bleedingdev/modern-js-i18n-integration@3.9.3-ultramodern.4",
172
- "@modern-js/plugin-bff": "npm:@bleedingdev/modern-js-plugin-bff@3.9.3-ultramodern.4",
173
- "@modern-js/plugin-tanstack": "npm:@bleedingdev/modern-js-plugin-tanstack@3.9.3-ultramodern.4",
174
- "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.3-ultramodern.4",
175
- "@modern-js/renderer-octane": "npm:@bleedingdev/modern-js-renderer-octane@3.9.3-ultramodern.4",
176
- "@modern-js/renderer-solid": "npm:@bleedingdev/modern-js-renderer-solid@3.9.3-ultramodern.4",
177
- "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.3-ultramodern.4",
178
- "@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.3-ultramodern.4",
179
- "@modern-js/server": "npm:@bleedingdev/modern-js-server@3.9.3-ultramodern.4",
180
- "@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.3-ultramodern.4",
171
+ "@modern-js/i18n-integration": "npm:@bleedingdev/modern-js-i18n-integration@3.9.3-ultramodern.5",
172
+ "@modern-js/plugin-bff": "npm:@bleedingdev/modern-js-plugin-bff@3.9.3-ultramodern.5",
173
+ "@modern-js/plugin-tanstack": "npm:@bleedingdev/modern-js-plugin-tanstack@3.9.3-ultramodern.5",
174
+ "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.3-ultramodern.5",
175
+ "@modern-js/renderer-octane": "npm:@bleedingdev/modern-js-renderer-octane@3.9.3-ultramodern.5",
176
+ "@modern-js/renderer-solid": "npm:@bleedingdev/modern-js-renderer-solid@3.9.3-ultramodern.5",
177
+ "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.3-ultramodern.5",
178
+ "@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.3-ultramodern.5",
179
+ "@modern-js/server": "npm:@bleedingdev/modern-js-server@3.9.3-ultramodern.5",
180
+ "@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.3-ultramodern.5",
181
181
  "@octanejs/rspack-plugin": "0.1.55",
182
182
  "@rsbuild/plugin-svgr": "2.0.5",
183
183
  "@rslib/core": "1.0.3",
@@ -236,11 +236,11 @@
236
236
  "ultramodern": "bin/ultramodern.mjs"
237
237
  },
238
238
  "peerDependencies": {
239
- "@modern-js/i18n-integration": "3.9.3-ultramodern.4",
240
- "@modern-js/renderer-octane": "3.9.3-ultramodern.4",
241
- "@modern-js/renderer-solid": "3.9.3-ultramodern.4",
242
- "@modern-js/runtime": "3.9.3-ultramodern.4",
243
- "@modern-js/runtime-renderer-extensions": "3.9.3-ultramodern.4",
239
+ "@modern-js/i18n-integration": "3.9.3-ultramodern.5",
240
+ "@modern-js/renderer-octane": "3.9.3-ultramodern.5",
241
+ "@modern-js/renderer-solid": "3.9.3-ultramodern.5",
242
+ "@modern-js/runtime": "3.9.3-ultramodern.5",
243
+ "@modern-js/runtime-renderer-extensions": "3.9.3-ultramodern.5",
244
244
  "@rsbuild/plugin-svgr": "2.0.5",
245
245
  "typescript": "7.0.2"
246
246
  },
@@ -39,8 +39,12 @@ export function createRendererBuildIdentityResolver(
39
39
  ...(delivery
40
40
  ? {
41
41
  appId: delivery.appId,
42
- unitId: delivery.unitId,
43
- sourceRevision: delivery.sourceRevision,
42
+ // Already resolved by `resolveUltramodernReleaseIdentity`.
43
+ deliveryUnit: {
44
+ unitId: delivery.unitId,
45
+ buildMarker: delivery.buildMarker,
46
+ sourceRevision: delivery.sourceRevision,
47
+ },
44
48
  }
45
49
  : { appId: context.packageName || undefined }),
46
50
  });
@@ -345,15 +345,20 @@ const resolveWorkspaceConfig = (
345
345
  );
346
346
  }
347
347
  // Topology declares each UI app's renderer. The authored config may restate
348
- // it for `defineConfig`, but cannot select a different renderer.
348
+ // it for `defineConfig`, but cannot select a different renderer. A headless
349
+ // unit declares renderer `none`: it has no UI renderer and no browser Module
350
+ // Federation identity, so its config selects no renderer at all.
349
351
  const declaredRenderer = (app as { renderer?: unknown }).renderer;
352
+ const headless =
353
+ app.surfaceProfile === 'api-only' || declaredRenderer === 'none';
350
354
  if (
351
- declaredRenderer !== undefined &&
352
- config.renderer !== undefined &&
353
- config.renderer !== declaredRenderer
355
+ (headless && config.renderer !== undefined) ||
356
+ (declaredRenderer !== undefined &&
357
+ config.renderer !== undefined &&
358
+ config.renderer !== declaredRenderer)
354
359
  ) {
355
360
  throw new Error(
356
- `[ultramodern-workspace] Renderer for ${options.appId} does not match topology.`,
361
+ `[ultramodern-workspace] Renderer for ${options.appId} does not match topology${headless ? ': a headless unit selects no renderer' : ''}.`,
357
362
  );
358
363
  }
359
364
  const portEnv = portEnvironment(app);
@@ -472,12 +477,16 @@ const resolveWorkspaceConfig = (
472
477
  );
473
478
  return binding ? [binding] : [];
474
479
  });
475
- const mfName = requiredString(
476
- app.moduleFederation?.name,
477
- `${options.appId}.moduleFederation.name`,
478
- );
480
+ // Only UI units own a browser Module Federation container whose chunk
481
+ // globals must stay distinct in a shared page.
482
+ const mfName = headless
483
+ ? undefined
484
+ : requiredString(
485
+ app.moduleFederation?.name,
486
+ `${options.appId}.moduleFederation.name`,
487
+ );
479
488
  const workspaceConfig: AppUserConfig = {
480
- ...(declaredRenderer !== undefined
489
+ ...(!headless && declaredRenderer !== undefined
481
490
  ? { renderer: declaredRenderer as AppUserConfig['renderer'] }
482
491
  : {}),
483
492
  ...(cloudflare
@@ -530,9 +539,7 @@ const resolveWorkspaceConfig = (
530
539
  ),
531
540
  ]
532
541
  : []),
533
- ...(app.surfaceProfile === 'api-only'
534
- ? []
535
- : [zephyrBuildPlugin(configFilename, environment)]),
542
+ ...(headless ? [] : [zephyrBuildPlugin(configFilename, environment)]),
536
543
  ],
537
544
  server: { port, publicDir: ['./locales', './assets'] },
538
545
  source: {
@@ -545,13 +552,17 @@ const resolveWorkspaceConfig = (
545
552
  },
546
553
  tools: {
547
554
  autoprefixer: { overrideBrowserslist: ['defaults'] },
548
- bundlerChain: chain => {
549
- chain.output
550
- .uniqueName(mfName)
551
- .chunkLoadingGlobal(
552
- `__ULTRAMODERN_${envSegment(mfName)}_LOADED_CHUNKS__`,
553
- );
554
- },
555
+ ...(mfName
556
+ ? {
557
+ bundlerChain: chain => {
558
+ chain.output
559
+ .uniqueName(mfName)
560
+ .chunkLoadingGlobal(
561
+ `__ULTRAMODERN_${envSegment(mfName)}_LOADED_CHUNKS__`,
562
+ );
563
+ },
564
+ }
565
+ : {}),
555
566
  devServer: {
556
567
  headers: {
557
568
  'Access-Control-Allow-Headers':