@bleedingdev/modern-js-server-core 3.5.0-ultramodern.4 → 3.5.0-ultramodern.41

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.
@@ -41,15 +41,11 @@ __webpack_require__.d(__webpack_exports__, {
41
41
  createStaticMiddleware: ()=>createStaticMiddleware,
42
42
  serverStaticPlugin: ()=>serverStaticPlugin
43
43
  });
44
- const fileReader_namespaceObject = require("@modern-js/runtime-utils/fileReader");
45
- const utils_namespaceObject = require("@modern-js/utils");
46
- const mime_namespaceObject = require("hono/utils/mime");
47
44
  const external_path_namespaceObject = require("path");
48
45
  var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
49
46
  const index_js_namespaceObject = require("../../../utils/index.js");
50
47
  const publicDir_js_namespaceObject = require("../../../utils/publicDir.js");
51
- const external_staticModuleFederation_js_namespaceObject = require("./staticModuleFederation.js");
52
- const external_staticPrecompressed_js_namespaceObject = require("./staticPrecompressed.js");
48
+ const external_staticServing_js_namespaceObject = require("./staticServing.js");
53
49
  const serverStaticPlugin = ()=>({
54
50
  name: '@modern-js/plugin-server-static',
55
51
  setup (api) {
@@ -74,22 +70,8 @@ function createPublicMiddleware({ pwd, routes }) {
74
70
  return async (c, next)=>{
75
71
  const route = matchPublicRoute(c.req, routes);
76
72
  if (route) {
77
- const { entryPath } = route;
78
- const originFilename = external_path_default().join(pwd, entryPath);
79
- const preCompressedAsset = await (0, external_staticPrecompressed_js_namespaceObject.resolvePreCompressedAsset)(c, originFilename);
80
- const filename = preCompressedAsset.selected?.filepath ?? originFilename;
81
- const data = await fileReader_namespaceObject.fileReader.readFile(filename, 'buffer');
82
- const mimeType = (0, mime_namespaceObject.getMimeType)(originFilename);
83
- if (null !== data) {
84
- const body = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
85
- if (mimeType) c.header('Content-Type', mimeType);
86
- Object.entries(route.responseHeaders || {}).forEach(([k, v])=>{
87
- c.header(k, v);
88
- });
89
- (0, external_staticPrecompressed_js_namespaceObject.applyPreCompressedAssetHeaders)(c, preCompressedAsset);
90
- c.header('Content-Length', String(data.byteLength));
91
- return c.body(body, 200);
92
- }
73
+ const response = await (0, external_staticServing_js_namespaceObject.servePreCompressedPublicRouteAsset)(c, pwd, route);
74
+ if (null !== response) return response;
93
75
  }
94
76
  return await next();
95
77
  };
@@ -140,54 +122,24 @@ function createStaticMiddleware(options) {
140
122
  pwd,
141
123
  routes: routes || []
142
124
  });
143
- let moduleFederationAssetsPromise = null;
144
- const getModuleFederationAssets = async ()=>{
145
- if (!moduleFederationAssetsPromise) moduleFederationAssetsPromise = (0, external_staticModuleFederation_js_namespaceObject.getModuleFederationAssetList)(pwd);
146
- return moduleFederationAssetsPromise;
147
- };
148
- const serveFile = async (c, filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false, requestPath = '')=>{
149
- if (moduleFederationAsset) (0, external_staticModuleFederation_js_namespaceObject.applyModuleFederationAssetHeaders)(c);
150
- const mimeType = (0, mime_namespaceObject.getMimeType)(filepath);
151
- if (mimeType) c.header('Content-Type', mimeType);
152
- const shouldPatchManifest = moduleFederationAsset && (0, external_staticModuleFederation_js_namespaceObject.isModuleFederationManifestRequest)(requestPath);
153
- const shouldPatchRemoteEntry = moduleFederationRemoteEntry;
154
- const canUsePreCompressed = !shouldPatchManifest && !shouldPatchRemoteEntry;
155
- const preCompressedAsset = canUsePreCompressed ? await (0, external_staticPrecompressed_js_namespaceObject.resolvePreCompressedAsset)(c, filepath) : {
156
- selected: null,
157
- hasVariant: false
158
- };
159
- const targetFilepath = preCompressedAsset.selected?.filepath ?? filepath;
160
- const chunk = await fileReader_namespaceObject.fileReader.readFileFromSystem(targetFilepath, 'buffer');
161
- if (null === chunk) return null;
162
- const responseChunk = shouldPatchManifest ? (0, external_staticModuleFederation_js_namespaceObject.patchModuleFederationManifestPublicPath)(c, chunk, pathPrefix) : shouldPatchRemoteEntry ? (0, external_staticModuleFederation_js_namespaceObject.patchModuleFederationRemoteEntryPublicPath)(c, chunk, pathPrefix) : chunk;
163
- (0, external_staticPrecompressed_js_namespaceObject.applyPreCompressedAssetHeaders)(c, preCompressedAsset);
164
- c.header('Content-Length', String(responseChunk.byteLength));
165
- const body = new Uint8Array(responseChunk.buffer, responseChunk.byteOffset, responseChunk.byteLength);
166
- return c.body(body, 200);
167
- };
125
+ const moduleFederationStaticServing = (0, external_staticServing_js_namespaceObject.createModuleFederationStaticServing)({
126
+ pwd,
127
+ pathPrefix
128
+ });
168
129
  return async (c, next)=>{
169
130
  const pageRoute = c.get('route');
170
131
  const pathname = c.req.path;
171
132
  if (pageRoute && '' === external_path_default().extname(pathname)) return next();
172
133
  const hit = staticPathRegExp.test(pathname);
173
- const requestPath = (0, external_staticModuleFederation_js_namespaceObject.getModuleFederationRequestPath)(pathname, pathPrefix);
174
- if (requestPath.includes('..')) return next();
175
- const moduleFederationAssetMeta = await getModuleFederationAssets();
176
- const isModuleFederationAsset = moduleFederationAssetMeta.assets.has(requestPath);
177
- const isModuleFederationRemoteEntry = moduleFederationAssetMeta.remoteEntry === requestPath;
178
- const serveByPath = async (filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false)=>{
179
- if (!await utils_namespaceObject.fs.pathExists(filepath)) return null;
180
- return serveFile(c, filepath, moduleFederationAsset, moduleFederationRemoteEntry, requestPath);
181
- };
134
+ const staticServingRequest = await moduleFederationStaticServing.resolveRequest(pathname);
135
+ if (null === staticServingRequest) return next();
182
136
  if (hit) {
183
- const response = await serveByPath(external_path_default().join(pwd, requestPath), isModuleFederationAsset, isModuleFederationRemoteEntry);
137
+ const response = await moduleFederationStaticServing.serveStaticHit(c, staticServingRequest);
184
138
  if (null !== response) return response;
185
139
  return next();
186
140
  }
187
- if (isModuleFederationAsset) {
188
- const response = await serveByPath(external_path_default().join(pwd, requestPath), true, isModuleFederationRemoteEntry);
189
- if (null !== response) return response;
190
- }
141
+ const moduleFederationResponse = await moduleFederationStaticServing.serveModuleFederationAsset(c, staticServingRequest);
142
+ if (null !== moduleFederationResponse) return moduleFederationResponse;
191
143
  return publicMiddleware(c, next);
192
144
  };
193
145
  }
@@ -43,20 +43,24 @@ __webpack_require__.d(__webpack_exports__, {
43
43
  getModuleFederationRequestPath: ()=>getModuleFederationRequestPath,
44
44
  isModuleFederationManifestRequest: ()=>isModuleFederationManifestRequest,
45
45
  patchModuleFederationManifestPublicPath: ()=>patchModuleFederationManifestPublicPath,
46
- patchModuleFederationRemoteEntryPublicPath: ()=>patchModuleFederationRemoteEntryPublicPath,
47
- trimLeadingSlash: ()=>trimLeadingSlash
46
+ patchModuleFederationRemoteEntryPublicPath: ()=>patchModuleFederationRemoteEntryPublicPath
48
47
  });
49
48
  const fileReader_namespaceObject = require("@modern-js/runtime-utils/fileReader");
50
49
  const utils_namespaceObject = require("@modern-js/utils");
51
50
  const external_path_namespaceObject = require("path");
52
51
  var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
53
52
  const MODULE_FEDERATION_MANIFEST_FILE = 'mf-manifest.json';
53
+ const BACKEND_MODULE_FEDERATION_MANIFEST_FILE = 'backend-mf-manifest.json';
54
+ const MODULE_FEDERATION_MANIFEST_FILES = [
55
+ MODULE_FEDERATION_MANIFEST_FILE,
56
+ BACKEND_MODULE_FEDERATION_MANIFEST_FILE
57
+ ];
54
58
  const MODULE_FEDERATION_OPTIONAL_FILES = [
55
59
  'mf-stats.json'
56
60
  ];
57
61
  const trimLeadingSlash = (value)=>value.replace(/^\/+/, '');
58
62
  const getModuleFederationRequestPath = (pathname, pathPrefix)=>trimLeadingSlash(pathname.replace(pathPrefix, ()=>''));
59
- const isModuleFederationManifestRequest = (requestPath)=>requestPath === MODULE_FEDERATION_MANIFEST_FILE;
63
+ const isModuleFederationManifestRequest = (requestPath)=>MODULE_FEDERATION_MANIFEST_FILES.includes(requestPath);
60
64
  const applyModuleFederationAssetHeaders = (c)=>{
61
65
  c.header('Access-Control-Allow-Origin', '*');
62
66
  c.header('Access-Control-Allow-Headers', '*');
@@ -67,8 +71,7 @@ const joinModuleFederationAssetPath = (assetPath, assetName)=>{
67
71
  return trimLeadingSlash(external_path_default().posix.join(assetPath || '', assetName));
68
72
  };
69
73
  const appendModuleFederationAsset = (set, assetPath)=>{
70
- if (!assetPath) return;
71
- set.add(trimLeadingSlash(assetPath));
74
+ if (assetPath) set.add(trimLeadingSlash(assetPath));
72
75
  };
73
76
  const appendModuleFederationAssets = (set, assets)=>{
74
77
  assets?.js?.sync?.forEach((asset)=>appendModuleFederationAsset(set, asset));
@@ -109,37 +112,36 @@ const patchModuleFederationRemoteEntryPublicPath = (c, remoteEntryBuffer, pathPr
109
112
  };
110
113
  const getModuleFederationAssetList = async (pwd)=>{
111
114
  const assets = new Set();
112
- const manifestPath = external_path_default().join(pwd, MODULE_FEDERATION_MANIFEST_FILE);
113
- if (!await utils_namespaceObject.fs.pathExists(manifestPath)) return {
114
- assets,
115
- remoteEntry: null
116
- };
117
- assets.add(MODULE_FEDERATION_MANIFEST_FILE);
118
- const manifestBuffer = await fileReader_namespaceObject.fileReader.readFileFromSystem(manifestPath, 'buffer');
119
- if (null === manifestBuffer) return {
120
- assets,
121
- remoteEntry: null
122
- };
123
- for (const filename of MODULE_FEDERATION_OPTIONAL_FILES)if (await utils_namespaceObject.fs.pathExists(external_path_default().join(pwd, filename))) assets.add(filename);
124
- let remoteEntryFile = null;
125
- try {
126
- const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
127
- const remoteEntry = joinModuleFederationAssetPath(manifest.metaData?.remoteEntry?.path, manifest.metaData?.remoteEntry?.name);
128
- const dtsZip = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.zip);
129
- const dtsApi = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.api);
130
- if (remoteEntry) {
131
- assets.add(remoteEntry);
132
- remoteEntryFile = remoteEntry;
133
- }
134
- if (dtsZip) assets.add(dtsZip);
135
- if (dtsApi) assets.add(dtsApi);
136
- manifest.shared?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
137
- manifest.remotes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
138
- manifest.exposes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
139
- } catch {}
115
+ const remoteEntries = new Set();
116
+ let manifestFound = false;
117
+ for (const manifestFile of MODULE_FEDERATION_MANIFEST_FILES){
118
+ const manifestPath = external_path_default().join(pwd, manifestFile);
119
+ if (!await utils_namespaceObject.fs.pathExists(manifestPath)) continue;
120
+ manifestFound = true;
121
+ assets.add(manifestFile);
122
+ const manifestBuffer = await fileReader_namespaceObject.fileReader.readFileFromSystem(manifestPath, 'buffer');
123
+ if (null !== manifestBuffer) try {
124
+ const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
125
+ const remoteEntry = joinModuleFederationAssetPath(manifest.metaData?.remoteEntry?.path, manifest.metaData?.remoteEntry?.name);
126
+ const dtsZip = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.zip);
127
+ const dtsApi = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.api);
128
+ if (remoteEntry) {
129
+ assets.add(remoteEntry);
130
+ remoteEntries.add(remoteEntry);
131
+ }
132
+ appendModuleFederationAsset(assets, dtsZip);
133
+ appendModuleFederationAsset(assets, dtsApi);
134
+ manifest.shared?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
135
+ manifest.remotes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
136
+ manifest.exposes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
137
+ } catch {}
138
+ }
139
+ if (manifestFound) {
140
+ for (const filename of MODULE_FEDERATION_OPTIONAL_FILES)if (await utils_namespaceObject.fs.pathExists(external_path_default().join(pwd, filename))) assets.add(filename);
141
+ }
140
142
  return {
141
143
  assets,
142
- remoteEntry: remoteEntryFile
144
+ remoteEntries
143
145
  };
144
146
  };
145
147
  exports.MODULE_FEDERATION_MANIFEST_FILE = __webpack_exports__.MODULE_FEDERATION_MANIFEST_FILE;
@@ -149,7 +151,6 @@ exports.getModuleFederationRequestPath = __webpack_exports__.getModuleFederation
149
151
  exports.isModuleFederationManifestRequest = __webpack_exports__.isModuleFederationManifestRequest;
150
152
  exports.patchModuleFederationManifestPublicPath = __webpack_exports__.patchModuleFederationManifestPublicPath;
151
153
  exports.patchModuleFederationRemoteEntryPublicPath = __webpack_exports__.patchModuleFederationRemoteEntryPublicPath;
152
- exports.trimLeadingSlash = __webpack_exports__.trimLeadingSlash;
153
154
  for(var __rspack_i in __webpack_exports__)if (-1 === [
154
155
  "MODULE_FEDERATION_MANIFEST_FILE",
155
156
  "applyModuleFederationAssetHeaders",
@@ -157,8 +158,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
157
158
  "getModuleFederationRequestPath",
158
159
  "isModuleFederationManifestRequest",
159
160
  "patchModuleFederationManifestPublicPath",
160
- "patchModuleFederationRemoteEntryPublicPath",
161
- "trimLeadingSlash"
161
+ "patchModuleFederationRemoteEntryPublicPath"
162
162
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
163
163
  Object.defineProperty(exports, '__esModule', {
164
164
  value: true
@@ -28,7 +28,6 @@ var __webpack_require__ = {};
28
28
  var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
- appendVaryHeader: ()=>appendVaryHeader,
32
31
  applyPreCompressedAssetHeaders: ()=>applyPreCompressedAssetHeaders,
33
32
  resolvePreCompressedAsset: ()=>resolvePreCompressedAsset
34
33
  });
@@ -122,11 +121,9 @@ const applyPreCompressedAssetHeaders = (c, preCompressedAsset)=>{
122
121
  if (preCompressedAsset.hasVariant) appendVaryHeader(c, 'Accept-Encoding');
123
122
  if (preCompressedAsset.selected) c.header('Content-Encoding', preCompressedAsset.selected.encoding);
124
123
  };
125
- exports.appendVaryHeader = __webpack_exports__.appendVaryHeader;
126
124
  exports.applyPreCompressedAssetHeaders = __webpack_exports__.applyPreCompressedAssetHeaders;
127
125
  exports.resolvePreCompressedAsset = __webpack_exports__.resolvePreCompressedAsset;
128
126
  for(var __rspack_i in __webpack_exports__)if (-1 === [
129
- "appendVaryHeader",
130
127
  "applyPreCompressedAssetHeaders",
131
128
  "resolvePreCompressedAsset"
132
129
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ createModuleFederationStaticServing: ()=>createModuleFederationStaticServing,
41
+ servePreCompressedPublicRouteAsset: ()=>servePreCompressedPublicRouteAsset
42
+ });
43
+ const fileReader_namespaceObject = require("@modern-js/runtime-utils/fileReader");
44
+ const utils_namespaceObject = require("@modern-js/utils");
45
+ const mime_namespaceObject = require("hono/utils/mime");
46
+ const external_path_namespaceObject = require("path");
47
+ var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
48
+ const external_staticModuleFederation_js_namespaceObject = require("./staticModuleFederation.js");
49
+ const external_staticPrecompressed_js_namespaceObject = require("./staticPrecompressed.js");
50
+ const servePreCompressedPublicRouteAsset = async (c, pwd, route)=>{
51
+ const { entryPath } = route;
52
+ const originFilename = external_path_default().join(pwd, entryPath);
53
+ const preCompressedAsset = await (0, external_staticPrecompressed_js_namespaceObject.resolvePreCompressedAsset)(c, originFilename);
54
+ const filename = preCompressedAsset.selected?.filepath ?? originFilename;
55
+ const data = await fileReader_namespaceObject.fileReader.readFile(filename, 'buffer');
56
+ const mimeType = (0, mime_namespaceObject.getMimeType)(originFilename);
57
+ if (null === data) return null;
58
+ const body = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
59
+ if (mimeType) c.header('Content-Type', mimeType);
60
+ Object.entries(route.responseHeaders || {}).forEach(([k, v])=>{
61
+ c.header(k, v);
62
+ });
63
+ (0, external_staticPrecompressed_js_namespaceObject.applyPreCompressedAssetHeaders)(c, preCompressedAsset);
64
+ c.header('Content-Length', String(data.byteLength));
65
+ return c.body(body, 200);
66
+ };
67
+ const isPathInside = (target, root)=>{
68
+ const relative = external_path_default().relative(external_path_default().resolve(root), external_path_default().resolve(target));
69
+ return '' === relative || !relative.startsWith(`..${external_path_default().sep}`) && '..' !== relative && !external_path_default().isAbsolute(relative);
70
+ };
71
+ const createModuleFederationStaticServing = ({ pwd, pathPrefix })=>{
72
+ let moduleFederationAssetsPromise = null;
73
+ const getModuleFederationAssets = async ()=>{
74
+ if (!moduleFederationAssetsPromise) moduleFederationAssetsPromise = (0, external_staticModuleFederation_js_namespaceObject.getModuleFederationAssetList)(pwd);
75
+ return moduleFederationAssetsPromise;
76
+ };
77
+ const resolveRequest = async (pathname)=>{
78
+ const requestPath = (0, external_staticModuleFederation_js_namespaceObject.getModuleFederationRequestPath)(pathname, pathPrefix);
79
+ if (requestPath.includes('..')) return null;
80
+ const moduleFederationAssetMeta = await getModuleFederationAssets();
81
+ return {
82
+ requestPath,
83
+ isModuleFederationAsset: moduleFederationAssetMeta.assets.has(requestPath),
84
+ isModuleFederationRemoteEntry: moduleFederationAssetMeta.remoteEntries.has(requestPath)
85
+ };
86
+ };
87
+ const serveFile = async (c, filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false, requestPath = '')=>{
88
+ if (moduleFederationAsset) (0, external_staticModuleFederation_js_namespaceObject.applyModuleFederationAssetHeaders)(c);
89
+ const mimeType = (0, mime_namespaceObject.getMimeType)(filepath);
90
+ if (mimeType) c.header('Content-Type', mimeType);
91
+ const shouldPatchManifest = moduleFederationAsset && (0, external_staticModuleFederation_js_namespaceObject.isModuleFederationManifestRequest)(requestPath);
92
+ const shouldPatchRemoteEntry = moduleFederationRemoteEntry;
93
+ const canUsePreCompressed = !shouldPatchManifest && !shouldPatchRemoteEntry;
94
+ const preCompressedAsset = canUsePreCompressed ? await (0, external_staticPrecompressed_js_namespaceObject.resolvePreCompressedAsset)(c, filepath) : {
95
+ selected: null,
96
+ hasVariant: false
97
+ };
98
+ const targetFilepath = preCompressedAsset.selected?.filepath ?? filepath;
99
+ const chunk = await fileReader_namespaceObject.fileReader.readFileFromSystem(targetFilepath, 'buffer');
100
+ if (null === chunk) return null;
101
+ const responseChunk = shouldPatchManifest ? (0, external_staticModuleFederation_js_namespaceObject.patchModuleFederationManifestPublicPath)(c, chunk, pathPrefix) : shouldPatchRemoteEntry ? (0, external_staticModuleFederation_js_namespaceObject.patchModuleFederationRemoteEntryPublicPath)(c, chunk, pathPrefix) : chunk;
102
+ (0, external_staticPrecompressed_js_namespaceObject.applyPreCompressedAssetHeaders)(c, preCompressedAsset);
103
+ c.header('Content-Length', String(responseChunk.byteLength));
104
+ const body = new Uint8Array(responseChunk.buffer, responseChunk.byteOffset, responseChunk.byteLength);
105
+ return c.body(body, 200);
106
+ };
107
+ const serveByPath = async (c, filepath, request, moduleFederationAsset = false, moduleFederationRemoteEntry = false)=>{
108
+ if (!isPathInside(filepath, pwd)) return null;
109
+ if (!await utils_namespaceObject.fs.pathExists(filepath)) return null;
110
+ return serveFile(c, filepath, moduleFederationAsset, moduleFederationRemoteEntry, request.requestPath);
111
+ };
112
+ const serveStaticHit = (c, request)=>serveByPath(c, external_path_default().join(pwd, request.requestPath), request, request.isModuleFederationAsset, request.isModuleFederationRemoteEntry);
113
+ const serveModuleFederationAsset = (c, request)=>{
114
+ if (!request.isModuleFederationAsset) return null;
115
+ return serveByPath(c, external_path_default().join(pwd, request.requestPath), request, true, request.isModuleFederationRemoteEntry);
116
+ };
117
+ return {
118
+ resolveRequest,
119
+ serveStaticHit,
120
+ serveModuleFederationAsset
121
+ };
122
+ };
123
+ exports.createModuleFederationStaticServing = __webpack_exports__.createModuleFederationStaticServing;
124
+ exports.servePreCompressedPublicRouteAsset = __webpack_exports__.servePreCompressedPublicRouteAsset;
125
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
126
+ "createModuleFederationStaticServing",
127
+ "servePreCompressedPublicRouteAsset"
128
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
129
+ Object.defineProperty(exports, '__esModule', {
130
+ value: true
131
+ });
@@ -1,11 +1,7 @@
1
- import { fileReader } from "@modern-js/runtime-utils/fileReader";
2
- import { fs } from "@modern-js/utils";
3
- import { getMimeType } from "hono/utils/mime";
4
1
  import path from "path";
5
2
  import { sortRoutes } from "../../../utils/index.mjs";
6
3
  import { getPublicDirPatterns } from "../../../utils/publicDir.mjs";
7
- import { applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath } from "./staticModuleFederation.mjs";
8
- import { applyPreCompressedAssetHeaders, resolvePreCompressedAsset } from "./staticPrecompressed.mjs";
4
+ import { createModuleFederationStaticServing, servePreCompressedPublicRouteAsset } from "./staticServing.mjs";
9
5
  const serverStaticPlugin = ()=>({
10
6
  name: '@modern-js/plugin-server-static',
11
7
  setup (api) {
@@ -30,22 +26,8 @@ function createPublicMiddleware({ pwd, routes }) {
30
26
  return async (c, next)=>{
31
27
  const route = matchPublicRoute(c.req, routes);
32
28
  if (route) {
33
- const { entryPath } = route;
34
- const originFilename = path.join(pwd, entryPath);
35
- const preCompressedAsset = await resolvePreCompressedAsset(c, originFilename);
36
- const filename = preCompressedAsset.selected?.filepath ?? originFilename;
37
- const data = await fileReader.readFile(filename, 'buffer');
38
- const mimeType = getMimeType(originFilename);
39
- if (null !== data) {
40
- const body = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
41
- if (mimeType) c.header('Content-Type', mimeType);
42
- Object.entries(route.responseHeaders || {}).forEach(([k, v])=>{
43
- c.header(k, v);
44
- });
45
- applyPreCompressedAssetHeaders(c, preCompressedAsset);
46
- c.header('Content-Length', String(data.byteLength));
47
- return c.body(body, 200);
48
- }
29
+ const response = await servePreCompressedPublicRouteAsset(c, pwd, route);
30
+ if (null !== response) return response;
49
31
  }
50
32
  return await next();
51
33
  };
@@ -96,54 +78,24 @@ function createStaticMiddleware(options) {
96
78
  pwd,
97
79
  routes: routes || []
98
80
  });
99
- let moduleFederationAssetsPromise = null;
100
- const getModuleFederationAssets = async ()=>{
101
- if (!moduleFederationAssetsPromise) moduleFederationAssetsPromise = getModuleFederationAssetList(pwd);
102
- return moduleFederationAssetsPromise;
103
- };
104
- const serveFile = async (c, filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false, requestPath = '')=>{
105
- if (moduleFederationAsset) applyModuleFederationAssetHeaders(c);
106
- const mimeType = getMimeType(filepath);
107
- if (mimeType) c.header('Content-Type', mimeType);
108
- const shouldPatchManifest = moduleFederationAsset && isModuleFederationManifestRequest(requestPath);
109
- const shouldPatchRemoteEntry = moduleFederationRemoteEntry;
110
- const canUsePreCompressed = !shouldPatchManifest && !shouldPatchRemoteEntry;
111
- const preCompressedAsset = canUsePreCompressed ? await resolvePreCompressedAsset(c, filepath) : {
112
- selected: null,
113
- hasVariant: false
114
- };
115
- const targetFilepath = preCompressedAsset.selected?.filepath ?? filepath;
116
- const chunk = await fileReader.readFileFromSystem(targetFilepath, 'buffer');
117
- if (null === chunk) return null;
118
- const responseChunk = shouldPatchManifest ? patchModuleFederationManifestPublicPath(c, chunk, pathPrefix) : shouldPatchRemoteEntry ? patchModuleFederationRemoteEntryPublicPath(c, chunk, pathPrefix) : chunk;
119
- applyPreCompressedAssetHeaders(c, preCompressedAsset);
120
- c.header('Content-Length', String(responseChunk.byteLength));
121
- const body = new Uint8Array(responseChunk.buffer, responseChunk.byteOffset, responseChunk.byteLength);
122
- return c.body(body, 200);
123
- };
81
+ const moduleFederationStaticServing = createModuleFederationStaticServing({
82
+ pwd,
83
+ pathPrefix
84
+ });
124
85
  return async (c, next)=>{
125
86
  const pageRoute = c.get('route');
126
87
  const pathname = c.req.path;
127
88
  if (pageRoute && '' === path.extname(pathname)) return next();
128
89
  const hit = staticPathRegExp.test(pathname);
129
- const requestPath = getModuleFederationRequestPath(pathname, pathPrefix);
130
- if (requestPath.includes('..')) return next();
131
- const moduleFederationAssetMeta = await getModuleFederationAssets();
132
- const isModuleFederationAsset = moduleFederationAssetMeta.assets.has(requestPath);
133
- const isModuleFederationRemoteEntry = moduleFederationAssetMeta.remoteEntry === requestPath;
134
- const serveByPath = async (filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false)=>{
135
- if (!await fs.pathExists(filepath)) return null;
136
- return serveFile(c, filepath, moduleFederationAsset, moduleFederationRemoteEntry, requestPath);
137
- };
90
+ const staticServingRequest = await moduleFederationStaticServing.resolveRequest(pathname);
91
+ if (null === staticServingRequest) return next();
138
92
  if (hit) {
139
- const response = await serveByPath(path.join(pwd, requestPath), isModuleFederationAsset, isModuleFederationRemoteEntry);
93
+ const response = await moduleFederationStaticServing.serveStaticHit(c, staticServingRequest);
140
94
  if (null !== response) return response;
141
95
  return next();
142
96
  }
143
- if (isModuleFederationAsset) {
144
- const response = await serveByPath(path.join(pwd, requestPath), true, isModuleFederationRemoteEntry);
145
- if (null !== response) return response;
146
- }
97
+ const moduleFederationResponse = await moduleFederationStaticServing.serveModuleFederationAsset(c, staticServingRequest);
98
+ if (null !== moduleFederationResponse) return moduleFederationResponse;
147
99
  return publicMiddleware(c, next);
148
100
  };
149
101
  }
@@ -2,12 +2,17 @@ import { fileReader } from "@modern-js/runtime-utils/fileReader";
2
2
  import { fs } from "@modern-js/utils";
3
3
  import path from "path";
4
4
  const MODULE_FEDERATION_MANIFEST_FILE = 'mf-manifest.json';
5
+ const BACKEND_MODULE_FEDERATION_MANIFEST_FILE = 'backend-mf-manifest.json';
6
+ const MODULE_FEDERATION_MANIFEST_FILES = [
7
+ MODULE_FEDERATION_MANIFEST_FILE,
8
+ BACKEND_MODULE_FEDERATION_MANIFEST_FILE
9
+ ];
5
10
  const MODULE_FEDERATION_OPTIONAL_FILES = [
6
11
  'mf-stats.json'
7
12
  ];
8
13
  const trimLeadingSlash = (value)=>value.replace(/^\/+/, '');
9
14
  const getModuleFederationRequestPath = (pathname, pathPrefix)=>trimLeadingSlash(pathname.replace(pathPrefix, ()=>''));
10
- const isModuleFederationManifestRequest = (requestPath)=>requestPath === MODULE_FEDERATION_MANIFEST_FILE;
15
+ const isModuleFederationManifestRequest = (requestPath)=>MODULE_FEDERATION_MANIFEST_FILES.includes(requestPath);
11
16
  const applyModuleFederationAssetHeaders = (c)=>{
12
17
  c.header('Access-Control-Allow-Origin', '*');
13
18
  c.header('Access-Control-Allow-Headers', '*');
@@ -18,8 +23,7 @@ const joinModuleFederationAssetPath = (assetPath, assetName)=>{
18
23
  return trimLeadingSlash(path.posix.join(assetPath || '', assetName));
19
24
  };
20
25
  const appendModuleFederationAsset = (set, assetPath)=>{
21
- if (!assetPath) return;
22
- set.add(trimLeadingSlash(assetPath));
26
+ if (assetPath) set.add(trimLeadingSlash(assetPath));
23
27
  };
24
28
  const appendModuleFederationAssets = (set, assets)=>{
25
29
  assets?.js?.sync?.forEach((asset)=>appendModuleFederationAsset(set, asset));
@@ -60,37 +64,36 @@ const patchModuleFederationRemoteEntryPublicPath = (c, remoteEntryBuffer, pathPr
60
64
  };
61
65
  const getModuleFederationAssetList = async (pwd)=>{
62
66
  const assets = new Set();
63
- const manifestPath = path.join(pwd, MODULE_FEDERATION_MANIFEST_FILE);
64
- if (!await fs.pathExists(manifestPath)) return {
65
- assets,
66
- remoteEntry: null
67
- };
68
- assets.add(MODULE_FEDERATION_MANIFEST_FILE);
69
- const manifestBuffer = await fileReader.readFileFromSystem(manifestPath, 'buffer');
70
- if (null === manifestBuffer) return {
71
- assets,
72
- remoteEntry: null
73
- };
74
- for (const filename of MODULE_FEDERATION_OPTIONAL_FILES)if (await fs.pathExists(path.join(pwd, filename))) assets.add(filename);
75
- let remoteEntryFile = null;
76
- try {
77
- const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
78
- const remoteEntry = joinModuleFederationAssetPath(manifest.metaData?.remoteEntry?.path, manifest.metaData?.remoteEntry?.name);
79
- const dtsZip = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.zip);
80
- const dtsApi = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.api);
81
- if (remoteEntry) {
82
- assets.add(remoteEntry);
83
- remoteEntryFile = remoteEntry;
84
- }
85
- if (dtsZip) assets.add(dtsZip);
86
- if (dtsApi) assets.add(dtsApi);
87
- manifest.shared?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
88
- manifest.remotes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
89
- manifest.exposes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
90
- } catch {}
67
+ const remoteEntries = new Set();
68
+ let manifestFound = false;
69
+ for (const manifestFile of MODULE_FEDERATION_MANIFEST_FILES){
70
+ const manifestPath = path.join(pwd, manifestFile);
71
+ if (!await fs.pathExists(manifestPath)) continue;
72
+ manifestFound = true;
73
+ assets.add(manifestFile);
74
+ const manifestBuffer = await fileReader.readFileFromSystem(manifestPath, 'buffer');
75
+ if (null !== manifestBuffer) try {
76
+ const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
77
+ const remoteEntry = joinModuleFederationAssetPath(manifest.metaData?.remoteEntry?.path, manifest.metaData?.remoteEntry?.name);
78
+ const dtsZip = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.zip);
79
+ const dtsApi = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.api);
80
+ if (remoteEntry) {
81
+ assets.add(remoteEntry);
82
+ remoteEntries.add(remoteEntry);
83
+ }
84
+ appendModuleFederationAsset(assets, dtsZip);
85
+ appendModuleFederationAsset(assets, dtsApi);
86
+ manifest.shared?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
87
+ manifest.remotes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
88
+ manifest.exposes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
89
+ } catch {}
90
+ }
91
+ if (manifestFound) {
92
+ for (const filename of MODULE_FEDERATION_OPTIONAL_FILES)if (await fs.pathExists(path.join(pwd, filename))) assets.add(filename);
93
+ }
91
94
  return {
92
95
  assets,
93
- remoteEntry: remoteEntryFile
96
+ remoteEntries
94
97
  };
95
98
  };
96
- export { MODULE_FEDERATION_MANIFEST_FILE, applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath, trimLeadingSlash };
99
+ export { MODULE_FEDERATION_MANIFEST_FILE, applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath };
@@ -88,4 +88,4 @@ const applyPreCompressedAssetHeaders = (c, preCompressedAsset)=>{
88
88
  if (preCompressedAsset.hasVariant) appendVaryHeader(c, 'Accept-Encoding');
89
89
  if (preCompressedAsset.selected) c.header('Content-Encoding', preCompressedAsset.selected.encoding);
90
90
  };
91
- export { appendVaryHeader, applyPreCompressedAssetHeaders, resolvePreCompressedAsset };
91
+ export { applyPreCompressedAssetHeaders, resolvePreCompressedAsset };
@@ -0,0 +1,80 @@
1
+ import { fileReader } from "@modern-js/runtime-utils/fileReader";
2
+ import { fs } from "@modern-js/utils";
3
+ import { getMimeType } from "hono/utils/mime";
4
+ import path from "path";
5
+ import { applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath } from "./staticModuleFederation.mjs";
6
+ import { applyPreCompressedAssetHeaders, resolvePreCompressedAsset } from "./staticPrecompressed.mjs";
7
+ const servePreCompressedPublicRouteAsset = async (c, pwd, route)=>{
8
+ const { entryPath } = route;
9
+ const originFilename = path.join(pwd, entryPath);
10
+ const preCompressedAsset = await resolvePreCompressedAsset(c, originFilename);
11
+ const filename = preCompressedAsset.selected?.filepath ?? originFilename;
12
+ const data = await fileReader.readFile(filename, 'buffer');
13
+ const mimeType = getMimeType(originFilename);
14
+ if (null === data) return null;
15
+ const body = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
16
+ if (mimeType) c.header('Content-Type', mimeType);
17
+ Object.entries(route.responseHeaders || {}).forEach(([k, v])=>{
18
+ c.header(k, v);
19
+ });
20
+ applyPreCompressedAssetHeaders(c, preCompressedAsset);
21
+ c.header('Content-Length', String(data.byteLength));
22
+ return c.body(body, 200);
23
+ };
24
+ const isPathInside = (target, root)=>{
25
+ const relative = path.relative(path.resolve(root), path.resolve(target));
26
+ return '' === relative || !relative.startsWith(`..${path.sep}`) && '..' !== relative && !path.isAbsolute(relative);
27
+ };
28
+ const createModuleFederationStaticServing = ({ pwd, pathPrefix })=>{
29
+ let moduleFederationAssetsPromise = null;
30
+ const getModuleFederationAssets = async ()=>{
31
+ if (!moduleFederationAssetsPromise) moduleFederationAssetsPromise = getModuleFederationAssetList(pwd);
32
+ return moduleFederationAssetsPromise;
33
+ };
34
+ const resolveRequest = async (pathname)=>{
35
+ const requestPath = getModuleFederationRequestPath(pathname, pathPrefix);
36
+ if (requestPath.includes('..')) return null;
37
+ const moduleFederationAssetMeta = await getModuleFederationAssets();
38
+ return {
39
+ requestPath,
40
+ isModuleFederationAsset: moduleFederationAssetMeta.assets.has(requestPath),
41
+ isModuleFederationRemoteEntry: moduleFederationAssetMeta.remoteEntries.has(requestPath)
42
+ };
43
+ };
44
+ const serveFile = async (c, filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false, requestPath = '')=>{
45
+ if (moduleFederationAsset) applyModuleFederationAssetHeaders(c);
46
+ const mimeType = getMimeType(filepath);
47
+ if (mimeType) c.header('Content-Type', mimeType);
48
+ const shouldPatchManifest = moduleFederationAsset && isModuleFederationManifestRequest(requestPath);
49
+ const shouldPatchRemoteEntry = moduleFederationRemoteEntry;
50
+ const canUsePreCompressed = !shouldPatchManifest && !shouldPatchRemoteEntry;
51
+ const preCompressedAsset = canUsePreCompressed ? await resolvePreCompressedAsset(c, filepath) : {
52
+ selected: null,
53
+ hasVariant: false
54
+ };
55
+ const targetFilepath = preCompressedAsset.selected?.filepath ?? filepath;
56
+ const chunk = await fileReader.readFileFromSystem(targetFilepath, 'buffer');
57
+ if (null === chunk) return null;
58
+ const responseChunk = shouldPatchManifest ? patchModuleFederationManifestPublicPath(c, chunk, pathPrefix) : shouldPatchRemoteEntry ? patchModuleFederationRemoteEntryPublicPath(c, chunk, pathPrefix) : chunk;
59
+ applyPreCompressedAssetHeaders(c, preCompressedAsset);
60
+ c.header('Content-Length', String(responseChunk.byteLength));
61
+ const body = new Uint8Array(responseChunk.buffer, responseChunk.byteOffset, responseChunk.byteLength);
62
+ return c.body(body, 200);
63
+ };
64
+ const serveByPath = async (c, filepath, request, moduleFederationAsset = false, moduleFederationRemoteEntry = false)=>{
65
+ if (!isPathInside(filepath, pwd)) return null;
66
+ if (!await fs.pathExists(filepath)) return null;
67
+ return serveFile(c, filepath, moduleFederationAsset, moduleFederationRemoteEntry, request.requestPath);
68
+ };
69
+ const serveStaticHit = (c, request)=>serveByPath(c, path.join(pwd, request.requestPath), request, request.isModuleFederationAsset, request.isModuleFederationRemoteEntry);
70
+ const serveModuleFederationAsset = (c, request)=>{
71
+ if (!request.isModuleFederationAsset) return null;
72
+ return serveByPath(c, path.join(pwd, request.requestPath), request, true, request.isModuleFederationRemoteEntry);
73
+ };
74
+ return {
75
+ resolveRequest,
76
+ serveStaticHit,
77
+ serveModuleFederationAsset
78
+ };
79
+ };
80
+ export { createModuleFederationStaticServing, servePreCompressedPublicRouteAsset };
@@ -8,10 +8,10 @@ import { renderRscHandler } from "./renderRscHandler.mjs";
8
8
  import { serverActionHandler } from "./serverActionHandler.mjs";
9
9
  import { ssrRender } from "./ssrRender.mjs";
10
10
  import { __webpack_require__ } from "../../rslib-runtime.mjs";
11
- import * as __rspack_external__modern_js_runtime_utils_router_2aa8d96f from "@modern-js/runtime-utils/router";
11
+ import * as __rspack_external__modern_js_runtime_utils_router_4aa9f9b0 from "@modern-js/runtime-utils/router";
12
12
  __webpack_require__.add({
13
- 2420 (module) {
14
- module.exports = __rspack_external__modern_js_runtime_utils_router_2aa8d96f;
13
+ 5327 (module) {
14
+ module.exports = __rspack_external__modern_js_runtime_utils_router_4aa9f9b0;
15
15
  }
16
16
  });
17
17
  const DYNAMIC_ROUTE_REG = /\/:./;
@@ -163,7 +163,7 @@ async function renderHandler(request, options, mode, fallbackWrapper, framework)
163
163
  const { nestedRoutesJson } = serverManifest;
164
164
  const routes = nestedRoutesJson?.[options.routeInfo.entryName];
165
165
  if (routes) {
166
- const { matchRoutes } = __webpack_require__(2420);
166
+ const { matchRoutes } = __webpack_require__(5327);
167
167
  const url = new URL(request.url);
168
168
  const matchedRoutes = matchRoutes(routes, url.pathname, options.routeInfo.urlPath);
169
169
  if (matchedRoutes) {
@@ -1,12 +1,8 @@
1
1
  import "node:module";
2
- import { fileReader } from "@modern-js/runtime-utils/fileReader";
3
- import { fs } from "@modern-js/utils";
4
- import { getMimeType } from "hono/utils/mime";
5
2
  import path from "path";
6
3
  import { sortRoutes } from "../../../utils/index.mjs";
7
4
  import { getPublicDirPatterns } from "../../../utils/publicDir.mjs";
8
- import { applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath } from "./staticModuleFederation.mjs";
9
- import { applyPreCompressedAssetHeaders, resolvePreCompressedAsset } from "./staticPrecompressed.mjs";
5
+ import { createModuleFederationStaticServing, servePreCompressedPublicRouteAsset } from "./staticServing.mjs";
10
6
  const serverStaticPlugin = ()=>({
11
7
  name: '@modern-js/plugin-server-static',
12
8
  setup (api) {
@@ -31,22 +27,8 @@ function createPublicMiddleware({ pwd, routes }) {
31
27
  return async (c, next)=>{
32
28
  const route = matchPublicRoute(c.req, routes);
33
29
  if (route) {
34
- const { entryPath } = route;
35
- const originFilename = path.join(pwd, entryPath);
36
- const preCompressedAsset = await resolvePreCompressedAsset(c, originFilename);
37
- const filename = preCompressedAsset.selected?.filepath ?? originFilename;
38
- const data = await fileReader.readFile(filename, 'buffer');
39
- const mimeType = getMimeType(originFilename);
40
- if (null !== data) {
41
- const body = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
42
- if (mimeType) c.header('Content-Type', mimeType);
43
- Object.entries(route.responseHeaders || {}).forEach(([k, v])=>{
44
- c.header(k, v);
45
- });
46
- applyPreCompressedAssetHeaders(c, preCompressedAsset);
47
- c.header('Content-Length', String(data.byteLength));
48
- return c.body(body, 200);
49
- }
30
+ const response = await servePreCompressedPublicRouteAsset(c, pwd, route);
31
+ if (null !== response) return response;
50
32
  }
51
33
  return await next();
52
34
  };
@@ -97,54 +79,24 @@ function createStaticMiddleware(options) {
97
79
  pwd,
98
80
  routes: routes || []
99
81
  });
100
- let moduleFederationAssetsPromise = null;
101
- const getModuleFederationAssets = async ()=>{
102
- if (!moduleFederationAssetsPromise) moduleFederationAssetsPromise = getModuleFederationAssetList(pwd);
103
- return moduleFederationAssetsPromise;
104
- };
105
- const serveFile = async (c, filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false, requestPath = '')=>{
106
- if (moduleFederationAsset) applyModuleFederationAssetHeaders(c);
107
- const mimeType = getMimeType(filepath);
108
- if (mimeType) c.header('Content-Type', mimeType);
109
- const shouldPatchManifest = moduleFederationAsset && isModuleFederationManifestRequest(requestPath);
110
- const shouldPatchRemoteEntry = moduleFederationRemoteEntry;
111
- const canUsePreCompressed = !shouldPatchManifest && !shouldPatchRemoteEntry;
112
- const preCompressedAsset = canUsePreCompressed ? await resolvePreCompressedAsset(c, filepath) : {
113
- selected: null,
114
- hasVariant: false
115
- };
116
- const targetFilepath = preCompressedAsset.selected?.filepath ?? filepath;
117
- const chunk = await fileReader.readFileFromSystem(targetFilepath, 'buffer');
118
- if (null === chunk) return null;
119
- const responseChunk = shouldPatchManifest ? patchModuleFederationManifestPublicPath(c, chunk, pathPrefix) : shouldPatchRemoteEntry ? patchModuleFederationRemoteEntryPublicPath(c, chunk, pathPrefix) : chunk;
120
- applyPreCompressedAssetHeaders(c, preCompressedAsset);
121
- c.header('Content-Length', String(responseChunk.byteLength));
122
- const body = new Uint8Array(responseChunk.buffer, responseChunk.byteOffset, responseChunk.byteLength);
123
- return c.body(body, 200);
124
- };
82
+ const moduleFederationStaticServing = createModuleFederationStaticServing({
83
+ pwd,
84
+ pathPrefix
85
+ });
125
86
  return async (c, next)=>{
126
87
  const pageRoute = c.get('route');
127
88
  const pathname = c.req.path;
128
89
  if (pageRoute && '' === path.extname(pathname)) return next();
129
90
  const hit = staticPathRegExp.test(pathname);
130
- const requestPath = getModuleFederationRequestPath(pathname, pathPrefix);
131
- if (requestPath.includes('..')) return next();
132
- const moduleFederationAssetMeta = await getModuleFederationAssets();
133
- const isModuleFederationAsset = moduleFederationAssetMeta.assets.has(requestPath);
134
- const isModuleFederationRemoteEntry = moduleFederationAssetMeta.remoteEntry === requestPath;
135
- const serveByPath = async (filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false)=>{
136
- if (!await fs.pathExists(filepath)) return null;
137
- return serveFile(c, filepath, moduleFederationAsset, moduleFederationRemoteEntry, requestPath);
138
- };
91
+ const staticServingRequest = await moduleFederationStaticServing.resolveRequest(pathname);
92
+ if (null === staticServingRequest) return next();
139
93
  if (hit) {
140
- const response = await serveByPath(path.join(pwd, requestPath), isModuleFederationAsset, isModuleFederationRemoteEntry);
94
+ const response = await moduleFederationStaticServing.serveStaticHit(c, staticServingRequest);
141
95
  if (null !== response) return response;
142
96
  return next();
143
97
  }
144
- if (isModuleFederationAsset) {
145
- const response = await serveByPath(path.join(pwd, requestPath), true, isModuleFederationRemoteEntry);
146
- if (null !== response) return response;
147
- }
98
+ const moduleFederationResponse = await moduleFederationStaticServing.serveModuleFederationAsset(c, staticServingRequest);
99
+ if (null !== moduleFederationResponse) return moduleFederationResponse;
148
100
  return publicMiddleware(c, next);
149
101
  };
150
102
  }
@@ -3,12 +3,17 @@ import { fileReader } from "@modern-js/runtime-utils/fileReader";
3
3
  import { fs } from "@modern-js/utils";
4
4
  import path from "path";
5
5
  const MODULE_FEDERATION_MANIFEST_FILE = 'mf-manifest.json';
6
+ const BACKEND_MODULE_FEDERATION_MANIFEST_FILE = 'backend-mf-manifest.json';
7
+ const MODULE_FEDERATION_MANIFEST_FILES = [
8
+ MODULE_FEDERATION_MANIFEST_FILE,
9
+ BACKEND_MODULE_FEDERATION_MANIFEST_FILE
10
+ ];
6
11
  const MODULE_FEDERATION_OPTIONAL_FILES = [
7
12
  'mf-stats.json'
8
13
  ];
9
14
  const trimLeadingSlash = (value)=>value.replace(/^\/+/, '');
10
15
  const getModuleFederationRequestPath = (pathname, pathPrefix)=>trimLeadingSlash(pathname.replace(pathPrefix, ()=>''));
11
- const isModuleFederationManifestRequest = (requestPath)=>requestPath === MODULE_FEDERATION_MANIFEST_FILE;
16
+ const isModuleFederationManifestRequest = (requestPath)=>MODULE_FEDERATION_MANIFEST_FILES.includes(requestPath);
12
17
  const applyModuleFederationAssetHeaders = (c)=>{
13
18
  c.header('Access-Control-Allow-Origin', '*');
14
19
  c.header('Access-Control-Allow-Headers', '*');
@@ -19,8 +24,7 @@ const joinModuleFederationAssetPath = (assetPath, assetName)=>{
19
24
  return trimLeadingSlash(path.posix.join(assetPath || '', assetName));
20
25
  };
21
26
  const appendModuleFederationAsset = (set, assetPath)=>{
22
- if (!assetPath) return;
23
- set.add(trimLeadingSlash(assetPath));
27
+ if (assetPath) set.add(trimLeadingSlash(assetPath));
24
28
  };
25
29
  const appendModuleFederationAssets = (set, assets)=>{
26
30
  assets?.js?.sync?.forEach((asset)=>appendModuleFederationAsset(set, asset));
@@ -61,37 +65,36 @@ const patchModuleFederationRemoteEntryPublicPath = (c, remoteEntryBuffer, pathPr
61
65
  };
62
66
  const getModuleFederationAssetList = async (pwd)=>{
63
67
  const assets = new Set();
64
- const manifestPath = path.join(pwd, MODULE_FEDERATION_MANIFEST_FILE);
65
- if (!await fs.pathExists(manifestPath)) return {
66
- assets,
67
- remoteEntry: null
68
- };
69
- assets.add(MODULE_FEDERATION_MANIFEST_FILE);
70
- const manifestBuffer = await fileReader.readFileFromSystem(manifestPath, 'buffer');
71
- if (null === manifestBuffer) return {
72
- assets,
73
- remoteEntry: null
74
- };
75
- for (const filename of MODULE_FEDERATION_OPTIONAL_FILES)if (await fs.pathExists(path.join(pwd, filename))) assets.add(filename);
76
- let remoteEntryFile = null;
77
- try {
78
- const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
79
- const remoteEntry = joinModuleFederationAssetPath(manifest.metaData?.remoteEntry?.path, manifest.metaData?.remoteEntry?.name);
80
- const dtsZip = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.zip);
81
- const dtsApi = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.api);
82
- if (remoteEntry) {
83
- assets.add(remoteEntry);
84
- remoteEntryFile = remoteEntry;
85
- }
86
- if (dtsZip) assets.add(dtsZip);
87
- if (dtsApi) assets.add(dtsApi);
88
- manifest.shared?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
89
- manifest.remotes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
90
- manifest.exposes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
91
- } catch {}
68
+ const remoteEntries = new Set();
69
+ let manifestFound = false;
70
+ for (const manifestFile of MODULE_FEDERATION_MANIFEST_FILES){
71
+ const manifestPath = path.join(pwd, manifestFile);
72
+ if (!await fs.pathExists(manifestPath)) continue;
73
+ manifestFound = true;
74
+ assets.add(manifestFile);
75
+ const manifestBuffer = await fileReader.readFileFromSystem(manifestPath, 'buffer');
76
+ if (null !== manifestBuffer) try {
77
+ const manifest = JSON.parse(manifestBuffer.toString('utf-8'));
78
+ const remoteEntry = joinModuleFederationAssetPath(manifest.metaData?.remoteEntry?.path, manifest.metaData?.remoteEntry?.name);
79
+ const dtsZip = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.zip);
80
+ const dtsApi = joinModuleFederationAssetPath(manifest.metaData?.types?.path, manifest.metaData?.types?.api);
81
+ if (remoteEntry) {
82
+ assets.add(remoteEntry);
83
+ remoteEntries.add(remoteEntry);
84
+ }
85
+ appendModuleFederationAsset(assets, dtsZip);
86
+ appendModuleFederationAsset(assets, dtsApi);
87
+ manifest.shared?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
88
+ manifest.remotes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
89
+ manifest.exposes?.forEach((item)=>appendModuleFederationAssets(assets, item.assets));
90
+ } catch {}
91
+ }
92
+ if (manifestFound) {
93
+ for (const filename of MODULE_FEDERATION_OPTIONAL_FILES)if (await fs.pathExists(path.join(pwd, filename))) assets.add(filename);
94
+ }
92
95
  return {
93
96
  assets,
94
- remoteEntry: remoteEntryFile
97
+ remoteEntries
95
98
  };
96
99
  };
97
- export { MODULE_FEDERATION_MANIFEST_FILE, applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath, trimLeadingSlash };
100
+ export { MODULE_FEDERATION_MANIFEST_FILE, applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath };
@@ -89,4 +89,4 @@ const applyPreCompressedAssetHeaders = (c, preCompressedAsset)=>{
89
89
  if (preCompressedAsset.hasVariant) appendVaryHeader(c, 'Accept-Encoding');
90
90
  if (preCompressedAsset.selected) c.header('Content-Encoding', preCompressedAsset.selected.encoding);
91
91
  };
92
- export { appendVaryHeader, applyPreCompressedAssetHeaders, resolvePreCompressedAsset };
92
+ export { applyPreCompressedAssetHeaders, resolvePreCompressedAsset };
@@ -0,0 +1,81 @@
1
+ import "node:module";
2
+ import { fileReader } from "@modern-js/runtime-utils/fileReader";
3
+ import { fs } from "@modern-js/utils";
4
+ import { getMimeType } from "hono/utils/mime";
5
+ import path from "path";
6
+ import { applyModuleFederationAssetHeaders, getModuleFederationAssetList, getModuleFederationRequestPath, isModuleFederationManifestRequest, patchModuleFederationManifestPublicPath, patchModuleFederationRemoteEntryPublicPath } from "./staticModuleFederation.mjs";
7
+ import { applyPreCompressedAssetHeaders, resolvePreCompressedAsset } from "./staticPrecompressed.mjs";
8
+ const servePreCompressedPublicRouteAsset = async (c, pwd, route)=>{
9
+ const { entryPath } = route;
10
+ const originFilename = path.join(pwd, entryPath);
11
+ const preCompressedAsset = await resolvePreCompressedAsset(c, originFilename);
12
+ const filename = preCompressedAsset.selected?.filepath ?? originFilename;
13
+ const data = await fileReader.readFile(filename, 'buffer');
14
+ const mimeType = getMimeType(originFilename);
15
+ if (null === data) return null;
16
+ const body = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
17
+ if (mimeType) c.header('Content-Type', mimeType);
18
+ Object.entries(route.responseHeaders || {}).forEach(([k, v])=>{
19
+ c.header(k, v);
20
+ });
21
+ applyPreCompressedAssetHeaders(c, preCompressedAsset);
22
+ c.header('Content-Length', String(data.byteLength));
23
+ return c.body(body, 200);
24
+ };
25
+ const isPathInside = (target, root)=>{
26
+ const relative = path.relative(path.resolve(root), path.resolve(target));
27
+ return '' === relative || !relative.startsWith(`..${path.sep}`) && '..' !== relative && !path.isAbsolute(relative);
28
+ };
29
+ const createModuleFederationStaticServing = ({ pwd, pathPrefix })=>{
30
+ let moduleFederationAssetsPromise = null;
31
+ const getModuleFederationAssets = async ()=>{
32
+ if (!moduleFederationAssetsPromise) moduleFederationAssetsPromise = getModuleFederationAssetList(pwd);
33
+ return moduleFederationAssetsPromise;
34
+ };
35
+ const resolveRequest = async (pathname)=>{
36
+ const requestPath = getModuleFederationRequestPath(pathname, pathPrefix);
37
+ if (requestPath.includes('..')) return null;
38
+ const moduleFederationAssetMeta = await getModuleFederationAssets();
39
+ return {
40
+ requestPath,
41
+ isModuleFederationAsset: moduleFederationAssetMeta.assets.has(requestPath),
42
+ isModuleFederationRemoteEntry: moduleFederationAssetMeta.remoteEntries.has(requestPath)
43
+ };
44
+ };
45
+ const serveFile = async (c, filepath, moduleFederationAsset = false, moduleFederationRemoteEntry = false, requestPath = '')=>{
46
+ if (moduleFederationAsset) applyModuleFederationAssetHeaders(c);
47
+ const mimeType = getMimeType(filepath);
48
+ if (mimeType) c.header('Content-Type', mimeType);
49
+ const shouldPatchManifest = moduleFederationAsset && isModuleFederationManifestRequest(requestPath);
50
+ const shouldPatchRemoteEntry = moduleFederationRemoteEntry;
51
+ const canUsePreCompressed = !shouldPatchManifest && !shouldPatchRemoteEntry;
52
+ const preCompressedAsset = canUsePreCompressed ? await resolvePreCompressedAsset(c, filepath) : {
53
+ selected: null,
54
+ hasVariant: false
55
+ };
56
+ const targetFilepath = preCompressedAsset.selected?.filepath ?? filepath;
57
+ const chunk = await fileReader.readFileFromSystem(targetFilepath, 'buffer');
58
+ if (null === chunk) return null;
59
+ const responseChunk = shouldPatchManifest ? patchModuleFederationManifestPublicPath(c, chunk, pathPrefix) : shouldPatchRemoteEntry ? patchModuleFederationRemoteEntryPublicPath(c, chunk, pathPrefix) : chunk;
60
+ applyPreCompressedAssetHeaders(c, preCompressedAsset);
61
+ c.header('Content-Length', String(responseChunk.byteLength));
62
+ const body = new Uint8Array(responseChunk.buffer, responseChunk.byteOffset, responseChunk.byteLength);
63
+ return c.body(body, 200);
64
+ };
65
+ const serveByPath = async (c, filepath, request, moduleFederationAsset = false, moduleFederationRemoteEntry = false)=>{
66
+ if (!isPathInside(filepath, pwd)) return null;
67
+ if (!await fs.pathExists(filepath)) return null;
68
+ return serveFile(c, filepath, moduleFederationAsset, moduleFederationRemoteEntry, request.requestPath);
69
+ };
70
+ const serveStaticHit = (c, request)=>serveByPath(c, path.join(pwd, request.requestPath), request, request.isModuleFederationAsset, request.isModuleFederationRemoteEntry);
71
+ const serveModuleFederationAsset = (c, request)=>{
72
+ if (!request.isModuleFederationAsset) return null;
73
+ return serveByPath(c, path.join(pwd, request.requestPath), request, true, request.isModuleFederationRemoteEntry);
74
+ };
75
+ return {
76
+ resolveRequest,
77
+ serveStaticHit,
78
+ serveModuleFederationAsset
79
+ };
80
+ };
81
+ export { createModuleFederationStaticServing, servePreCompressedPublicRouteAsset };
@@ -9,10 +9,10 @@ import { renderRscHandler } from "./renderRscHandler.mjs";
9
9
  import { serverActionHandler } from "./serverActionHandler.mjs";
10
10
  import { ssrRender } from "./ssrRender.mjs";
11
11
  import { __webpack_require__ } from "../../rslib-runtime.mjs";
12
- import * as __rspack_external__modern_js_runtime_utils_router_2aa8d96f from "@modern-js/runtime-utils/router";
12
+ import * as __rspack_external__modern_js_runtime_utils_router_4aa9f9b0 from "@modern-js/runtime-utils/router";
13
13
  __webpack_require__.add({
14
14
  "@modern-js/runtime-utils/router" (module) {
15
- module.exports = __rspack_external__modern_js_runtime_utils_router_2aa8d96f;
15
+ module.exports = __rspack_external__modern_js_runtime_utils_router_4aa9f9b0;
16
16
  }
17
17
  });
18
18
  const DYNAMIC_ROUTE_REG = /\/:./;
@@ -2,11 +2,10 @@ import type { Middleware } from '../../../types';
2
2
  export declare const MODULE_FEDERATION_MANIFEST_FILE = "mf-manifest.json";
3
3
  export type ModuleFederationServeAssets = {
4
4
  assets: Set<string>;
5
- remoteEntry: string | null;
5
+ remoteEntries: Set<string>;
6
6
  };
7
- export declare const trimLeadingSlash: (value: string) => string;
8
7
  export declare const getModuleFederationRequestPath: (pathname: string, pathPrefix: string) => string;
9
- export declare const isModuleFederationManifestRequest: (requestPath: string) => requestPath is "mf-manifest.json";
8
+ export declare const isModuleFederationManifestRequest: (requestPath: string) => boolean;
10
9
  export declare const applyModuleFederationAssetHeaders: (c: Parameters<Middleware>[0]) => void;
11
10
  export declare const patchModuleFederationManifestPublicPath: (c: Parameters<Middleware>[0], manifestBuffer: Buffer, pathPrefix: string) => Buffer<ArrayBufferLike>;
12
11
  export declare const patchModuleFederationRemoteEntryPublicPath: (c: Parameters<Middleware>[0], remoteEntryBuffer: Buffer, pathPrefix: string) => Buffer<ArrayBufferLike>;
@@ -1,13 +1,12 @@
1
1
  import type { Middleware } from '../../../types';
2
2
  type SupportedEncoding = 'br' | 'gzip';
3
- export type ResolvePreCompressedAssetResult = {
3
+ type ResolvePreCompressedAssetResult = {
4
4
  selected: {
5
5
  filepath: string;
6
6
  encoding: SupportedEncoding;
7
7
  } | null;
8
8
  hasVariant: boolean;
9
9
  };
10
- export declare const appendVaryHeader: (c: Parameters<Middleware>[0], value: string) => void;
11
10
  export declare const resolvePreCompressedAsset: (c: Parameters<Middleware>[0], filepath: string) => Promise<ResolvePreCompressedAssetResult>;
12
11
  export declare const applyPreCompressedAssetHeaders: (c: Parameters<Middleware>[0], preCompressedAsset: ResolvePreCompressedAssetResult) => void;
13
12
  export {};
@@ -0,0 +1,19 @@
1
+ import type { ServerRoute } from '@modern-js/types';
2
+ import type { Middleware } from '../../../types';
3
+ type MiddlewareContext = Parameters<Middleware>[0];
4
+ type StaticServingRequest = {
5
+ requestPath: string;
6
+ isModuleFederationAsset: boolean;
7
+ isModuleFederationRemoteEntry: boolean;
8
+ };
9
+ type StaticServingOptions = {
10
+ pwd: string;
11
+ pathPrefix: string;
12
+ };
13
+ export declare const servePreCompressedPublicRouteAsset: (c: MiddlewareContext, pwd: string, route: ServerRoute) => Promise<(Response & import("hono").TypedResponse<Uint8Array<ArrayBuffer>, 200, "body">) | null>;
14
+ export declare const createModuleFederationStaticServing: ({ pwd, pathPrefix, }: StaticServingOptions) => {
15
+ resolveRequest: (pathname: string) => Promise<StaticServingRequest | null>;
16
+ serveStaticHit: (c: MiddlewareContext, request: StaticServingRequest) => Promise<(Response & import("hono").TypedResponse<Uint8Array<ArrayBuffer>, 200, "body">) | null>;
17
+ serveModuleFederationAsset: (c: MiddlewareContext, request: StaticServingRequest) => Promise<(Response & import("hono").TypedResponse<Uint8Array<ArrayBuffer>, 200, "body">) | null> | null;
18
+ };
19
+ export {};
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.5.0-ultramodern.4",
20
+ "version": "3.5.0-ultramodern.41",
21
21
  "types": "./dist/types/index.d.ts",
22
22
  "main": "./dist/cjs/index.js",
23
23
  "exports": {
@@ -74,21 +74,21 @@
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.27",
77
+ "hono": "^4.12.28",
78
78
  "ts-deepmerge": "8.0.0",
79
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.4",
80
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.5.0-ultramodern.4",
81
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.4"
79
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.41",
80
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.41",
81
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.5.0-ultramodern.41"
82
82
  },
83
83
  "devDependencies": {
84
- "@rslib/core": "0.23.1",
84
+ "@rslib/core": "0.23.2",
85
85
  "@types/cloneable-readable": "^2.0.3",
86
86
  "@types/merge-deep": "^3.0.3",
87
- "@types/node": "^26.0.1",
88
- "@typescript/native-preview": "7.0.0-dev.20260628.1",
89
- "http-proxy-middleware": "^4.1.1",
90
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.5.0-ultramodern.4",
91
- "@scripts/rstest-config": "2.66.0"
87
+ "@types/node": "^26.1.1",
88
+ "@typescript/native-preview": "7.0.0-dev.20260707.2",
89
+ "http-proxy-middleware": "^4.2.0",
90
+ "@scripts/rstest-config": "2.66.0",
91
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.5.0-ultramodern.41"
92
92
  },
93
93
  "sideEffects": false,
94
94
  "publishConfig": {