@bleedingdev/modern-js-server-core 3.2.0-ultramodern.11 → 3.2.0-ultramodern.111

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 (72) hide show
  1. package/dist/cjs/adapters/node/helper/index.js +9 -5
  2. package/dist/cjs/adapters/node/helper/loadCache.js +9 -5
  3. package/dist/cjs/adapters/node/helper/loadConfig.js +9 -5
  4. package/dist/cjs/adapters/node/helper/loadEnv.js +9 -5
  5. package/dist/cjs/adapters/node/helper/loadPlugin.js +9 -5
  6. package/dist/cjs/adapters/node/helper/utils.js +12 -8
  7. package/dist/cjs/adapters/node/hono.js +9 -5
  8. package/dist/cjs/adapters/node/index.js +9 -5
  9. package/dist/cjs/adapters/node/node.js +9 -5
  10. package/dist/cjs/adapters/node/plugins/index.js +9 -5
  11. package/dist/cjs/adapters/node/plugins/moduleFederationCss.js +176 -0
  12. package/dist/cjs/adapters/node/plugins/nodeServer.js +12 -8
  13. package/dist/cjs/adapters/node/plugins/resource.js +15 -6
  14. package/dist/cjs/adapters/node/plugins/static.js +9 -5
  15. package/dist/cjs/constants.js +18 -13
  16. package/dist/cjs/context.js +9 -5
  17. package/dist/cjs/helper.js +12 -8
  18. package/dist/cjs/hono.js +9 -5
  19. package/dist/cjs/index.js +26 -22
  20. package/dist/cjs/plugins/compat/hooks.js +14 -10
  21. package/dist/cjs/plugins/compat/index.js +9 -5
  22. package/dist/cjs/plugins/contractGateAutopilot.js +9 -5
  23. package/dist/cjs/plugins/contractGateSnapshotStore.js +9 -5
  24. package/dist/cjs/plugins/default.js +9 -5
  25. package/dist/cjs/plugins/favicon.js +12 -8
  26. package/dist/cjs/plugins/index.js +9 -5
  27. package/dist/cjs/plugins/log.js +9 -5
  28. package/dist/cjs/plugins/mfCache.js +15 -11
  29. package/dist/cjs/plugins/middlewares.js +12 -8
  30. package/dist/cjs/plugins/monitors.js +9 -5
  31. package/dist/cjs/plugins/processedBy.js +12 -8
  32. package/dist/cjs/plugins/render/csrRscRender.js +11 -5
  33. package/dist/cjs/plugins/render/dataHandler.js +9 -5
  34. package/dist/cjs/plugins/render/index.js +12 -8
  35. package/dist/cjs/plugins/render/inject.js +9 -5
  36. package/dist/cjs/plugins/render/render.js +9 -5
  37. package/dist/cjs/plugins/render/renderRscHandler.js +11 -5
  38. package/dist/cjs/plugins/render/serverActionHandler.js +9 -5
  39. package/dist/cjs/plugins/render/ssrCache.js +9 -5
  40. package/dist/cjs/plugins/render/ssrRender.js +11 -5
  41. package/dist/cjs/plugins/render/utils.js +12 -8
  42. package/dist/cjs/plugins/route.js +9 -5
  43. package/dist/cjs/plugins/telemetry.js +9 -5
  44. package/dist/cjs/serverBase.js +9 -5
  45. package/dist/cjs/types/config/index.js +9 -5
  46. package/dist/cjs/types/index.js +9 -5
  47. package/dist/cjs/types/plugins/index.js +9 -5
  48. package/dist/cjs/utils/entry.js +13 -9
  49. package/dist/cjs/utils/env.js +13 -9
  50. package/dist/cjs/utils/error.js +9 -5
  51. package/dist/cjs/utils/index.js +9 -5
  52. package/dist/cjs/utils/middlewareCollector.js +13 -9
  53. package/dist/cjs/utils/publicDir.js +9 -5
  54. package/dist/cjs/utils/request.js +16 -12
  55. package/dist/cjs/utils/serverConfig.js +9 -5
  56. package/dist/cjs/utils/storage.js +9 -5
  57. package/dist/cjs/utils/transformStream.js +13 -9
  58. package/dist/cjs/utils/warmup.js +12 -8
  59. package/dist/esm/adapters/node/plugins/moduleFederationCss.mjs +125 -0
  60. package/dist/esm/adapters/node/plugins/resource.mjs +6 -1
  61. package/dist/esm/plugins/render/csrRscRender.mjs +2 -0
  62. package/dist/esm/plugins/render/renderRscHandler.mjs +2 -0
  63. package/dist/esm/plugins/render/ssrRender.mjs +2 -0
  64. package/dist/esm-node/adapters/node/plugins/moduleFederationCss.mjs +126 -0
  65. package/dist/esm-node/adapters/node/plugins/resource.mjs +6 -1
  66. package/dist/esm-node/plugins/render/csrRscRender.mjs +2 -0
  67. package/dist/esm-node/plugins/render/renderRscHandler.mjs +2 -0
  68. package/dist/esm-node/plugins/render/ssrRender.mjs +2 -0
  69. package/dist/types/adapters/node/plugins/moduleFederationCss.d.ts +33 -0
  70. package/dist/types/types/requestHandler.d.ts +1 -0
  71. package/dist/types/types/server.d.ts +1 -0
  72. package/package.json +12 -12
@@ -0,0 +1,125 @@
1
+ import { fileReader } from "@modern-js/runtime-utils/fileReader";
2
+ import { fs } from "@modern-js/utils";
3
+ import path from "path";
4
+ const MODULE_FEDERATION_MANIFEST_FILE = 'mf-manifest.json';
5
+ const DEFAULT_REMOTE_MANIFEST_TIMEOUT = 1500;
6
+ const warn = (monitors, message, ...args)=>{
7
+ if (monitors) return void monitors.warn(message, ...args);
8
+ console.warn(message, ...args);
9
+ };
10
+ const ensureTrailingSlash = (value)=>value.endsWith('/') ? value : `${value}/`;
11
+ const tryResolveUrl = (value, base)=>{
12
+ try {
13
+ return new URL(value, base).toString();
14
+ } catch {
15
+ return;
16
+ }
17
+ };
18
+ const normalizeRemoteEntry = (entry)=>{
19
+ const value = entry.trim();
20
+ if (!value) return;
21
+ const atIndex = value.lastIndexOf('@');
22
+ return atIndex >= 0 ? value.slice(atIndex + 1) : value;
23
+ };
24
+ const getCssAssets = (assets)=>[
25
+ ...assets?.css?.sync || [],
26
+ ...assets?.css?.async || []
27
+ ];
28
+ const getManifestFallbackBase = (manifestUrl)=>{
29
+ try {
30
+ return new URL('.', manifestUrl).toString();
31
+ } catch {
32
+ return ensureTrailingSlash(manifestUrl);
33
+ }
34
+ };
35
+ const getManifestPublicPathBase = (publicPath, manifestUrl)=>{
36
+ if (!publicPath || 'auto' === publicPath) return getManifestFallbackBase(manifestUrl);
37
+ const base = tryResolveUrl(ensureTrailingSlash(publicPath), manifestUrl);
38
+ return base || getManifestFallbackBase(manifestUrl);
39
+ };
40
+ const appendResolvedCssAssets = (result, seen, assets, base)=>{
41
+ for (const asset of assets){
42
+ if (!asset) continue;
43
+ const resolved = tryResolveUrl(asset, base);
44
+ if (resolved && !seen.has(resolved)) {
45
+ seen.add(resolved);
46
+ result.push(resolved);
47
+ }
48
+ }
49
+ };
50
+ const collectModuleFederationManifestCss = (manifest, manifestUrl)=>{
51
+ const base = getManifestPublicPathBase(manifest.metaData?.publicPath, manifestUrl);
52
+ const result = [];
53
+ const seen = new Set();
54
+ for (const item of manifest.shared || [])appendResolvedCssAssets(result, seen, getCssAssets(item.assets), base);
55
+ for (const item of manifest.exposes || [])appendResolvedCssAssets(result, seen, getCssAssets(item.assets), base);
56
+ return result;
57
+ };
58
+ const fetchJsonWithTimeout = async (url, fetcher, timeout)=>{
59
+ const controller = new AbortController();
60
+ let timeoutId;
61
+ try {
62
+ const response = await Promise.race([
63
+ fetcher(url, {
64
+ signal: controller.signal
65
+ }),
66
+ new Promise((_, reject)=>{
67
+ timeoutId = setTimeout(()=>{
68
+ controller.abort();
69
+ reject(new Error(`Request timed out after ${timeout}ms`));
70
+ }, timeout);
71
+ })
72
+ ]);
73
+ if (!response.ok) throw new Error(`Unexpected status ${response.status}`);
74
+ return await response.json();
75
+ } finally{
76
+ if (timeoutId) clearTimeout(timeoutId);
77
+ }
78
+ };
79
+ const getHostManifest = async (pwd, monitors)=>{
80
+ const manifestPath = path.join(pwd, MODULE_FEDERATION_MANIFEST_FILE);
81
+ if (!await fs.pathExists(manifestPath)) return;
82
+ const manifestBuffer = await fileReader.readFileFromSystem(manifestPath, 'buffer');
83
+ if (null === manifestBuffer) return;
84
+ try {
85
+ return JSON.parse(manifestBuffer.toString('utf-8'));
86
+ } catch (error) {
87
+ warn(monitors, 'Parse module federation manifest failed, error = %s', error instanceof Error ? error.message : error);
88
+ return;
89
+ }
90
+ };
91
+ const collectDirectRemoteModuleFederationCss = async (pwd, options = {})=>{
92
+ const hostManifest = await getHostManifest(pwd, options.monitors);
93
+ if (!hostManifest) return [];
94
+ const fetcher = options.fetcher || globalThis.fetch?.bind(globalThis);
95
+ if (!fetcher) {
96
+ warn(options.monitors, 'Skip module federation remote CSS collection because fetch is unavailable.');
97
+ return [];
98
+ }
99
+ const timeout = options.timeout ?? DEFAULT_REMOTE_MANIFEST_TIMEOUT;
100
+ const cssAssets = [];
101
+ const seen = new Set();
102
+ for (const remote of hostManifest.remotes || []){
103
+ if (!remote.entry) continue;
104
+ const remoteEntry = normalizeRemoteEntry(remote.entry);
105
+ if (!remoteEntry) continue;
106
+ let remoteManifestUrl;
107
+ try {
108
+ remoteManifestUrl = new URL(remoteEntry).toString();
109
+ } catch {
110
+ warn(options.monitors, 'Skip module federation remote CSS collection for non-absolute manifest URL %s', remoteEntry);
111
+ continue;
112
+ }
113
+ try {
114
+ const remoteManifest = await fetchJsonWithTimeout(remoteManifestUrl, fetcher, timeout);
115
+ for (const asset of collectModuleFederationManifestCss(remoteManifest, remoteManifestUrl))if (!seen.has(asset)) {
116
+ seen.add(asset);
117
+ cssAssets.push(asset);
118
+ }
119
+ } catch (error) {
120
+ warn(options.monitors, 'Load module federation remote manifest %s failed, error = %s', remoteManifestUrl, error instanceof Error ? error.message : error);
121
+ }
122
+ }
123
+ return cssAssets;
124
+ };
125
+ export { collectDirectRemoteModuleFederationCss, collectModuleFederationManifestCss };
@@ -2,6 +2,7 @@ import { fileReader } from "@modern-js/runtime-utils/fileReader";
2
2
  import { LOADABLE_STATS_FILE, MAIN_ENTRY_NAME, NESTED_ROUTE_SPEC_FILE, ROUTE_MANIFEST_FILE, SERVER_BUNDLE_DIRECTORY, compatibleRequire, fs, isProd } from "@modern-js/utils";
3
3
  import path from "path";
4
4
  import { uniqueKeyByRoute } from "../../../utils/index.mjs";
5
+ import { collectDirectRemoteModuleFederationCss } from "./moduleFederationCss.mjs";
5
6
  async function getHtmlTemplates(pwd, routes) {
6
7
  const htmlRoutes = routes.filter((route)=>route.entryName);
7
8
  const htmls = await Promise.all(htmlRoutes.map(async (route)=>{
@@ -56,12 +57,16 @@ async function getServerManifest(pwd, routes, monitors) {
56
57
  const routeManifest = await compatibleRequire(routesManifestUri).catch((_)=>({}));
57
58
  const nestedRoutesJsonPath = path.join(pwd, NESTED_ROUTE_SPEC_FILE);
58
59
  const nestedRoutesJson = await compatibleRequire(nestedRoutesJsonPath).catch((_)=>({}));
60
+ const moduleFederationCssAssets = await collectDirectRemoteModuleFederationCss(pwd, {
61
+ monitors
62
+ });
59
63
  return {
60
64
  loaderBundles,
61
65
  renderBundles,
62
66
  loadableStats,
63
67
  routeManifest,
64
- nestedRoutesJson
68
+ nestedRoutesJson,
69
+ moduleFederationCssAssets
65
70
  };
66
71
  }
67
72
  function injectServerManifest(pwd, routes, manifestPromise) {
@@ -5,12 +5,14 @@ const csrRscRender = async (req, options)=>{
5
5
  const serverBundle = serverManifest?.renderBundles?.[routeInfo.entryName || MAIN_ENTRY_NAME];
6
6
  const loadableStats = serverManifest.loadableStats || {};
7
7
  const routeManifest = serverManifest.routeManifest || {};
8
+ const moduleFederationCssAssets = serverManifest.moduleFederationCssAssets || [];
8
9
  const config = createRequestHandlerConfig(options.config);
9
10
  const requestHandlerOptions = {
10
11
  resource: {
11
12
  route: routeInfo,
12
13
  loadableStats,
13
14
  routeManifest,
15
+ moduleFederationCssAssets,
14
16
  entryName: routeInfo.entryName || MAIN_ENTRY_NAME
15
17
  },
16
18
  config,
@@ -5,12 +5,14 @@ const renderRscHandler = async (req, options)=>{
5
5
  const serverBundle = serverManifest?.renderBundles?.[routeInfo.entryName || MAIN_ENTRY_NAME];
6
6
  const loadableStats = serverManifest.loadableStats || {};
7
7
  const routeManifest = serverManifest.routeManifest || {};
8
+ const moduleFederationCssAssets = serverManifest.moduleFederationCssAssets || [];
8
9
  const config = createRequestHandlerConfig(options.config);
9
10
  const requestHandlerOptions = {
10
11
  resource: {
11
12
  route: routeInfo,
12
13
  loadableStats,
13
14
  routeManifest,
15
+ moduleFederationCssAssets,
14
16
  entryName: routeInfo.entryName || MAIN_ENTRY_NAME
15
17
  },
16
18
  config,
@@ -8,6 +8,7 @@ async function ssrRender(request, { routeInfo, html, config: userConfig, staticG
8
8
  const { entryName } = routeInfo;
9
9
  const loadableStats = serverManifest.loadableStats || {};
10
10
  const routeManifest = serverManifest.routeManifest || {};
11
+ const moduleFederationCssAssets = serverManifest.moduleFederationCssAssets || [];
11
12
  const headers = parseHeaders(request);
12
13
  if (nodeReq) {
13
14
  for(const key in nodeReq.headers)if (!headers[key]) headers[key] = nodeReq.headers[key];
@@ -21,6 +22,7 @@ async function ssrRender(request, { routeInfo, html, config: userConfig, staticG
21
22
  route: routeInfo,
22
23
  loadableStats,
23
24
  routeManifest,
25
+ moduleFederationCssAssets,
24
26
  htmlTemplate: html,
25
27
  entryName: entryName || MAIN_ENTRY_NAME
26
28
  },
@@ -0,0 +1,126 @@
1
+ import "node:module";
2
+ import { fileReader } from "@modern-js/runtime-utils/fileReader";
3
+ import { fs } from "@modern-js/utils";
4
+ import path from "path";
5
+ const MODULE_FEDERATION_MANIFEST_FILE = 'mf-manifest.json';
6
+ const DEFAULT_REMOTE_MANIFEST_TIMEOUT = 1500;
7
+ const warn = (monitors, message, ...args)=>{
8
+ if (monitors) return void monitors.warn(message, ...args);
9
+ console.warn(message, ...args);
10
+ };
11
+ const ensureTrailingSlash = (value)=>value.endsWith('/') ? value : `${value}/`;
12
+ const tryResolveUrl = (value, base)=>{
13
+ try {
14
+ return new URL(value, base).toString();
15
+ } catch {
16
+ return;
17
+ }
18
+ };
19
+ const normalizeRemoteEntry = (entry)=>{
20
+ const value = entry.trim();
21
+ if (!value) return;
22
+ const atIndex = value.lastIndexOf('@');
23
+ return atIndex >= 0 ? value.slice(atIndex + 1) : value;
24
+ };
25
+ const getCssAssets = (assets)=>[
26
+ ...assets?.css?.sync || [],
27
+ ...assets?.css?.async || []
28
+ ];
29
+ const getManifestFallbackBase = (manifestUrl)=>{
30
+ try {
31
+ return new URL('.', manifestUrl).toString();
32
+ } catch {
33
+ return ensureTrailingSlash(manifestUrl);
34
+ }
35
+ };
36
+ const getManifestPublicPathBase = (publicPath, manifestUrl)=>{
37
+ if (!publicPath || 'auto' === publicPath) return getManifestFallbackBase(manifestUrl);
38
+ const base = tryResolveUrl(ensureTrailingSlash(publicPath), manifestUrl);
39
+ return base || getManifestFallbackBase(manifestUrl);
40
+ };
41
+ const appendResolvedCssAssets = (result, seen, assets, base)=>{
42
+ for (const asset of assets){
43
+ if (!asset) continue;
44
+ const resolved = tryResolveUrl(asset, base);
45
+ if (resolved && !seen.has(resolved)) {
46
+ seen.add(resolved);
47
+ result.push(resolved);
48
+ }
49
+ }
50
+ };
51
+ const collectModuleFederationManifestCss = (manifest, manifestUrl)=>{
52
+ const base = getManifestPublicPathBase(manifest.metaData?.publicPath, manifestUrl);
53
+ const result = [];
54
+ const seen = new Set();
55
+ for (const item of manifest.shared || [])appendResolvedCssAssets(result, seen, getCssAssets(item.assets), base);
56
+ for (const item of manifest.exposes || [])appendResolvedCssAssets(result, seen, getCssAssets(item.assets), base);
57
+ return result;
58
+ };
59
+ const fetchJsonWithTimeout = async (url, fetcher, timeout)=>{
60
+ const controller = new AbortController();
61
+ let timeoutId;
62
+ try {
63
+ const response = await Promise.race([
64
+ fetcher(url, {
65
+ signal: controller.signal
66
+ }),
67
+ new Promise((_, reject)=>{
68
+ timeoutId = setTimeout(()=>{
69
+ controller.abort();
70
+ reject(new Error(`Request timed out after ${timeout}ms`));
71
+ }, timeout);
72
+ })
73
+ ]);
74
+ if (!response.ok) throw new Error(`Unexpected status ${response.status}`);
75
+ return await response.json();
76
+ } finally{
77
+ if (timeoutId) clearTimeout(timeoutId);
78
+ }
79
+ };
80
+ const getHostManifest = async (pwd, monitors)=>{
81
+ const manifestPath = path.join(pwd, MODULE_FEDERATION_MANIFEST_FILE);
82
+ if (!await fs.pathExists(manifestPath)) return;
83
+ const manifestBuffer = await fileReader.readFileFromSystem(manifestPath, 'buffer');
84
+ if (null === manifestBuffer) return;
85
+ try {
86
+ return JSON.parse(manifestBuffer.toString('utf-8'));
87
+ } catch (error) {
88
+ warn(monitors, 'Parse module federation manifest failed, error = %s', error instanceof Error ? error.message : error);
89
+ return;
90
+ }
91
+ };
92
+ const collectDirectRemoteModuleFederationCss = async (pwd, options = {})=>{
93
+ const hostManifest = await getHostManifest(pwd, options.monitors);
94
+ if (!hostManifest) return [];
95
+ const fetcher = options.fetcher || globalThis.fetch?.bind(globalThis);
96
+ if (!fetcher) {
97
+ warn(options.monitors, 'Skip module federation remote CSS collection because fetch is unavailable.');
98
+ return [];
99
+ }
100
+ const timeout = options.timeout ?? DEFAULT_REMOTE_MANIFEST_TIMEOUT;
101
+ const cssAssets = [];
102
+ const seen = new Set();
103
+ for (const remote of hostManifest.remotes || []){
104
+ if (!remote.entry) continue;
105
+ const remoteEntry = normalizeRemoteEntry(remote.entry);
106
+ if (!remoteEntry) continue;
107
+ let remoteManifestUrl;
108
+ try {
109
+ remoteManifestUrl = new URL(remoteEntry).toString();
110
+ } catch {
111
+ warn(options.monitors, 'Skip module federation remote CSS collection for non-absolute manifest URL %s', remoteEntry);
112
+ continue;
113
+ }
114
+ try {
115
+ const remoteManifest = await fetchJsonWithTimeout(remoteManifestUrl, fetcher, timeout);
116
+ for (const asset of collectModuleFederationManifestCss(remoteManifest, remoteManifestUrl))if (!seen.has(asset)) {
117
+ seen.add(asset);
118
+ cssAssets.push(asset);
119
+ }
120
+ } catch (error) {
121
+ warn(options.monitors, 'Load module federation remote manifest %s failed, error = %s', remoteManifestUrl, error instanceof Error ? error.message : error);
122
+ }
123
+ }
124
+ return cssAssets;
125
+ };
126
+ export { collectDirectRemoteModuleFederationCss, collectModuleFederationManifestCss };
@@ -3,6 +3,7 @@ import { fileReader } from "@modern-js/runtime-utils/fileReader";
3
3
  import { LOADABLE_STATS_FILE, MAIN_ENTRY_NAME, NESTED_ROUTE_SPEC_FILE, ROUTE_MANIFEST_FILE, SERVER_BUNDLE_DIRECTORY, compatibleRequire, fs, isProd } from "@modern-js/utils";
4
4
  import path from "path";
5
5
  import { uniqueKeyByRoute } from "../../../utils/index.mjs";
6
+ import { collectDirectRemoteModuleFederationCss } from "./moduleFederationCss.mjs";
6
7
  async function getHtmlTemplates(pwd, routes) {
7
8
  const htmlRoutes = routes.filter((route)=>route.entryName);
8
9
  const htmls = await Promise.all(htmlRoutes.map(async (route)=>{
@@ -57,12 +58,16 @@ async function getServerManifest(pwd, routes, monitors) {
57
58
  const routeManifest = await compatibleRequire(routesManifestUri).catch((_)=>({}));
58
59
  const nestedRoutesJsonPath = path.join(pwd, NESTED_ROUTE_SPEC_FILE);
59
60
  const nestedRoutesJson = await compatibleRequire(nestedRoutesJsonPath).catch((_)=>({}));
61
+ const moduleFederationCssAssets = await collectDirectRemoteModuleFederationCss(pwd, {
62
+ monitors
63
+ });
60
64
  return {
61
65
  loaderBundles,
62
66
  renderBundles,
63
67
  loadableStats,
64
68
  routeManifest,
65
- nestedRoutesJson
69
+ nestedRoutesJson,
70
+ moduleFederationCssAssets
66
71
  };
67
72
  }
68
73
  function injectServerManifest(pwd, routes, manifestPromise) {
@@ -6,12 +6,14 @@ const csrRscRender = async (req, options)=>{
6
6
  const serverBundle = serverManifest?.renderBundles?.[routeInfo.entryName || MAIN_ENTRY_NAME];
7
7
  const loadableStats = serverManifest.loadableStats || {};
8
8
  const routeManifest = serverManifest.routeManifest || {};
9
+ const moduleFederationCssAssets = serverManifest.moduleFederationCssAssets || [];
9
10
  const config = createRequestHandlerConfig(options.config);
10
11
  const requestHandlerOptions = {
11
12
  resource: {
12
13
  route: routeInfo,
13
14
  loadableStats,
14
15
  routeManifest,
16
+ moduleFederationCssAssets,
15
17
  entryName: routeInfo.entryName || MAIN_ENTRY_NAME
16
18
  },
17
19
  config,
@@ -6,12 +6,14 @@ const renderRscHandler = async (req, options)=>{
6
6
  const serverBundle = serverManifest?.renderBundles?.[routeInfo.entryName || MAIN_ENTRY_NAME];
7
7
  const loadableStats = serverManifest.loadableStats || {};
8
8
  const routeManifest = serverManifest.routeManifest || {};
9
+ const moduleFederationCssAssets = serverManifest.moduleFederationCssAssets || [];
9
10
  const config = createRequestHandlerConfig(options.config);
10
11
  const requestHandlerOptions = {
11
12
  resource: {
12
13
  route: routeInfo,
13
14
  loadableStats,
14
15
  routeManifest,
16
+ moduleFederationCssAssets,
15
17
  entryName: routeInfo.entryName || MAIN_ENTRY_NAME
16
18
  },
17
19
  config,
@@ -9,6 +9,7 @@ async function ssrRender(request, { routeInfo, html, config: userConfig, staticG
9
9
  const { entryName } = routeInfo;
10
10
  const loadableStats = serverManifest.loadableStats || {};
11
11
  const routeManifest = serverManifest.routeManifest || {};
12
+ const moduleFederationCssAssets = serverManifest.moduleFederationCssAssets || [];
12
13
  const headers = parseHeaders(request);
13
14
  if (nodeReq) {
14
15
  for(const key in nodeReq.headers)if (!headers[key]) headers[key] = nodeReq.headers[key];
@@ -22,6 +23,7 @@ async function ssrRender(request, { routeInfo, html, config: userConfig, staticG
22
23
  route: routeInfo,
23
24
  loadableStats,
24
25
  routeManifest,
26
+ moduleFederationCssAssets,
25
27
  htmlTemplate: html,
26
28
  entryName: entryName || MAIN_ENTRY_NAME
27
29
  },
@@ -0,0 +1,33 @@
1
+ import type { Monitors } from '@modern-js/types';
2
+ type ModuleFederationAssets = {
3
+ css?: {
4
+ sync?: string[];
5
+ async?: string[];
6
+ };
7
+ };
8
+ export type ModuleFederationManifest = {
9
+ metaData?: {
10
+ publicPath?: string;
11
+ };
12
+ shared?: Array<{
13
+ assets?: ModuleFederationAssets;
14
+ }>;
15
+ remotes?: Array<{
16
+ entry?: string;
17
+ assets?: ModuleFederationAssets;
18
+ }>;
19
+ exposes?: Array<{
20
+ assets?: ModuleFederationAssets;
21
+ }>;
22
+ };
23
+ type FetchLike = (input: string, init?: {
24
+ signal?: AbortSignal;
25
+ }) => Promise<Response>;
26
+ export type CollectDirectRemoteModuleFederationCssOptions = {
27
+ fetcher?: FetchLike;
28
+ monitors?: Monitors;
29
+ timeout?: number;
30
+ };
31
+ export declare const collectModuleFederationManifestCss: (manifest: ModuleFederationManifest, manifestUrl: string) => string[];
32
+ export declare const collectDirectRemoteModuleFederationCss: (pwd: string, options?: CollectDirectRemoteModuleFederationCssOptions) => Promise<string[]>;
33
+ export {};
@@ -7,6 +7,7 @@ export type Resource = {
7
7
  route: ServerRoute;
8
8
  htmlTemplate: string;
9
9
  entryName: string;
10
+ moduleFederationCssAssets?: string[];
10
11
  };
11
12
  export type Params = Record<string, any>;
12
13
  export type RequestHandlerConfig = {
@@ -32,6 +32,7 @@ export type ServerManifest = {
32
32
  loadableStats?: Record<string, any>;
33
33
  routeManifest?: Record<string, any>;
34
34
  nestedRoutesJson?: Record<string, any>;
35
+ moduleFederationCssAssets?: string[];
35
36
  };
36
37
  type ServerVariables = {
37
38
  /** @deprecated */
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.2.0-ultramodern.11",
20
+ "version": "3.2.0-ultramodern.111",
21
21
  "types": "./dist/types/index.d.ts",
22
22
  "main": "./dist/cjs/index.js",
23
23
  "exports": {
@@ -68,27 +68,27 @@
68
68
  "node": ">=20"
69
69
  },
70
70
  "dependencies": {
71
- "@swc/helpers": "^0.5.21",
71
+ "@swc/helpers": "^0.5.23",
72
72
  "@web-std/fetch": "^4.2.1",
73
73
  "@web-std/file": "^3.0.3",
74
74
  "@web-std/stream": "^1.0.3",
75
75
  "cloneable-readable": "^3.0.0",
76
76
  "flatted": "^3.4.2",
77
- "hono": "^4.12.19",
78
- "ts-deepmerge": "7.0.3",
79
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.2.0-ultramodern.11",
80
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.2.0-ultramodern.11",
81
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.2.0-ultramodern.11"
77
+ "hono": "^4.12.22",
78
+ "ts-deepmerge": "8.0.0",
79
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.2.0-ultramodern.111",
80
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.2.0-ultramodern.111",
81
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.2.0-ultramodern.111"
82
82
  },
83
83
  "devDependencies": {
84
84
  "@rslib/core": "0.21.5",
85
85
  "@types/cloneable-readable": "^2.0.3",
86
86
  "@types/merge-deep": "^3.0.3",
87
- "@types/node": "^25.8.0",
88
- "@typescript/native-preview": "7.0.0-dev.20260516.1",
87
+ "@types/node": "^25.9.1",
88
+ "@typescript/native-preview": "7.0.0-dev.20260606.1",
89
89
  "http-proxy-middleware": "^4.0.0",
90
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.2.0-ultramodern.11",
91
- "@scripts/rstest-config": "2.66.0"
90
+ "@scripts/rstest-config": "2.66.0",
91
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.2.0-ultramodern.111"
92
92
  },
93
93
  "sideEffects": false,
94
94
  "publishConfig": {
@@ -97,7 +97,7 @@
97
97
  },
98
98
  "scripts": {
99
99
  "dev": "rslib build --watch",
100
- "build": "rslib build",
100
+ "build": "rslib build && pnpm -w tsgo:dts \"$PWD\"",
101
101
  "test": "rstest --passWithNoTests"
102
102
  }
103
103
  }