@bleedingdev/modern-js-ultramodern-app-tools 3.9.3-ultramodern.1 → 3.9.3-ultramodern.2

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.
@@ -40,7 +40,8 @@ __webpack_require__.d(__webpack_exports__, {
40
40
  UltramodernReleaseIdentityBannerPlugin: ()=>UltramodernReleaseIdentityBannerPlugin,
41
41
  createPresetUltramodernConfig: ()=>createPresetUltramodernConfig,
42
42
  isUltramodernReleaseIdentityBannerPlugin: ()=>isUltramodernReleaseIdentityBannerPlugin,
43
- presetUltramodern: ()=>presetUltramodern
43
+ presetUltramodern: ()=>presetUltramodern,
44
+ releaseIdentityBanner: ()=>releaseIdentityBanner
44
45
  });
45
46
  const external_node_fs_namespaceObject = require("node:fs");
46
47
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
@@ -53,6 +54,7 @@ const cli_namespaceObject = require("@modern-js/plugin/cli");
53
54
  const renderer_core_namespaceObject = require("@modern-js/renderer-core");
54
55
  const core_namespaceObject = require("@rsbuild/core");
55
56
  const module_federation_shared_plugin_js_namespaceObject = require("../renderers/react/module-federation-shared-plugin.js");
57
+ const external_server_minify_js_namespaceObject = require("./server-minify.js");
56
58
  const external_type_checker_js_namespaceObject = require("./type-checker.js");
57
59
  const DEFAULT_OTLP_ENDPOINT = 'http://127.0.0.1:4318/v1/logs';
58
60
  const DEFAULT_VICTORIA_METRICS_ENDPOINT = 'http://127.0.0.1:8428/api/v1/import/prometheus';
@@ -65,6 +67,7 @@ class UltramodernReleaseIdentityBannerPlugin extends core_namespaceObject.rspack
65
67
  });
66
68
  }
67
69
  }
70
+ const releaseIdentityBanner = (values)=>values.map((value)=>`${JSON.stringify(value)};`).join('');
68
71
  function isUltramodernReleaseIdentityBannerPlugin(plugin) {
69
72
  return 'object' == typeof plugin && null !== plugin && Object.getOwnPropertyDescriptor(plugin, RELEASE_IDENTITY_BANNER)?.value === true;
70
73
  }
@@ -158,7 +161,11 @@ const createRendererPreset = (options = {}, renderer = 'react')=>{
158
161
  rspack: (config)=>{
159
162
  config.plugins ??= [];
160
163
  config.plugins.push(new UltramodernReleaseIdentityBannerPlugin({
161
- banner: `void ${JSON.stringify(bundledReleaseIdentity.buildMarker)};void ${JSON.stringify(bundledReleaseIdentity.sourceRevision)};void ${JSON.stringify(bundledReleaseIdentity.releaseVersion)};`,
164
+ banner: releaseIdentityBanner([
165
+ bundledReleaseIdentity.buildMarker,
166
+ bundledReleaseIdentity.sourceRevision,
167
+ bundledReleaseIdentity.releaseVersion
168
+ ]),
162
169
  raw: true,
163
170
  stage: core_namespaceObject.rspack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
164
171
  test: /\.(?:c|m)?js$/u
@@ -181,6 +188,7 @@ const presetUltramodern = (config, options = {})=>{
181
188
  ]);
182
189
  merged.builderPlugins = [
183
190
  (0, plugin_namespaceObject.builderPluginAdapterPrecompress)(merged.output?.precompress),
191
+ (0, external_server_minify_js_namespaceObject.builderPluginServerMinify)(merged.output?.minify),
184
192
  ...merged.builderPlugins ?? []
185
193
  ];
186
194
  return merged;
@@ -189,11 +197,13 @@ exports.UltramodernReleaseIdentityBannerPlugin = __webpack_exports__.Ultramodern
189
197
  exports.createPresetUltramodernConfig = __webpack_exports__.createPresetUltramodernConfig;
190
198
  exports.isUltramodernReleaseIdentityBannerPlugin = __webpack_exports__.isUltramodernReleaseIdentityBannerPlugin;
191
199
  exports.presetUltramodern = __webpack_exports__.presetUltramodern;
200
+ exports.releaseIdentityBanner = __webpack_exports__.releaseIdentityBanner;
192
201
  for(var __rspack_i in __webpack_exports__)if (-1 === [
193
202
  "UltramodernReleaseIdentityBannerPlugin",
194
203
  "createPresetUltramodernConfig",
195
204
  "isUltramodernReleaseIdentityBannerPlugin",
196
- "presetUltramodern"
205
+ "presetUltramodern",
206
+ "releaseIdentityBanner"
197
207
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
198
208
  Object.defineProperty(exports, '__esModule', {
199
209
  value: true
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ const ULTRAMODERN_SERVER_MINIFY = {
31
+ js: true,
32
+ jsOptions: {
33
+ minimizerOptions: {
34
+ compress: {
35
+ keep_classnames: true,
36
+ keep_fnames: true
37
+ },
38
+ mangle: {
39
+ keep_classnames: true,
40
+ keep_fnames: true
41
+ }
42
+ }
43
+ }
44
+ };
45
+ const builderPluginServerMinify = (appMinify)=>({
46
+ name: 'ultramodern:server-minify',
47
+ setup (api) {
48
+ if (void 0 !== appMinify) return;
49
+ api.modifyRsbuildConfig((config)=>{
50
+ if (config.output?.minify !== void 0) return;
51
+ for (const environment of Object.values(config.environments ?? {})){
52
+ const target = environment.output?.target ?? config.output?.target;
53
+ if ('node' === target && environment.output?.minify === void 0) environment.output = {
54
+ ...environment.output,
55
+ minify: ULTRAMODERN_SERVER_MINIFY
56
+ };
57
+ }
58
+ });
59
+ }
60
+ });
61
+ __webpack_require__.d(__webpack_exports__, {}, {
62
+ ULTRAMODERN_SERVER_MINIFY: ULTRAMODERN_SERVER_MINIFY,
63
+ builderPluginServerMinify: builderPluginServerMinify
64
+ });
65
+ exports.ULTRAMODERN_SERVER_MINIFY = __webpack_exports__.ULTRAMODERN_SERVER_MINIFY;
66
+ exports.builderPluginServerMinify = __webpack_exports__.builderPluginServerMinify;
67
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
68
+ "ULTRAMODERN_SERVER_MINIFY",
69
+ "builderPluginServerMinify"
70
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
71
+ Object.defineProperty(exports, '__esModule', {
72
+ value: true
73
+ });
@@ -150,7 +150,10 @@ function reactRendererBuildMetadataPlugin(options) {
150
150
  const { buildId, sourceRevision } = identities;
151
151
  config.plugins = (config.plugins ?? []).filter((plugin)=>!(0, preset_js_namespaceObject.isUltramodernReleaseIdentityBannerPlugin)(plugin));
152
152
  config.plugins.push(new core_namespaceObject.rspack.BannerPlugin({
153
- banner: `void ${JSON.stringify(buildId)};void ${JSON.stringify(sourceRevision)};`,
153
+ banner: (0, preset_js_namespaceObject.releaseIdentityBanner)([
154
+ buildId,
155
+ sourceRevision
156
+ ]),
154
157
  raw: true,
155
158
  stage: core_namespaceObject.rspack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
156
159
  test: /\.(?:c|m)?js$/u
@@ -7,6 +7,7 @@ import { mergeConfig } from "@modern-js/plugin/cli";
7
7
  import { resolveRenderer } from "@modern-js/renderer-core";
8
8
  import { rspack } from "@rsbuild/core";
9
9
  import { ultramodernModuleFederationSharedPlugin } from "../renderers/react/module-federation-shared-plugin.mjs";
10
+ import { builderPluginServerMinify } from "./server-minify.mjs";
10
11
  import { rendererTypeCheckerOptions } from "./type-checker.mjs";
11
12
  const DEFAULT_OTLP_ENDPOINT = 'http://127.0.0.1:4318/v1/logs';
12
13
  const DEFAULT_VICTORIA_METRICS_ENDPOINT = 'http://127.0.0.1:8428/api/v1/import/prometheus';
@@ -19,6 +20,7 @@ class UltramodernReleaseIdentityBannerPlugin extends rspack.BannerPlugin {
19
20
  });
20
21
  }
21
22
  }
23
+ const releaseIdentityBanner = (values)=>values.map((value)=>`${JSON.stringify(value)};`).join('');
22
24
  function isUltramodernReleaseIdentityBannerPlugin(plugin) {
23
25
  return 'object' == typeof plugin && null !== plugin && Object.getOwnPropertyDescriptor(plugin, RELEASE_IDENTITY_BANNER)?.value === true;
24
26
  }
@@ -112,7 +114,11 @@ const createRendererPreset = (options = {}, renderer = 'react')=>{
112
114
  rspack: (config)=>{
113
115
  config.plugins ??= [];
114
116
  config.plugins.push(new UltramodernReleaseIdentityBannerPlugin({
115
- banner: `void ${JSON.stringify(bundledReleaseIdentity.buildMarker)};void ${JSON.stringify(bundledReleaseIdentity.sourceRevision)};void ${JSON.stringify(bundledReleaseIdentity.releaseVersion)};`,
117
+ banner: releaseIdentityBanner([
118
+ bundledReleaseIdentity.buildMarker,
119
+ bundledReleaseIdentity.sourceRevision,
120
+ bundledReleaseIdentity.releaseVersion
121
+ ]),
116
122
  raw: true,
117
123
  stage: rspack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
118
124
  test: /\.(?:c|m)?js$/u
@@ -135,8 +141,9 @@ const presetUltramodern = (config, options = {})=>{
135
141
  ]);
136
142
  merged.builderPlugins = [
137
143
  builderPluginAdapterPrecompress(merged.output?.precompress),
144
+ builderPluginServerMinify(merged.output?.minify),
138
145
  ...merged.builderPlugins ?? []
139
146
  ];
140
147
  return merged;
141
148
  };
142
- export { UltramodernReleaseIdentityBannerPlugin, createPresetUltramodernConfig, isUltramodernReleaseIdentityBannerPlugin, presetUltramodern };
149
+ export { UltramodernReleaseIdentityBannerPlugin, createPresetUltramodernConfig, isUltramodernReleaseIdentityBannerPlugin, presetUltramodern, releaseIdentityBanner };
@@ -0,0 +1,32 @@
1
+ const ULTRAMODERN_SERVER_MINIFY = {
2
+ js: true,
3
+ jsOptions: {
4
+ minimizerOptions: {
5
+ compress: {
6
+ keep_classnames: true,
7
+ keep_fnames: true
8
+ },
9
+ mangle: {
10
+ keep_classnames: true,
11
+ keep_fnames: true
12
+ }
13
+ }
14
+ }
15
+ };
16
+ const builderPluginServerMinify = (appMinify)=>({
17
+ name: 'ultramodern:server-minify',
18
+ setup (api) {
19
+ if (void 0 !== appMinify) return;
20
+ api.modifyRsbuildConfig((config)=>{
21
+ if (config.output?.minify !== void 0) return;
22
+ for (const environment of Object.values(config.environments ?? {})){
23
+ const target = environment.output?.target ?? config.output?.target;
24
+ if ('node' === target && environment.output?.minify === void 0) environment.output = {
25
+ ...environment.output,
26
+ minify: ULTRAMODERN_SERVER_MINIFY
27
+ };
28
+ }
29
+ });
30
+ }
31
+ });
32
+ export { ULTRAMODERN_SERVER_MINIFY, builderPluginServerMinify };
@@ -9,7 +9,7 @@ import { getArgv } from "@modern-js/utils";
9
9
  import { rspack } from "@rsbuild/core";
10
10
  import { isEntryMetadataRead } from "../../native-composition/config-read-context.mjs";
11
11
  import { createRendererBuildManifest, readRendererBuildManifest, rendererBuildCachePerformance, writeRendererBuildManifest } from "../../native-composition/native-build-manifest.mjs";
12
- import { isUltramodernReleaseIdentityBannerPlugin } from "../../native-composition/preset.mjs";
12
+ import { isUltramodernReleaseIdentityBannerPlugin, releaseIdentityBanner } from "../../native-composition/preset.mjs";
13
13
  import { resolveRendererProfile, resolveRendererRouterFrameworks } from "../../native-composition/renderer-profile.mjs";
14
14
  import { reactRendererAdapter } from "./adapter.mjs";
15
15
  const REACT_RENDERER_IDENTITY_ELEMENT_ID = 'ultramodern-renderer-identity';
@@ -102,7 +102,10 @@ function reactRendererBuildMetadataPlugin(options) {
102
102
  const { buildId, sourceRevision } = identities;
103
103
  config.plugins = (config.plugins ?? []).filter((plugin)=>!isUltramodernReleaseIdentityBannerPlugin(plugin));
104
104
  config.plugins.push(new rspack.BannerPlugin({
105
- banner: `void ${JSON.stringify(buildId)};void ${JSON.stringify(sourceRevision)};`,
105
+ banner: releaseIdentityBanner([
106
+ buildId,
107
+ sourceRevision
108
+ ]),
106
109
  raw: true,
107
110
  stage: rspack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
108
111
  test: /\.(?:c|m)?js$/u
@@ -8,6 +8,7 @@ import { mergeConfig } from "@modern-js/plugin/cli";
8
8
  import { resolveRenderer } from "@modern-js/renderer-core";
9
9
  import { rspack } from "@rsbuild/core";
10
10
  import { ultramodernModuleFederationSharedPlugin } from "../renderers/react/module-federation-shared-plugin.mjs";
11
+ import { builderPluginServerMinify } from "./server-minify.mjs";
11
12
  import { rendererTypeCheckerOptions } from "./type-checker.mjs";
12
13
  const DEFAULT_OTLP_ENDPOINT = 'http://127.0.0.1:4318/v1/logs';
13
14
  const DEFAULT_VICTORIA_METRICS_ENDPOINT = 'http://127.0.0.1:8428/api/v1/import/prometheus';
@@ -20,6 +21,7 @@ class UltramodernReleaseIdentityBannerPlugin extends rspack.BannerPlugin {
20
21
  });
21
22
  }
22
23
  }
24
+ const releaseIdentityBanner = (values)=>values.map((value)=>`${JSON.stringify(value)};`).join('');
23
25
  function isUltramodernReleaseIdentityBannerPlugin(plugin) {
24
26
  return 'object' == typeof plugin && null !== plugin && Object.getOwnPropertyDescriptor(plugin, RELEASE_IDENTITY_BANNER)?.value === true;
25
27
  }
@@ -113,7 +115,11 @@ const createRendererPreset = (options = {}, renderer = 'react')=>{
113
115
  rspack: (config)=>{
114
116
  config.plugins ??= [];
115
117
  config.plugins.push(new UltramodernReleaseIdentityBannerPlugin({
116
- banner: `void ${JSON.stringify(bundledReleaseIdentity.buildMarker)};void ${JSON.stringify(bundledReleaseIdentity.sourceRevision)};void ${JSON.stringify(bundledReleaseIdentity.releaseVersion)};`,
118
+ banner: releaseIdentityBanner([
119
+ bundledReleaseIdentity.buildMarker,
120
+ bundledReleaseIdentity.sourceRevision,
121
+ bundledReleaseIdentity.releaseVersion
122
+ ]),
117
123
  raw: true,
118
124
  stage: rspack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
119
125
  test: /\.(?:c|m)?js$/u
@@ -136,8 +142,9 @@ const presetUltramodern = (config, options = {})=>{
136
142
  ]);
137
143
  merged.builderPlugins = [
138
144
  builderPluginAdapterPrecompress(merged.output?.precompress),
145
+ builderPluginServerMinify(merged.output?.minify),
139
146
  ...merged.builderPlugins ?? []
140
147
  ];
141
148
  return merged;
142
149
  };
143
- export { UltramodernReleaseIdentityBannerPlugin, createPresetUltramodernConfig, isUltramodernReleaseIdentityBannerPlugin, presetUltramodern };
150
+ export { UltramodernReleaseIdentityBannerPlugin, createPresetUltramodernConfig, isUltramodernReleaseIdentityBannerPlugin, presetUltramodern, releaseIdentityBanner };
@@ -0,0 +1,33 @@
1
+ import "node:module";
2
+ const ULTRAMODERN_SERVER_MINIFY = {
3
+ js: true,
4
+ jsOptions: {
5
+ minimizerOptions: {
6
+ compress: {
7
+ keep_classnames: true,
8
+ keep_fnames: true
9
+ },
10
+ mangle: {
11
+ keep_classnames: true,
12
+ keep_fnames: true
13
+ }
14
+ }
15
+ }
16
+ };
17
+ const builderPluginServerMinify = (appMinify)=>({
18
+ name: 'ultramodern:server-minify',
19
+ setup (api) {
20
+ if (void 0 !== appMinify) return;
21
+ api.modifyRsbuildConfig((config)=>{
22
+ if (config.output?.minify !== void 0) return;
23
+ for (const environment of Object.values(config.environments ?? {})){
24
+ const target = environment.output?.target ?? config.output?.target;
25
+ if ('node' === target && environment.output?.minify === void 0) environment.output = {
26
+ ...environment.output,
27
+ minify: ULTRAMODERN_SERVER_MINIFY
28
+ };
29
+ }
30
+ });
31
+ }
32
+ });
33
+ export { ULTRAMODERN_SERVER_MINIFY, builderPluginServerMinify };
@@ -10,7 +10,7 @@ import { getArgv } from "@modern-js/utils";
10
10
  import { rspack } from "@rsbuild/core";
11
11
  import { isEntryMetadataRead } from "../../native-composition/config-read-context.mjs";
12
12
  import { createRendererBuildManifest, readRendererBuildManifest, rendererBuildCachePerformance, writeRendererBuildManifest } from "../../native-composition/native-build-manifest.mjs";
13
- import { isUltramodernReleaseIdentityBannerPlugin } from "../../native-composition/preset.mjs";
13
+ import { isUltramodernReleaseIdentityBannerPlugin, releaseIdentityBanner } from "../../native-composition/preset.mjs";
14
14
  import { resolveRendererProfile, resolveRendererRouterFrameworks } from "../../native-composition/renderer-profile.mjs";
15
15
  import { reactRendererAdapter } from "./adapter.mjs";
16
16
  const REACT_RENDERER_IDENTITY_ELEMENT_ID = 'ultramodern-renderer-identity';
@@ -103,7 +103,10 @@ function reactRendererBuildMetadataPlugin(options) {
103
103
  const { buildId, sourceRevision } = identities;
104
104
  config.plugins = (config.plugins ?? []).filter((plugin)=>!isUltramodernReleaseIdentityBannerPlugin(plugin));
105
105
  config.plugins.push(new rspack.BannerPlugin({
106
- banner: `void ${JSON.stringify(buildId)};void ${JSON.stringify(sourceRevision)};`,
106
+ banner: releaseIdentityBanner([
107
+ buildId,
108
+ sourceRevision
109
+ ]),
107
110
  raw: true,
108
111
  stage: rspack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
109
112
  test: /\.(?:c|m)?js$/u
@@ -3,6 +3,12 @@ import type { AppUserConfig } from './types.js';
3
3
  export declare class UltramodernReleaseIdentityBannerPlugin extends rspack.BannerPlugin {
4
4
  constructor(options: ConstructorParameters<typeof rspack.BannerPlugin>[0]);
5
5
  }
6
+ /**
7
+ * Raw release identity banner. String statements extend the chunk's directive
8
+ * prologue, so a following `"use strict"` still applies; `void` expressions
9
+ * would end the prologue and silently turn every chunk sloppy.
10
+ */
11
+ export declare const releaseIdentityBanner: (values: readonly string[]) => string;
6
12
  export declare function isUltramodernReleaseIdentityBannerPlugin(plugin: unknown): boolean;
7
13
  export interface PresetUltramodernOptions {
8
14
  /** Build environment; defaults to the current process environment. */
@@ -0,0 +1,33 @@
1
+ import type { RsbuildConfig, RsbuildPlugin } from '@rsbuild/core';
2
+ type MinifyConfig = NonNullable<NonNullable<RsbuildConfig['output']>['minify']>;
3
+ /**
4
+ * Production minification for `node` environments.
5
+ *
6
+ * Rsbuild leaves server bundles unminified, so SSR and backend chunks ship
7
+ * dead framework branches and whitespace that every cold start parses. Names
8
+ * are kept: server logs, error classes and `constructor.name` checks read them,
9
+ * and keeping them costs a few percent of the minified size.
10
+ */
11
+ export declare const ULTRAMODERN_SERVER_MINIFY: {
12
+ readonly js: true;
13
+ readonly jsOptions: {
14
+ readonly minimizerOptions: {
15
+ readonly compress: {
16
+ readonly keep_classnames: true;
17
+ readonly keep_fnames: true;
18
+ };
19
+ readonly mangle: {
20
+ readonly keep_classnames: true;
21
+ readonly keep_fnames: true;
22
+ };
23
+ };
24
+ };
25
+ };
26
+ /**
27
+ * Minify `node` environments unless the application chose `output.minify`.
28
+ *
29
+ * Runs in `modifyRsbuildConfig`, before Rsbuild fills its `!isServer` default,
30
+ * so an explicit app or environment value is still distinguishable and wins.
31
+ */
32
+ export declare const builderPluginServerMinify: (appMinify: MinifyConfig | undefined) => RsbuildPlugin;
33
+ export {};
@@ -3,6 +3,12 @@ import type { AppUserConfig } from './types.mjs';
3
3
  export declare class UltramodernReleaseIdentityBannerPlugin extends rspack.BannerPlugin {
4
4
  constructor(options: ConstructorParameters<typeof rspack.BannerPlugin>[0]);
5
5
  }
6
+ /**
7
+ * Raw release identity banner. String statements extend the chunk's directive
8
+ * prologue, so a following `"use strict"` still applies; `void` expressions
9
+ * would end the prologue and silently turn every chunk sloppy.
10
+ */
11
+ export declare const releaseIdentityBanner: (values: readonly string[]) => string;
6
12
  export declare function isUltramodernReleaseIdentityBannerPlugin(plugin: unknown): boolean;
7
13
  export interface PresetUltramodernOptions {
8
14
  /** Build environment; defaults to the current process environment. */
@@ -0,0 +1,33 @@
1
+ import type { RsbuildConfig, RsbuildPlugin } from '@rsbuild/core';
2
+ type MinifyConfig = NonNullable<NonNullable<RsbuildConfig['output']>['minify']>;
3
+ /**
4
+ * Production minification for `node` environments.
5
+ *
6
+ * Rsbuild leaves server bundles unminified, so SSR and backend chunks ship
7
+ * dead framework branches and whitespace that every cold start parses. Names
8
+ * are kept: server logs, error classes and `constructor.name` checks read them,
9
+ * and keeping them costs a few percent of the minified size.
10
+ */
11
+ export declare const ULTRAMODERN_SERVER_MINIFY: {
12
+ readonly js: true;
13
+ readonly jsOptions: {
14
+ readonly minimizerOptions: {
15
+ readonly compress: {
16
+ readonly keep_classnames: true;
17
+ readonly keep_fnames: true;
18
+ };
19
+ readonly mangle: {
20
+ readonly keep_classnames: true;
21
+ readonly keep_fnames: true;
22
+ };
23
+ };
24
+ };
25
+ };
26
+ /**
27
+ * Minify `node` environments unless the application chose `output.minify`.
28
+ *
29
+ * Runs in `modifyRsbuildConfig`, before Rsbuild fills its `!isServer` default,
30
+ * so an explicit app or environment value is still distinguishable and wins.
31
+ */
32
+ export declare const builderPluginServerMinify: (appMinify: MinifyConfig | undefined) => RsbuildPlugin;
33
+ export {};
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.1",
14
+ "version": "3.9.3-ultramodern.2",
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.1",
153
- "@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.3-ultramodern.1",
154
- "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.3-ultramodern.1",
155
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.3-ultramodern.1",
156
- "@modern-js/federation-runtime": "npm:@bleedingdev/modern-js-federation-runtime@3.9.3-ultramodern.1",
157
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.3-ultramodern.1",
158
- "@modern-js/plugin-bff-build-extensions": "npm:@bleedingdev/modern-js-plugin-bff-build-extensions@3.9.3-ultramodern.1",
159
- "@modern-js/renderer-core": "npm:@bleedingdev/modern-js-renderer-core@3.9.3-ultramodern.1",
160
- "@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.3-ultramodern.1",
161
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.3-ultramodern.1",
162
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.3-ultramodern.1",
163
- "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.3-ultramodern.1",
164
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.1",
165
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.1",
152
+ "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.3-ultramodern.2",
153
+ "@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.3-ultramodern.2",
154
+ "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.3-ultramodern.2",
155
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.3-ultramodern.2",
156
+ "@modern-js/federation-runtime": "npm:@bleedingdev/modern-js-federation-runtime@3.9.3-ultramodern.2",
157
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.3-ultramodern.2",
158
+ "@modern-js/plugin-bff-build-extensions": "npm:@bleedingdev/modern-js-plugin-bff-build-extensions@3.9.3-ultramodern.2",
159
+ "@modern-js/renderer-core": "npm:@bleedingdev/modern-js-renderer-core@3.9.3-ultramodern.2",
160
+ "@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.3-ultramodern.2",
161
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.3-ultramodern.2",
162
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.3-ultramodern.2",
163
+ "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.3-ultramodern.2",
164
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.3-ultramodern.2",
165
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.3-ultramodern.2",
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.1",
172
- "@modern-js/plugin-bff": "npm:@bleedingdev/modern-js-plugin-bff@3.9.3-ultramodern.1",
173
- "@modern-js/plugin-tanstack": "npm:@bleedingdev/modern-js-plugin-tanstack@3.9.3-ultramodern.1",
174
- "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.3-ultramodern.1",
175
- "@modern-js/renderer-octane": "npm:@bleedingdev/modern-js-renderer-octane@3.9.3-ultramodern.1",
176
- "@modern-js/renderer-solid": "npm:@bleedingdev/modern-js-renderer-solid@3.9.3-ultramodern.1",
177
- "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.3-ultramodern.1",
178
- "@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.3-ultramodern.1",
179
- "@modern-js/server": "npm:@bleedingdev/modern-js-server@3.9.3-ultramodern.1",
180
- "@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.3-ultramodern.1",
171
+ "@modern-js/i18n-integration": "npm:@bleedingdev/modern-js-i18n-integration@3.9.3-ultramodern.2",
172
+ "@modern-js/plugin-bff": "npm:@bleedingdev/modern-js-plugin-bff@3.9.3-ultramodern.2",
173
+ "@modern-js/plugin-tanstack": "npm:@bleedingdev/modern-js-plugin-tanstack@3.9.3-ultramodern.2",
174
+ "@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.3-ultramodern.2",
175
+ "@modern-js/renderer-octane": "npm:@bleedingdev/modern-js-renderer-octane@3.9.3-ultramodern.2",
176
+ "@modern-js/renderer-solid": "npm:@bleedingdev/modern-js-renderer-solid@3.9.3-ultramodern.2",
177
+ "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.3-ultramodern.2",
178
+ "@modern-js/runtime-renderer-extensions": "npm:@bleedingdev/modern-js-runtime-renderer-extensions@3.9.3-ultramodern.2",
179
+ "@modern-js/server": "npm:@bleedingdev/modern-js-server@3.9.3-ultramodern.2",
180
+ "@modern-js/tsconfig": "npm:@bleedingdev/modern-js-tsconfig@3.9.3-ultramodern.2",
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.1",
240
- "@modern-js/renderer-octane": "3.9.3-ultramodern.1",
241
- "@modern-js/renderer-solid": "3.9.3-ultramodern.1",
242
- "@modern-js/runtime": "3.9.3-ultramodern.1",
243
- "@modern-js/runtime-renderer-extensions": "3.9.3-ultramodern.1",
239
+ "@modern-js/i18n-integration": "3.9.3-ultramodern.2",
240
+ "@modern-js/renderer-octane": "3.9.3-ultramodern.2",
241
+ "@modern-js/renderer-solid": "3.9.3-ultramodern.2",
242
+ "@modern-js/runtime": "3.9.3-ultramodern.2",
243
+ "@modern-js/runtime-renderer-extensions": "3.9.3-ultramodern.2",
244
244
  "@rsbuild/plugin-svgr": "2.0.5",
245
245
  "typescript": "7.0.2"
246
246
  },
@@ -7,6 +7,7 @@ import { mergeConfig } from '@modern-js/plugin/cli';
7
7
  import { type Renderer, resolveRenderer } from '@modern-js/renderer-core';
8
8
  import { type RspackChain, rspack } from '@rsbuild/core';
9
9
  import { ultramodernModuleFederationSharedPlugin } from '../renderers/react/module-federation-shared-plugin';
10
+ import { builderPluginServerMinify } from './server-minify';
10
11
  import { rendererTypeCheckerOptions } from './type-checker';
11
12
  import type { AppUserConfig } from './types';
12
13
 
@@ -26,6 +27,14 @@ export class UltramodernReleaseIdentityBannerPlugin extends rspack.BannerPlugin
26
27
  }
27
28
  }
28
29
 
30
+ /**
31
+ * Raw release identity banner. String statements extend the chunk's directive
32
+ * prologue, so a following `"use strict"` still applies; `void` expressions
33
+ * would end the prologue and silently turn every chunk sloppy.
34
+ */
35
+ export const releaseIdentityBanner = (values: readonly string[]): string =>
36
+ values.map(value => `${JSON.stringify(value)};`).join('');
37
+
29
38
  export function isUltramodernReleaseIdentityBannerPlugin(
30
39
  plugin: unknown,
31
40
  ): boolean {
@@ -287,7 +296,11 @@ const createRendererPreset = (
287
296
  config.plugins ??= [];
288
297
  config.plugins.push(
289
298
  new UltramodernReleaseIdentityBannerPlugin({
290
- banner: `void ${JSON.stringify(bundledReleaseIdentity.buildMarker)};void ${JSON.stringify(bundledReleaseIdentity.sourceRevision)};void ${JSON.stringify(bundledReleaseIdentity.releaseVersion)};`,
299
+ banner: releaseIdentityBanner([
300
+ bundledReleaseIdentity.buildMarker,
301
+ bundledReleaseIdentity.sourceRevision,
302
+ bundledReleaseIdentity.releaseVersion,
303
+ ]),
291
304
  raw: true,
292
305
  // The default additions stage runs before production
293
306
  // minimization, which removes side-effect-free identity
@@ -338,6 +351,7 @@ export const presetUltramodern = (
338
351
  ]);
339
352
  merged.builderPlugins = [
340
353
  builderPluginAdapterPrecompress(merged.output?.precompress),
354
+ builderPluginServerMinify(merged.output?.minify),
341
355
  ...(merged.builderPlugins ?? []),
342
356
  ];
343
357
  return merged;
@@ -0,0 +1,48 @@
1
+ import type { RsbuildConfig, RsbuildPlugin } from '@rsbuild/core';
2
+
3
+ type MinifyConfig = NonNullable<NonNullable<RsbuildConfig['output']>['minify']>;
4
+
5
+ /**
6
+ * Production minification for `node` environments.
7
+ *
8
+ * Rsbuild leaves server bundles unminified, so SSR and backend chunks ship
9
+ * dead framework branches and whitespace that every cold start parses. Names
10
+ * are kept: server logs, error classes and `constructor.name` checks read them,
11
+ * and keeping them costs a few percent of the minified size.
12
+ */
13
+ export const ULTRAMODERN_SERVER_MINIFY = {
14
+ js: true,
15
+ jsOptions: {
16
+ minimizerOptions: {
17
+ compress: { keep_classnames: true, keep_fnames: true },
18
+ mangle: { keep_classnames: true, keep_fnames: true },
19
+ },
20
+ },
21
+ } as const satisfies MinifyConfig;
22
+
23
+ /**
24
+ * Minify `node` environments unless the application chose `output.minify`.
25
+ *
26
+ * Runs in `modifyRsbuildConfig`, before Rsbuild fills its `!isServer` default,
27
+ * so an explicit app or environment value is still distinguishable and wins.
28
+ */
29
+ export const builderPluginServerMinify = (
30
+ appMinify: MinifyConfig | undefined,
31
+ ): RsbuildPlugin => ({
32
+ name: 'ultramodern:server-minify',
33
+ setup(api) {
34
+ if (appMinify !== undefined) return;
35
+ api.modifyRsbuildConfig(config => {
36
+ if (config.output?.minify !== undefined) return;
37
+ for (const environment of Object.values(config.environments ?? {})) {
38
+ const target = environment.output?.target ?? config.output?.target;
39
+ if (target !== 'node' || environment.output?.minify !== undefined)
40
+ continue;
41
+ environment.output = {
42
+ ...environment.output,
43
+ minify: ULTRAMODERN_SERVER_MINIFY,
44
+ };
45
+ }
46
+ });
47
+ },
48
+ });
@@ -23,7 +23,10 @@ import {
23
23
  writeRendererBuildManifest,
24
24
  } from '../../native-composition/native-build-manifest';
25
25
  import type { NativeInfrastructureOptions } from '../../native-composition/native-infrastructure';
26
- import { isUltramodernReleaseIdentityBannerPlugin } from '../../native-composition/preset';
26
+ import {
27
+ isUltramodernReleaseIdentityBannerPlugin,
28
+ releaseIdentityBanner,
29
+ } from '../../native-composition/preset';
27
30
  import {
28
31
  resolveRendererProfile,
29
32
  resolveRendererRouterFrameworks,
@@ -168,7 +171,7 @@ export function reactRendererBuildMetadataPlugin(
168
171
  // identity changes every emitted script's content hash.
169
172
  config.plugins.push(
170
173
  new rspack.BannerPlugin({
171
- banner: `void ${JSON.stringify(buildId)};void ${JSON.stringify(sourceRevision)};`,
174
+ banner: releaseIdentityBanner([buildId, sourceRevision]),
172
175
  raw: true,
173
176
  stage: rspack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
174
177
  test: /\.(?:c|m)?js$/u,