@bleedingdev/modern-js-app-tools 3.8.2-ultramodern.9 → 3.8.3-ultramodern.1

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.
@@ -116,17 +116,19 @@ const createPresetUltramodernConfig = (options = {})=>{
116
116
  precompress: true
117
117
  },
118
118
  server,
119
- ...deliveryUnit ? {
120
- source: {
119
+ source: {
120
+ reactCompiler: true,
121
+ ...deliveryUnit ? {
121
122
  globalVars: {
122
123
  ULTRAMODERN_BUILD_MARKER: releaseIdentity?.buildMarker,
123
124
  ULTRAMODERN_RELEASE_VERSION: deliveryUnit.version,
124
125
  ULTRAMODERN_SOURCE_REVISION: releaseIdentity?.sourceRevision
125
126
  }
126
- }
127
- } : {},
127
+ } : {}
128
+ },
128
129
  tools: {
129
130
  bundlerChain: setReactRouterBridgeSafeAliases,
131
+ lightningcssLoader: true,
130
132
  ...bundledReleaseIdentity ? {
131
133
  rspack: (config)=>{
132
134
  config.plugins ??= [];
@@ -37,7 +37,7 @@ function getAutoInjectEnv(appContext) {
37
37
  const envReg = new RegExp(`^${prefix}`);
38
38
  return Object.keys(process.env).reduce((prev, key)=>{
39
39
  const value = process.env[key];
40
- if (envReg.test(key) && void 0 !== value) prev[`process.env.${key}`] = value;
40
+ if (envReg.test(key) && 'MODERN_MF_APP_SSR' !== key && void 0 !== value) prev[`process.env.${key}`] = value;
41
41
  return prev;
42
42
  }, {});
43
43
  }
@@ -72,17 +72,19 @@ const createPresetUltramodernConfig = (options = {})=>{
72
72
  precompress: true
73
73
  },
74
74
  server,
75
- ...deliveryUnit ? {
76
- source: {
75
+ source: {
76
+ reactCompiler: true,
77
+ ...deliveryUnit ? {
77
78
  globalVars: {
78
79
  ULTRAMODERN_BUILD_MARKER: releaseIdentity?.buildMarker,
79
80
  ULTRAMODERN_RELEASE_VERSION: deliveryUnit.version,
80
81
  ULTRAMODERN_SOURCE_REVISION: releaseIdentity?.sourceRevision
81
82
  }
82
- }
83
- } : {},
83
+ } : {}
84
+ },
84
85
  tools: {
85
86
  bundlerChain: setReactRouterBridgeSafeAliases,
87
+ lightningcssLoader: true,
86
88
  ...bundledReleaseIdentity ? {
87
89
  rspack: (config)=>{
88
90
  config.plugins ??= [];
@@ -5,7 +5,7 @@ function getAutoInjectEnv(appContext) {
5
5
  const envReg = new RegExp(`^${prefix}`);
6
6
  return Object.keys(process.env).reduce((prev, key)=>{
7
7
  const value = process.env[key];
8
- if (envReg.test(key) && void 0 !== value) prev[`process.env.${key}`] = value;
8
+ if (envReg.test(key) && 'MODERN_MF_APP_SSR' !== key && void 0 !== value) prev[`process.env.${key}`] = value;
9
9
  return prev;
10
10
  }, {});
11
11
  }
@@ -73,17 +73,19 @@ const createPresetUltramodernConfig = (options = {})=>{
73
73
  precompress: true
74
74
  },
75
75
  server,
76
- ...deliveryUnit ? {
77
- source: {
76
+ source: {
77
+ reactCompiler: true,
78
+ ...deliveryUnit ? {
78
79
  globalVars: {
79
80
  ULTRAMODERN_BUILD_MARKER: releaseIdentity?.buildMarker,
80
81
  ULTRAMODERN_RELEASE_VERSION: deliveryUnit.version,
81
82
  ULTRAMODERN_SOURCE_REVISION: releaseIdentity?.sourceRevision
82
83
  }
83
- }
84
- } : {},
84
+ } : {}
85
+ },
85
86
  tools: {
86
87
  bundlerChain: setReactRouterBridgeSafeAliases,
88
+ lightningcssLoader: true,
87
89
  ...bundledReleaseIdentity ? {
88
90
  rspack: (config)=>{
89
91
  config.plugins ??= [];
@@ -6,7 +6,7 @@ function getAutoInjectEnv(appContext) {
6
6
  const envReg = new RegExp(`^${prefix}`);
7
7
  return Object.keys(process.env).reduce((prev, key)=>{
8
8
  const value = process.env[key];
9
- if (envReg.test(key) && void 0 !== value) prev[`process.env.${key}`] = value;
9
+ if (envReg.test(key) && 'MODERN_MF_APP_SSR' !== key && void 0 !== value) prev[`process.env.${key}`] = value;
10
10
  return prev;
11
11
  }, {});
12
12
  }
@@ -40,14 +40,18 @@ export interface PresetUltramodernOptions {
40
40
  /**
41
41
  * OTLP exporter endpoint. Setting it (or the environment variable)
42
42
  * enables the OTLP exporter unless `enableTelemetryExporters` is `false`.
43
- * @default process.env.MODERN_TELEMETRY_OTLP_ENDPOINT || 'http://127.0.0.1:4318/v1/logs'
43
+ * The localhost endpoint is used only when exporters are forced on with
44
+ * `enableTelemetryExporters: true` and no endpoint was provided.
45
+ * @default process.env.MODERN_TELEMETRY_OTLP_ENDPOINT
44
46
  */
45
47
  otlpEndpoint?: string;
46
48
  /**
47
49
  * VictoriaMetrics exporter endpoint. Setting it (or the environment
48
50
  * variable) enables the VictoriaMetrics exporter unless
49
51
  * `enableTelemetryExporters` is `false`.
50
- * @default process.env.MODERN_TELEMETRY_VICTORIA_ENDPOINT || 'http://127.0.0.1:8428/api/v1/import/prometheus'
52
+ * The localhost endpoint is used only when exporters are forced on with
53
+ * `enableTelemetryExporters: true` and no endpoint was provided.
54
+ * @default process.env.MODERN_TELEMETRY_VICTORIA_ENDPOINT
51
55
  */
52
56
  victoriaMetricsEndpoint?: string;
53
57
  /**
@@ -62,5 +66,21 @@ export interface PresetUltramodernOptions {
62
66
  */
63
67
  enableModuleFederationSSR?: boolean;
64
68
  }
69
+ /**
70
+ * Materialize a fresh UltraModern preset config.
71
+ *
72
+ * This is the advanced inspection API. Use `presetUltramodern` when composing
73
+ * an application config so nested records, arrays, and hooks keep the normal
74
+ * Modern.js merge behavior.
75
+ */
65
76
  export declare const createPresetUltramodernConfig: (options?: PresetUltramodernOptions) => AppUserConfig;
77
+ /**
78
+ * Compose an application config over the UltraModern preset.
79
+ *
80
+ * The application config is merged after the preset. Nested records are
81
+ * preserved, scalar values and `false` override preset values, and omitted or
82
+ * `undefined` values keep the preset value. Arrays and hooks compose in
83
+ * preset-first order. An empty record does not reset nested preset defaults;
84
+ * use the typed `PresetUltramodernOptions` opt-outs instead.
85
+ */
66
86
  export declare const presetUltramodern: (config: AppUserConfig, options?: PresetUltramodernOptions) => AppUserConfig;
@@ -50,7 +50,7 @@ would give your app a second Effect identity. Before setting
50
50
  `/effect-server`, `/effect-edge` or `/effect-client`, install the exact cohort:
51
51
 
52
52
  ```bash
53
- pnpm add effect@4.0.0-beta.107 @effect/opentelemetry@4.0.0-beta.107
53
+ pnpm add effect@4.0.0-rc.112 @effect/opentelemetry@4.0.0-rc.112
54
54
  ```
55
55
 
56
56
  The pin is exact because UltraModern ships Effect as one lockstep cohort. Apps
@@ -215,17 +215,17 @@ generated apps use:
215
215
 
216
216
  ```yaml
217
217
  trustPolicyExclude:
218
- - 'effect@4.0.0-beta.107'
219
- - '@effect/opentelemetry@4.0.0-beta.107'
218
+ - 'effect@4.0.0-rc.112'
219
+ - '@effect/opentelemetry@4.0.0-rc.112'
220
220
 
221
221
  overrides:
222
- '@effect/opentelemetry': 4.0.0-beta.107
223
- '@effect/vitest': 4.0.0-beta.107
224
- effect: 4.0.0-beta.107
222
+ '@effect/opentelemetry': 4.0.0-rc.112
223
+ '@effect/vitest': 4.0.0-rc.112
224
+ effect: 4.0.0-rc.112
225
225
  ```
226
226
 
227
227
  Do not add a different direct `effect` version in an app package. A mismatched
228
- Effect beta can fail while building layers or HTTP middleware because runtime
228
+ Effect prerelease can fail while building layers or HTTP middleware because runtime
229
229
  services come from different package instances. The strict 24-hour release-age
230
230
  gate applies to installed packages; the current cohort has no Effect age
231
231
  exemption, and override-only `@effect/vitest` is not an installed approval
@@ -38,7 +38,7 @@ Additionally, after installing nvm or fnm, when there is a `.nvmrc` file contain
38
38
  It is recommended to use [pnpm](https://pnpm.io/installation) to manage dependencies:
39
39
 
40
40
  ```bash
41
- mise use pnpm@11.21.0
41
+ mise use pnpm@11.24.0
42
42
  ```
43
43
 
44
44
  :::note
@@ -141,8 +141,8 @@ migration work: move code to `shared/api.ts`, `api/index.ts`, and
141
141
  and `src/effect`.
142
142
 
143
143
  Generated strict Effect workspaces pin the compatible Effect cohort with pnpm
144
- overrides: `effect@4.0.0-beta.107`, `@effect/opentelemetry@4.0.0-beta.107`,
145
- and `@effect/vitest@4.0.0-beta.107`. Do not add app-local direct Effect
144
+ overrides: `effect@4.0.0-rc.112`, `@effect/opentelemetry@4.0.0-rc.112`,
145
+ and `@effect/vitest@4.0.0-rc.112`. Do not add app-local direct Effect
146
146
  versions that disagree with those overrides. The strict 24-hour release-age
147
147
  gate applies to installed packages; this cohort carries no Effect age
148
148
  exemption, and override-only `@effect/vitest` is not an installed approval
@@ -154,12 +154,21 @@ metadata transition; they are not release-age approvals.
154
154
 
155
155
  | Surface | Pin |
156
156
  | ------------------------------ | --------------------------------------------------------------------------------------------------- |
157
- | Effect runtime and test cohort | `effect`, `@effect/opentelemetry`, and `@effect/vitest`: `4.0.0-beta.107` |
158
- | Effect compiler | `@effect/tsgo@0.36.2` |
159
- | TanStack Router | `@tanstack/react-router@1.170.25`, `@tanstack/router-core@1.171.21`, `@tanstack/history@1.162.1` |
160
- | Module Federation | `bridge-react`, `manifest`, `modern-js-v3`, and `rspack`: `2.8.2`; `@module-federation/node@2.7.49` |
161
- | React Router | `react-router@7.18.2` |
162
- | Node and package tooling | Node `26.7.0`, `@types/node@^26.2.0`, pnpm `11.21.0` |
157
+ | Effect runtime and test cohort | `effect`, `@effect/opentelemetry`, and `@effect/vitest`: `4.0.0-rc.112` |
158
+ | Effect compiler | `@effect/tsgo@0.37.0` |
159
+ | Oxc and Ultracite | `oxlint@1.80.0`, `oxfmt@0.65.0`, `ultracite@7.10.6` |
160
+ | TanStack Router | `@tanstack/react-router@1.170.32`, `@tanstack/router-core@1.171.27`, `@tanstack/history@1.162.1` |
161
+ | Module Federation | `bridge-react`, `manifest`, `modern-js-v3`, and `rspack`: `2.9.0`; `@module-federation/node@2.7.50` |
162
+ | Tailwind CSS | `tailwindcss@4.3.3` |
163
+ | Node and package tooling | Node `26.7.0`, `@types/node@^26.2.0`, pnpm `11.24.0` |
164
+
165
+ Generated workspaces default to Module Federation bridge-react's router-free
166
+ base entry (`bridge.enableBridgeRouter: false`), with TanStack Router as the
167
+ application router. Declaring `react-router` (or `react-router-dom`) as a
168
+ direct dependency of an app marks it a React Router consumer: the
169
+ generator/migration then emit `enableBridgeRouter: true` for that app's
170
+ federation config, the workspace validator accepts it, and the UltraModern
171
+ preset aliases `react-router`'s entrypoints for the app's own routing.
163
172
 
164
173
  Gradual migration means old, unmigrated Modern.js apps can keep their existing
165
174
  runtime until they are converted. Once a surface is generated or migrated as
@@ -243,6 +252,94 @@ directories, and caches are isolated per app, build target, and Rspack
243
252
  environment so local `build`, `cloudflare:build`, and multi-environment
244
253
  compilers do not share mutable build state.
245
254
 
255
+ ## Configure the public preset
256
+
257
+ Use `presetUltramodern(appConfig, presetOptions)` inside the normal Modern.js
258
+ `defineConfig` call:
259
+
260
+ ```ts title="modern.config.ts"
261
+ import { defineConfig, presetUltramodern } from '@modern-js/app-tools';
262
+
263
+ export default defineConfig(
264
+ presetUltramodern(
265
+ {
266
+ output: {
267
+ precompress: false,
268
+ },
269
+ server: {
270
+ telemetry: {
271
+ failLoudStartup: true,
272
+ },
273
+ },
274
+ },
275
+ {
276
+ appId: 'catalog',
277
+ enableModuleFederationSSR: false,
278
+ enableTelemetryExporters: false,
279
+ },
280
+ ),
281
+ );
282
+ ```
283
+
284
+ The first argument is ordinary `AppUserConfig`. It contains app-owned config
285
+ and wins where it supplies an override. The second argument controls the
286
+ preset itself. Use its typed options, such as `enableBffRequestId: false`,
287
+ `enableTelemetry: false`, `enableTelemetryExporters: false`, and
288
+ `enableModuleFederationSSR: false`, to turn preset features off.
289
+
290
+ Composition follows the Modern.js config merge rules:
291
+
292
+ - Nested records merge, so changing one nested field keeps its preset
293
+ siblings.
294
+ - Scalars and `false` supplied by the app override preset values. Omitting a
295
+ field, or leaving it `undefined`, keeps the preset value.
296
+ - Arrays and config hooks compose in preset-first order. Non-function array
297
+ entries are deduplicated by deep equality, while function entries are all
298
+ retained. An empty array or empty record does not clear values already
299
+ supplied by the preset.
300
+
301
+ There is no generic reset sentinel. Use a typed preset option for preset-owned
302
+ behavior and a normal app config override for app-owned behavior.
303
+
304
+ `createPresetUltramodernConfig(options)` is an advanced API for inspecting or
305
+ materializing a fresh preset config. Do not spread its result into another
306
+ config object. Object spread is shallow, so replacing `server`, `output`, or
307
+ another nested record can silently discard preset siblings. Use
308
+ `presetUltramodern(...)` for authoring `modern.config.ts`.
309
+
310
+ ### Bare preset and generated workspace policy
311
+
312
+ The preset and the workspace generator own different parts of the config:
313
+
314
+ | Source | Identity | Remaining config |
315
+ | --------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
316
+ | Bare `createPresetUltramodernConfig()` result | Uses `appId: 'app'` and has no `deliveryUnit` | Uses the preset defaults. Telemetry stays enabled, but no exporter is configured until its endpoint is set. |
317
+ | Generated app | Supplies the app-specific `appId` and stamped `deliveryUnit` | Inherits the other strict defaults from `presetUltramodern(...)`. |
318
+ | Application | Supplies the first `appConfig` argument | Overrides app-owned fields through the normal Modern.js merge. |
319
+
320
+ Keep the generated `appId` and `deliveryUnit` options intact. To change
321
+ preset-owned behavior, use typed options such as
322
+ `enableTelemetryExporters: false`,
323
+ `enableTelemetry: false`, `enableBffRequestId: false`, or
324
+ `enableModuleFederationSSR: false`. To change an app-owned field, put the
325
+ override in the first argument, as in the example above.
326
+
327
+ Telemetry exporter endpoints are unset by default:
328
+
329
+ - `MODERN_TELEMETRY_OTLP_ENDPOINT` enables only the OTLP exporter.
330
+ - `MODERN_TELEMETRY_VICTORIA_ENDPOINT` enables only the VictoriaMetrics
331
+ exporter.
332
+ - Setting both enables both. Leaving both unset keeps the telemetry pipeline
333
+ enabled without configuring an exporter.
334
+
335
+ The typed `otlpEndpoint` and `victoriaMetricsEndpoint` preset options provide
336
+ the same per-exporter behavior without environment variables.
337
+
338
+ ```bash
339
+ MODERN_TELEMETRY_OTLP_ENDPOINT=https://otel.example.com/v1/logs \
340
+ mise exec -- pnpm dev
341
+ ```
342
+
246
343
  ## Human Workflow
247
344
 
248
345
  The public BleedingDev create package has one supported generated product. The
@@ -421,18 +518,6 @@ BleedingDev packages are published through GitHub Actions trusted publishing.
421
518
  The public workflow is tokenless; do not publish packages manually from a
422
519
  developer machine.
423
520
 
424
- ## Baseline Switches (Opt-out)
425
-
426
- The generated `presetUltramodern(...)` starter enables strict platform contracts. Use these env switches to opt out per app or per environment:
427
-
428
- - `MODERN_BASELINE_ENABLE_MF_SSR` (default: `true`): Enables app-level MF SSR baseline contract (`server.ssr.mode: 'stream'` + `moduleFederationAppSSR`). Disable when the app does not use app-level MF SSR, or when you need plain SSR/CSR behavior first.
429
- - `MODERN_BASELINE_ENABLE_BFF_REQUEST_ID` (default: `true`): Enables default BFF producer identity contract (`bff.requestId`). Disable when the app does not need cross-project producer isolation.
430
- - `MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS` (default: `true`): Enables telemetry exporters in baseline config. Disable when the environment has no telemetry backend yet.
431
- - `MODERN_BASELINE_APP_ID` (default: `basename(process.cwd())`): Overrides baseline `bff.requestId` identity. Set this when you need a fixed platform-wide producer ID convention.
432
- - `MODERN_TELEMETRY_OTLP_ENDPOINT` (default: `http://127.0.0.1:4318/v1/logs`): OTLP exporter endpoint. Override when you route telemetry through a different collector endpoint.
433
- - `MODERN_TELEMETRY_VICTORIA_ENDPOINT` (default: `http://127.0.0.1:8428/api/v1/import/prometheus`): VictoriaMetrics exporter endpoint. Override when you use a different VM ingress endpoint.
434
- - `MODERN_TELEMETRY_FAIL_LOUD_STARTUP` (default: `true`): Fails startup if configured exporters fail startup health checks. Disable in local/dev environments where temporary telemetry outage should not block boot.
435
-
436
521
  ## Related Docs
437
522
 
438
523
  - [BFF Runtime Frameworks](/guides/advanced-features/bff/frameworks.md)
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.8.2-ultramodern.9",
20
+ "version": "3.8.3-ultramodern.1",
21
21
  "types": "./dist/types/index.d.ts",
22
22
  "main": "./dist/cjs/index.js",
23
23
  "exports": {
@@ -134,17 +134,17 @@
134
134
  "@babel/traverse": "^8.0.0",
135
135
  "@babel/types": "^8.0.0",
136
136
  "@loadable/component": "5.16.7",
137
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.8.2-ultramodern.9",
138
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.8.2-ultramodern.9",
139
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.8.2-ultramodern.9",
140
- "@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.8.2-ultramodern.9",
141
- "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.8.2-ultramodern.9",
142
- "@modern-js/server": "npm:@bleedingdev/modern-js-server@3.8.2-ultramodern.9",
143
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.8.2-ultramodern.9",
144
- "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.8.2-ultramodern.9",
145
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.8.2-ultramodern.9",
146
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.8.2-ultramodern.9",
147
- "@rsbuild/core": "2.2.0-rc.0",
137
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.8.3-ultramodern.1",
138
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.8.3-ultramodern.1",
139
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.8.3-ultramodern.1",
140
+ "@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.8.3-ultramodern.1",
141
+ "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.8.3-ultramodern.1",
142
+ "@modern-js/server": "npm:@bleedingdev/modern-js-server@3.8.3-ultramodern.1",
143
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.8.3-ultramodern.1",
144
+ "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.8.3-ultramodern.1",
145
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.8.3-ultramodern.1",
146
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.8.3-ultramodern.1",
147
+ "@rsbuild/core": "2.2.0",
148
148
  "@swc/core": "1.15.43",
149
149
  "@swc/helpers": "^0.5.23",
150
150
  "compression-webpack-plugin": "^12.0.0",