@bleedingdev/modern-js-ultramodern-app-tools 0.0.0 → 3.9.0-ultramodern.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/native-composition/index.js +131 -0
  3. package/dist/cjs/native-composition/preset.js +178 -0
  4. package/dist/cjs/native-composition/release-envelope-plugin.js +44 -0
  5. package/dist/cjs/native-composition/router-integration-plugin.js +55 -0
  6. package/dist/cjs/native-composition/router-runtime.js +66 -0
  7. package/dist/cjs/native-composition/rsc-disabled-plugin.js +117 -0
  8. package/dist/cjs/native-composition/server-plugin.js +50 -0
  9. package/dist/cjs/native-composition/ssr-integration-plugin.js +145 -0
  10. package/dist/cjs/native-composition/types.js +18 -0
  11. package/dist/esm/native-composition/index.mjs +71 -0
  12. package/dist/esm/native-composition/preset.mjs +126 -0
  13. package/dist/esm/native-composition/release-envelope-plugin.mjs +6 -0
  14. package/dist/esm/native-composition/router-integration-plugin.mjs +17 -0
  15. package/dist/esm/native-composition/router-runtime.mjs +26 -0
  16. package/dist/esm/native-composition/rsc-disabled-plugin.mjs +79 -0
  17. package/dist/esm/native-composition/server-plugin.mjs +1 -0
  18. package/dist/esm/native-composition/ssr-integration-plugin.mjs +104 -0
  19. package/dist/esm/native-composition/types.mjs +0 -0
  20. package/dist/esm-node/native-composition/index.mjs +72 -0
  21. package/dist/esm-node/native-composition/preset.mjs +127 -0
  22. package/dist/esm-node/native-composition/release-envelope-plugin.mjs +7 -0
  23. package/dist/esm-node/native-composition/router-integration-plugin.mjs +18 -0
  24. package/dist/esm-node/native-composition/router-runtime.mjs +27 -0
  25. package/dist/esm-node/native-composition/rsc-disabled-plugin.mjs +81 -0
  26. package/dist/esm-node/native-composition/server-plugin.mjs +2 -0
  27. package/dist/esm-node/native-composition/ssr-integration-plugin.mjs +105 -0
  28. package/dist/esm-node/native-composition/types.mjs +1 -0
  29. package/dist/types/native-composition/index.d.ts +6 -0
  30. package/dist/types/native-composition/preset.d.ts +86 -0
  31. package/dist/types/native-composition/release-envelope-plugin.d.ts +2 -0
  32. package/dist/types/native-composition/router-integration-plugin.d.ts +3 -0
  33. package/dist/types/native-composition/router-runtime.d.ts +4 -0
  34. package/dist/types/native-composition/rsc-disabled-plugin.d.ts +2 -0
  35. package/dist/types/native-composition/server-plugin.d.ts +1 -0
  36. package/dist/types/native-composition/ssr-integration-plugin.d.ts +7 -0
  37. package/dist/types/native-composition/types.d.ts +24 -0
  38. package/dist/types-esm/native-composition/index.d.mts +6 -0
  39. package/dist/types-esm/native-composition/preset.d.mts +86 -0
  40. package/dist/types-esm/native-composition/release-envelope-plugin.d.mts +2 -0
  41. package/dist/types-esm/native-composition/router-integration-plugin.d.mts +3 -0
  42. package/dist/types-esm/native-composition/router-runtime.d.mts +4 -0
  43. package/dist/types-esm/native-composition/rsc-disabled-plugin.d.mts +2 -0
  44. package/dist/types-esm/native-composition/server-plugin.d.mts +1 -0
  45. package/dist/types-esm/native-composition/ssr-integration-plugin.d.mts +7 -0
  46. package/dist/types-esm/native-composition/types.d.mts +24 -0
  47. package/package.json +100 -5
  48. package/src/native-composition/index.ts +92 -0
  49. package/src/native-composition/preset.ts +338 -0
  50. package/src/native-composition/release-envelope-plugin.ts +6 -0
  51. package/src/native-composition/router-integration-plugin.ts +20 -0
  52. package/src/native-composition/router-runtime.ts +28 -0
  53. package/src/native-composition/rsc-disabled-plugin.ts +117 -0
  54. package/src/native-composition/server-plugin.ts +1 -0
  55. package/src/native-composition/ssr-integration-plugin.ts +244 -0
  56. package/src/native-composition/types.ts +32 -0
  57. package/README.md +0 -3
@@ -0,0 +1,244 @@
1
+ // @effect-diagnostics globalConsole:off processEnv:off strictBooleanExpressions:off
2
+ import type {
3
+ AppTools,
4
+ AppToolsNormalizedConfig,
5
+ CliPlugin,
6
+ ServerUserConfig,
7
+ } from '@modern-js/app-tools';
8
+ import type { CLIPluginAPI } from '@modern-js/plugin';
9
+ import type { MergedEnvironmentConfig, RsbuildPlugin } from '@rsbuild/core';
10
+
11
+ type RsbuildRspackPluginLike =
12
+ | string
13
+ | ((...args: any[]) => any)
14
+ | {
15
+ name?: string;
16
+ constructor?: {
17
+ name?: string;
18
+ };
19
+ }
20
+ | [unknown, ...unknown[]];
21
+
22
+ type EnvironmentConfigLike = Partial<
23
+ Pick<MergedEnvironmentConfig, 'output' | 'source' | 'tools'>
24
+ >;
25
+
26
+ const getRspackPlugins = (rspackConfig: unknown): RsbuildRspackPluginLike[] => {
27
+ if (!rspackConfig) {
28
+ return [];
29
+ }
30
+
31
+ const rspackEntries = Array.isArray(rspackConfig)
32
+ ? rspackConfig
33
+ : [rspackConfig];
34
+ const plugins: RsbuildRspackPluginLike[] = [];
35
+
36
+ for (const entry of rspackEntries) {
37
+ if (!entry || typeof entry === 'function' || typeof entry !== 'object') {
38
+ continue;
39
+ }
40
+
41
+ const maybePlugins = (entry as { plugins?: unknown }).plugins;
42
+
43
+ if (!Array.isArray(maybePlugins)) {
44
+ continue;
45
+ }
46
+
47
+ for (const plugin of maybePlugins) {
48
+ if (plugin) {
49
+ plugins.push(plugin as RsbuildRspackPluginLike);
50
+ }
51
+ }
52
+ }
53
+
54
+ return plugins;
55
+ };
56
+
57
+ const getRspackPluginName = (
58
+ plugin: RsbuildRspackPluginLike,
59
+ ): string | undefined => {
60
+ if (typeof plugin === 'string') {
61
+ return plugin;
62
+ }
63
+
64
+ if (typeof plugin === 'function') {
65
+ return plugin.name;
66
+ }
67
+
68
+ if (Array.isArray(plugin)) {
69
+ const [first] = plugin;
70
+
71
+ if (!first) {
72
+ return undefined;
73
+ }
74
+
75
+ if (typeof first === 'string') {
76
+ return first;
77
+ }
78
+
79
+ if (typeof first === 'function') {
80
+ return first.name;
81
+ }
82
+
83
+ if (typeof first === 'object') {
84
+ return (
85
+ (first as { name?: string }).name ||
86
+ (first as { constructor?: { name?: string } }).constructor?.name
87
+ );
88
+ }
89
+
90
+ return undefined;
91
+ }
92
+
93
+ return plugin.name || plugin.constructor?.name;
94
+ };
95
+
96
+ const hasServerRenderingConfig = (
97
+ userConfig: AppToolsNormalizedConfig,
98
+ ): boolean => {
99
+ const { output, server } = userConfig;
100
+
101
+ if (output?.ssg) {
102
+ return true;
103
+ }
104
+
105
+ if (output?.ssgByEntries && Object.keys(output.ssgByEntries).length > 0) {
106
+ return true;
107
+ }
108
+
109
+ if (server?.ssr) {
110
+ return true;
111
+ }
112
+
113
+ if (server?.ssrByEntries && Object.keys(server.ssrByEntries).length > 0) {
114
+ return true;
115
+ }
116
+
117
+ return false;
118
+ };
119
+
120
+ const isModuleFederationAppSSREnabledInConfig = (
121
+ ssr: ServerUserConfig['ssr'],
122
+ ): boolean => {
123
+ if (!ssr || typeof ssr !== 'object') {
124
+ return false;
125
+ }
126
+
127
+ return ssr.moduleFederationAppSSR === true;
128
+ };
129
+
130
+ const isModuleFederationAppSSREnabled = (
131
+ userConfig: AppToolsNormalizedConfig,
132
+ ): boolean => {
133
+ if (isModuleFederationAppSSREnabledInConfig(userConfig.server?.ssr)) {
134
+ return true;
135
+ }
136
+
137
+ if (
138
+ userConfig.server?.ssrByEntries &&
139
+ typeof userConfig.server.ssrByEntries === 'object'
140
+ ) {
141
+ return Object.values(userConfig.server.ssrByEntries).some(
142
+ isModuleFederationAppSSREnabledInConfig,
143
+ );
144
+ }
145
+
146
+ return false;
147
+ };
148
+
149
+ const isModuleFederationRspackPlugin = (
150
+ plugin: RsbuildRspackPluginLike,
151
+ ): boolean => {
152
+ const candidate = getRspackPluginName(plugin);
153
+
154
+ return typeof candidate === 'string' && /modulefederation/i.test(candidate);
155
+ };
156
+
157
+ const hasModuleFederationMarker = (config: EnvironmentConfigLike): boolean => {
158
+ if (process.env.MF_SSR_PRJ === 'true') {
159
+ return true;
160
+ }
161
+
162
+ const define = config.source?.define || {};
163
+
164
+ if ('REMOTE_IP_STRATEGY' in define || 'FEDERATION_IPV4' in define) {
165
+ return true;
166
+ }
167
+
168
+ const plugins = getRspackPlugins(config.tools?.rspack);
169
+
170
+ return plugins.some(isModuleFederationRspackPlugin);
171
+ };
172
+
173
+ const isNodeEnvironmentTarget = (target: unknown): boolean =>
174
+ typeof target === 'string' &&
175
+ (target === 'node' || target === 'async-node' || target.startsWith('node'));
176
+
177
+ export const shouldUseModuleFederationNodeOutput = (
178
+ config: EnvironmentConfigLike,
179
+ ): boolean =>
180
+ isNodeEnvironmentTarget(config.output?.target) &&
181
+ hasModuleFederationMarker(config);
182
+
183
+ const ssrIntegrationBuilderPlugin = (
184
+ modernAPI: CLIPluginAPI<AppTools>,
185
+ ): RsbuildPlugin => ({
186
+ name: '@modern-js/ultramodern-builder-plugin-ssr',
187
+ pre: ['@modern-js/builder-plugin-ssr'],
188
+ setup(api) {
189
+ api.modifyEnvironmentConfig((config, { name, mergeEnvironmentConfig }) => {
190
+ const isServerEnvironment =
191
+ isNodeEnvironmentTarget(config.output.target) || name === 'workerSSR';
192
+ const userConfig = modernAPI.getNormalizedConfig();
193
+ const hasServerRendering = hasServerRenderingConfig(userConfig);
194
+ const hasModuleFederationRuntimeMarker =
195
+ hasServerRendering && shouldUseModuleFederationNodeOutput(config);
196
+ const hasExplicitMfSsrFlag = isModuleFederationAppSSREnabled(userConfig);
197
+ const requireExplicitMfSsrFlag =
198
+ process.env.MODERN_MF_APP_SSR_REQUIRE_EXPLICIT === 'true';
199
+
200
+ if (
201
+ hasServerRendering &&
202
+ hasModuleFederationRuntimeMarker &&
203
+ !hasExplicitMfSsrFlag
204
+ ) {
205
+ const warningMessage =
206
+ '[modernjs][mf-ssr] Module Federation SSR was auto-detected from runtime markers. Set server.ssr.moduleFederationAppSSR=true explicitly in host and remotes to avoid heuristic drift.';
207
+ if (requireExplicitMfSsrFlag) {
208
+ throw new Error(
209
+ `${warningMessage} (enforced by MODERN_MF_APP_SSR_REQUIRE_EXPLICIT=true)`,
210
+ );
211
+ }
212
+ // eslint-disable-next-line no-console
213
+ console.warn(warningMessage);
214
+ }
215
+ const isModuleFederationAppSSR =
216
+ hasServerRendering && hasExplicitMfSsrFlag;
217
+ return mergeEnvironmentConfig(config, {
218
+ source: {
219
+ define: {
220
+ 'process.env.MODERN_MF_APP_SSR': JSON.stringify(
221
+ String(isModuleFederationAppSSR),
222
+ ),
223
+ },
224
+ },
225
+ ...(name === 'workerSSR' && userConfig.deploy?.target === 'cloudflare'
226
+ ? { output: { module: true } }
227
+ : {}),
228
+ splitChunks:
229
+ isServerEnvironment &&
230
+ (hasModuleFederationRuntimeMarker || hasExplicitMfSsrFlag)
231
+ ? false
232
+ : undefined,
233
+ });
234
+ });
235
+ },
236
+ });
237
+
238
+ /** Apply fork SSR policy after native SSR defaults through Rsbuild hooks. */
239
+ export const ultramodernSSRIntegrationPlugin = (): CliPlugin<AppTools> => ({
240
+ name: '@modern-js/ultramodern-ssr-integration',
241
+ setup(api) {
242
+ api.config(() => ({ builderPlugins: [ssrIntegrationBuilderPlugin(api)] }));
243
+ },
244
+ });
@@ -0,0 +1,32 @@
1
+ import type { AppUserConfig as NativeAppUserConfig } from '@modern-js/app-tools';
2
+ import type { PrecompressConfig } from '@modern-js/app-tools-extensions/build-config/precompress/plugin';
3
+ import type { CloudflareDeployConfig } from '@modern-js/app-tools-extensions/config';
4
+ import type {
5
+ BffRuntimeUserConfig,
6
+ ServerTelemetryUserConfig,
7
+ } from '@modern-js/runtime-extensions/server-config';
8
+
9
+ type NativeServerConfig = NonNullable<NativeAppUserConfig['server']>;
10
+ type NativeSSRConfig = Exclude<NativeServerConfig['ssr'], boolean | undefined>;
11
+
12
+ /** Native Modern.js configuration with the fork's explicitly owned options. */
13
+ export type UltramodernAppUserConfig = Omit<
14
+ NativeAppUserConfig,
15
+ 'output' | 'server' | 'bff' | 'deploy'
16
+ > & {
17
+ output?: Omit<NonNullable<NativeAppUserConfig['output']>, 'precompress'> & {
18
+ precompress?: boolean | PrecompressConfig;
19
+ };
20
+ server?: Omit<NativeServerConfig, 'ssr' | 'telemetry'> & {
21
+ ssr?: boolean | (NativeSSRConfig & { moduleFederationAppSSR?: boolean });
22
+ telemetry?: ServerTelemetryUserConfig;
23
+ };
24
+ bff?: Omit<
25
+ NonNullable<NativeAppUserConfig['bff']>,
26
+ keyof BffRuntimeUserConfig
27
+ > &
28
+ BffRuntimeUserConfig & { requestId?: string };
29
+ deploy?: NonNullable<NativeAppUserConfig['deploy']> & CloudflareDeployConfig;
30
+ };
31
+
32
+ export type AppUserConfig = UltramodernAppUserConfig;
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # @bleedingdev/modern-js-ultramodern-app-tools
2
-
3
- This 0.0.0 version only registers the package name so npm trusted publishing can be configured. It contains no runtime implementation. Use the subsequent UltraModern.js release, published from the repository workflow with provenance.