Socket
Socket
Sign inDemoInstall

@module-federation/node

Package Overview
Dependencies
Maintainers
5
Versions
609
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@module-federation/node - npm Package Compare versions

Comparing version 0.15.1 to 0.15.2-rc.0

179

CHANGELOG.md

@@ -5,2 +5,181 @@ # Changelog

## [0.15.2-rc.0](https://github.com/module-federation/nextjs-mf/compare/node-0.15.1...node-0.15.2-rc.0) (2023-05-23)
### Bug Fixes
* chunk and module duplications ([#885](https://github.com/module-federation/nextjs-mf/issues/885)) ([199e6b9](https://github.com/module-federation/nextjs-mf/commit/199e6b9937f4a2ca6caedb3ae4767342de463cb6))
* client prod build issues ([#899](https://github.com/module-federation/nextjs-mf/issues/899)) ([470d7ad](https://github.com/module-federation/nextjs-mf/commit/470d7ad408ae8d64dbccc5a9528eaa2ed60fa2ca))
* externalization and missing runtime chunks ([#887](https://github.com/module-federation/nextjs-mf/issues/887)) ([c79cd62](https://github.com/module-federation/nextjs-mf/commit/c79cd6226d3134f1d6294cd8eba40c8c33af5cb5))
* missing chunk hashes on exposed modules ([#893](https://github.com/module-federation/nextjs-mf/issues/893)) ([cfa43f5](https://github.com/module-federation/nextjs-mf/commit/cfa43f506999d5ce3ab6afeea513d50d85f7886e))
## [0.14.7-rc.2](https://github.com/module-federation/nextjs-mf/compare/node-0.14.7-rc.1...node-0.14.7-rc.2) (2023-05-17)
## [0.14.7-rc.1](https://github.com/module-federation/nextjs-mf/compare/node-0.14.7-rc.0...node-0.14.7-rc.1) (2023-05-17)
### Bug Fixes
* **chunk-module-duplication:** prevent runtime reset and share scope loss ([14bfc38](https://github.com/module-federation/nextjs-mf/commit/14bfc38515a4da3be7321d4b6d876905d45ad20b))
## [0.14.7-rc.0](https://github.com/module-federation/nextjs-mf/compare/node-0.14.7-beta.3...node-0.14.7-rc.0) (2023-05-16)
## [0.14.7-beta.3](https://github.com/module-federation/nextjs-mf/compare/node-0.14.7-beta.2...node-0.14.7-beta.3) (2023-05-16)
## [0.14.7-beta.2](https://github.com/module-federation/nextjs-mf/compare/node-0.14.7-beta.1...node-0.14.7-beta.2) (2023-05-16)
## [0.14.7-beta.1](https://github.com/module-federation/nextjs-mf/compare/node-0.14.7-beta.0...node-0.14.7-beta.1) (2023-05-16)
## [0.14.7-beta.0](https://github.com/module-federation/nextjs-mf/compare/node-0.14.6...node-0.14.7-beta.0) (2023-05-16)
## [0.14.6](https://github.com/module-federation/nextjs-mf/compare/node-0.14.5...node-0.14.6) (2023-05-16)
## [0.14.5](https://github.com/module-federation/nextjs-mf/compare/node-0.14.5-beta.0...node-0.14.5) (2023-05-15)
## [0.14.5-beta.0](https://github.com/module-federation/nextjs-mf/compare/node-0.14.4...node-0.14.5-beta.0) (2023-05-15)
### Features
* Quantum Modules ([#872](https://github.com/module-federation/nextjs-mf/issues/872)) ([2991039](https://github.com/module-federation/nextjs-mf/commit/299103932b4e0aa6d8017be588ffa5272f519260))
## [0.14.4](https://github.com/module-federation/nextjs-mf/compare/node-0.14.4-beta.0...node-0.14.4) (2023-05-13)
## [0.14.4-beta.0](https://github.com/module-federation/nextjs-mf/compare/node-0.14.3...node-0.14.4-beta.0) (2023-05-13)
### Bug Fixes
* remove container proxy code ([6123d98](https://github.com/module-federation/nextjs-mf/commit/6123d9846606d76be949492ca04474f5c8164bc7))
### Features
* [7] Async boundary runtime server ([#851](https://github.com/module-federation/nextjs-mf/issues/851)) ([7fa792a](https://github.com/module-federation/nextjs-mf/commit/7fa792a4b518cd007b5ac41db225e20521063e73)), closes [#864](https://github.com/module-federation/nextjs-mf/issues/864)
### BREAKING CHANGES
* automaticAsyncBoundary option has been removed
* fix: exclude specific pages from page map automatically
* refactor: conslidate codebase
* fix: improve hot reload share recovery
* refactor: remove server jsonp template
* chore: remove dead code from runtime modules
* fix: clean up jsonp getCustomJsonpCode
getting chunk loading global from compiler output options
* feat: adding cleanInitArrays runtime helper
* chore: remove share scope hoist and module hoisting system
* chore: cleanup code
## [0.14.3](https://github.com/module-federation/nextjs-mf/compare/node-0.14.3-beta.0...node-0.14.3) (2023-05-03)
## [0.14.3-beta.0](https://github.com/module-federation/nextjs-mf/compare/node-0.14.2...node-0.14.3-beta.0) (2023-05-03)
## [0.14.2](https://github.com/module-federation/nextjs-mf/compare/node-0.14.2-beta.1...node-0.14.2) (2023-04-28)
## [0.14.2-beta.1](https://github.com/module-federation/nextjs-mf/compare/node-0.14.2-beta.0...node-0.14.2-beta.1) (2023-04-28)
## [0.14.2-beta.0](https://github.com/module-federation/nextjs-mf/compare/node-0.14.1...node-0.14.2-beta.0) (2023-04-28)
### Bug Fixes
* use [fullhash] if no hash exists / in development mode. ([dfa7fb3](https://github.com/module-federation/nextjs-mf/commit/dfa7fb3a49b81b87dae43ec57ff2f86f5c2b7501))
## [0.14.1](https://github.com/module-federation/nextjs-mf/compare/node-0.14.1-beta.0...node-0.14.1) (2023-04-28)
## [0.14.1-beta.0](https://github.com/module-federation/nextjs-mf/compare/node-0.14.0...node-0.14.1-beta.0) (2023-04-28)
### Features
* Improve module chunk connections ([#802](https://github.com/module-federation/nextjs-mf/issues/802)) ([ce0bd7b](https://github.com/module-federation/nextjs-mf/commit/ce0bd7b16e080f712e6db0bdcd3955a8167c274f)), closes [#803](https://github.com/module-federation/nextjs-mf/issues/803) [#808](https://github.com/module-federation/nextjs-mf/issues/808) [#811](https://github.com/module-federation/nextjs-mf/issues/811)
## [0.13.1](https://github.com/module-federation/nextjs-mf/compare/node-0.13.1-beta.0...node-0.13.1) (2023-04-19)
## [0.13.1-beta.0](https://github.com/module-federation/nextjs-mf/compare/node-0.13.0...node-0.13.1-beta.0) (2023-04-19)
### Bug Fixes
* use container proxy on script VM instead of host resolver point ([2929d0f](https://github.com/module-federation/nextjs-mf/commit/2929d0f64d4b8edf268af5ca83f807a02b121861))
* get delegates working ([#527](https://github.com/module-federation/nextjs-mf/issues/527)) ([7655568](https://github.com/module-federation/nextjs-mf/commit/7655568fcef8dbfda40573deb5d3d029c101074c))
* improved asset pipeline ([63928b2](https://github.com/module-federation/nextjs-mf/commit/63928b28150c2c4e3adb9e14fb7aa54f5cf1578d))
* peer dependencies metadata ([d3a2ed0](https://github.com/module-federation/nextjs-mf/commit/d3a2ed0e378b59afdeb632d1e2e0290f05cbca19))
* solve externalization ([49f52e5](https://github.com/module-federation/nextjs-mf/commit/49f52e53ddddc990d31e6aa510d67dc0552a9d9a))
* use EntryPlugin for injection of remotes ([e522c5a](https://github.com/module-federation/nextjs-mf/commit/e522c5ad2b7adcbd6c39f9c5fdb7a3e418277b7a))
### Features
* delegate module support ([5061d3d](https://github.com/module-federation/nextjs-mf/commit/5061d3d64d7d83dbb25b4ef2378d434545186cb1))
* chunk flushing in delegates ([5e2375f](https://github.com/module-federation/nextjs-mf/commit/5e2375f598437803105ac4bc2237f6b652554d00))
* delegate module support ([8dd154c](https://github.com/module-federation/nextjs-mf/commit/8dd154c261b34183b12250ce204904cd3e085658))
* delegate module support ([d242163](https://github.com/module-federation/nextjs-mf/commit/d24216324183bfec5c7ba672ba6da05679f67809))
* delegates part two ([1be2686](https://github.com/module-federation/nextjs-mf/commit/1be2686624798a7df9f447b48279294985b3f592))
* improve chunk correlation ([22d8afc](https://github.com/module-federation/nextjs-mf/commit/22d8afccff101044fcdeba390656950dbc6eafed))
* new chunk flushing system for exposed modules ([97a75d8](https://github.com/module-federation/nextjs-mf/commit/97a75d8702f2ddc5e12cff2ac4d24aca1df6f990))
* prepare for v7 ([7bc4b3b](https://github.com/module-federation/nextjs-mf/commit/7bc4b3bd44e0926a52d6a9cbe56f0c4d7bb700ae))
### BREAKING CHANGES
* safety breaking change note
BREAKING_CHANGE: safety breaking change note
## [0.15.1](https://github.com/module-federation/nextjs-mf/compare/node-0.15.0...node-0.15.1) (2023-05-22)

@@ -7,0 +186,0 @@

5

package.json
{
"public": true,
"name": "@module-federation/node",
"version": "0.15.1",
"version": "0.15.2-rc.0",
"type": "commonjs",

@@ -38,3 +38,4 @@ "main": "src/index.js",

"node-fetch": "^2.6.7",
"@module-federation/utilities": "1.8.0"
"@module-federation/utilities": "1.8.1-rc.1",
"webpack-sources": "3.2.3"
},

@@ -41,0 +42,0 @@ "peerDependencies": {

200

src/plugins/ChunkCorrelationPlugin.js

@@ -59,4 +59,11 @@ "use strict";

function getExposedModules(stats, exposedFile) {
return stats.modules.filter((mod) => mod.name.startsWith(exposedFile));
return stats.modules.filter((mod) => mod.name?.startsWith(exposedFile));
}
function getDependenciesOfChunk(stats, chunk) {
return stats.chunks
.filter((c) => c.children.includes(chunk.id))
.reduce((acc, c) => {
return acc.concat(c.modules);
}, []);
}
/**

@@ -69,5 +76,21 @@ *

function getExposed(stats, mod) {
const chunks = stats.chunks.filter((chunk) => mod.chunks.some((id) => id === chunk.id));
const chunks = stats.chunks.filter((chunk) => {
return chunk.modules.find((modsInChunk) => {
return modsInChunk.id === mod.id && !modsInChunk.dependent;
});
});
const dependencies = stats.modules
.filter((sharedModule) => {
if (sharedModule.moduleType !== 'consume-shared-module')
return false;
return sharedModule.issuerId === mod.id;
})
.map((sharedModule) => {
return sharedModule.identifier.split('|')[2];
});
const flatChunks = flatMap(chunks, (chunk) => ({
[chunk.id]: chunk.files.map((f) => `${stats.publicPath === 'auto' ? '' : stats.publicPath || ''}${f}`),
[chunk.id]: {
files: chunk.files.map((f) => `${stats.publicPath === 'auto' ? '' : stats.publicPath || ''}${f}`),
requiredModules: dependencies,
},
}));

@@ -91,2 +114,14 @@ return flatChunks.reduce((acc, chunk) => {

}
function searchReason(mod, check) {
if (mod.reasons && check(mod.reasons)) {
return true;
}
return !!mod.reasons && mod.reasons.some((m) => searchReason(m, check));
}
function searchIssuerAndReason(mod, check) {
const foundIssuer = searchIssuer(mod, (issuer) => check(issuer));
if (foundIssuer)
return foundIssuer;
return searchReason(mod, (reason) => reason.some((r) => check(r?.moduleIdentifier)));
}
/**

@@ -105,2 +140,23 @@ * @param {import("webpack").Module} mod

}
function getIssuersAndReasons(mod, check) {
if (mod.issuer && check(mod.issuer)) {
return [mod.issuer];
}
if (mod.reasons &&
searchReason(mod, (reason) => reason.some((r) => check(r?.moduleIdentifier)))) {
return mod.reasons
.filter((r) => {
return r.moduleIdentifier && check(r.moduleIdentifier);
})
.map((r) => r.moduleIdentifier);
}
return ((mod.modules &&
mod.modules
.filter((m) => searchIssuerAndReason(m, check))
.map((m) => {
return (m.issuer ||
m.reasons.find((r) => check(r?.moduleIdentifier)).moduleIdentifier);
})) ||
[]);
}
/**

@@ -133,9 +189,9 @@ * @param {string} issuer

return flatMap(stats.chunks.filter((chunk) => {
if (!stats.entrypoints[federationPlugin._options.name]) {
if (!stats.entrypoints[federationPlugin.name]) {
return false;
}
return stats.entrypoints[federationPlugin._options.name].chunks.some((id) => chunk.id === id);
return stats.entrypoints[federationPlugin.name].chunks.some((id) => chunk.id === id);
}), (chunk) => flatMap(chunk.children, (id) => stats.chunks.filter((c) => c.id === id &&
c.files.length > 0 &&
c.parents.some((p) => stats.entrypoints[federationPlugin._options.name].chunks.some((c) => c === p)) &&
c.parents.some((p) => stats.entrypoints[federationPlugin.name].chunks.some((c) => c === p)) &&
c.modules.some((m) => searchIssuer(m, (issuer) => issuer?.startsWith('consume-shared-module'))))))

@@ -158,11 +214,17 @@ .map((chunk) => ({

: [];
return flatMap(chunks, (chunk) => flatMap(chunk.children, (id) => stats.chunks.filter((c) => c.id === id &&
c.files.length > 0 &&
c.modules.some((m) => searchIssuer(m, (issuer) => issuer?.startsWith('consume-shared-module'))))))
.map((chunk) => ({
chunks: chunk.files.map((f) => `${stats.publicPath === 'auto' ? '' : stats.publicPath || ''}${f}`),
provides: flatMap(chunk.modules.filter((m) => searchIssuer(m, (issuer) => issuer?.startsWith('consume-shared-module'))), (m) => getIssuers(m, (issuer) => issuer?.startsWith('consume-shared-module')))
.map(parseFederatedIssuer)
.filter((f) => !!f),
}))
return flatMap(chunks, (chunk) => flatMap(chunk.children, (id) => stats.chunks.filter((c) => {
return (c.id === id &&
c.files.length > 0 &&
c.modules.some((m) => {
return searchIssuerAndReason(m, (check) => check?.startsWith('consume-shared-module'));
}));
})))
.map((chunk) => {
return {
chunks: chunk.files.map((f) => `${stats.publicPath === 'auto' ? '' : stats.publicPath || ''}${f}`),
provides: flatMap(chunk.modules.filter((m) => searchIssuerAndReason(m, (check) => check?.startsWith('consume-shared-module'))), (m) => getIssuersAndReasons(m, (issuer) => issuer?.startsWith('consume-shared-module')))
.map(parseFederatedIssuer)
.filter((f) => !!f),
};
})
.filter((c) => c.provides.length > 0);

@@ -176,4 +238,4 @@ }

*/
function getFederationStats(stats, federationPlugin) {
const exposedModules = Object.entries(federationPlugin._options.exposes).reduce((exposedModules, [exposedAs, exposedFile]) => Object.assign(exposedModules, {
function getFederationStats(stats, federationPluginOptions) {
const exposedModules = Object.entries(federationPluginOptions.exposes).reduce((exposedModules, [exposedAs, exposedFile]) => Object.assign(exposedModules, {
[exposedAs]: getExposedModules(stats, exposedFile),

@@ -186,4 +248,4 @@ }), {});

/** @type {string} */
const remote = federationPlugin._options.library?.name || federationPlugin._options.name;
const sharedModules = getSharedModules(stats, federationPlugin);
const remote = federationPluginOptions.library?.name || federationPluginOptions.name;
const sharedModules = getSharedModules(stats, federationPluginOptions);
const remoteModules = getRemoteModules(stats);

@@ -195,3 +257,3 @@ return {

? stats.assetsByChunkName[remote][0]
: federationPlugin._options.filename}`,
: federationPluginOptions.filename}`,
sharedModules,

@@ -235,27 +297,89 @@ exposes,

}
let alreadyRun = false;
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
compilation.hooks.processAssets.tapPromise({
compilation.hooks.processAssets.tap({
name: PLUGIN_NAME,
stage: compilation.constructor.PROCESS_ASSETS_STAGE_ANALYSE,
}, async () => {
stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT,
},
// PLUGIN_NAME,
async () => {
const [federationOpts] = federationPlugins.map((federationPlugin) => {
return federationPlugin?._options;
});
let container;
for (const [name, entry] of compilation.entrypoints) {
if (container)
break;
federationOpts.name.includes(name) && (container = entry);
}
if (!container)
return;
container = container?.getEntrypointChunk();
const [containerEntryModule] = Array.from(compilation.chunkGraph.getChunkEntryModulesIterable(container));
const exposedObj = Object.fromEntries(containerEntryModule._exposes);
const moduleMap = {};
for (let mod of compilation.modules) {
if (mod.rawRequest)
moduleMap[mod.rawRequest] = mod;
}
const exposedResolved = {};
for (let exposed in exposedObj) {
exposedResolved[exposed] = moduleMap[exposedObj[exposed].import];
}
const builtExposes = {};
container.getAllAsyncChunks().forEach((chunk) => {
for (let expose in exposedResolved) {
const rootModulesInChunk = compilation.chunkGraph.getChunkRootModules(chunk);
if (rootModulesInChunk.includes(exposedResolved[expose])) {
const referencedChunks = chunk.getAllReferencedChunks();
const currentModule = exposedResolved[expose];
if (!builtExposes[expose])
builtExposes[expose] = [];
referencedChunks.forEach((chunk) => {
const rootReferencesInChunk = compilation.chunkGraph.getChunkRootModules(chunk);
const isNodeModule = rootReferencesInChunk.some((mod) => {
if (mod.rootModule)
mod = mod.rootModule;
return mod?.resource?.includes('node_modules');
});
if (isNodeModule)
return;
builtExposes[expose] = [
...builtExposes[expose],
...Array.from(chunk.files),
];
});
}
}
});
const stats = compilation.getStats().toJson({
performance: false,
time: false,
logging: 'none',
loggingDebug: false,
loggingTrace: false,
source: false,
children: false,
errors: false,
warnings: false,
errorsCount: false,
warningsCount: false,
builtAt: false,
timings: false,
all: false,
assets: true,
reasons: true,
modules: true,
children: true,
chunkGroups: true,
chunkModules: true,
chunkOrigins: false,
entrypoints: true,
namedChunkGroups: false,
chunkRelations: true,
chunks: true,
ids: true,
nestedModules: false,
outputPath: true,
publicPath: true,
});
const federatedModules = federationPlugins.map((federationPlugin) => getFederationStats(stats, federationPlugin));
const federatedModules = getFederationStats(stats, federationOpts);
federatedModules.exposes = builtExposes;
const sharedModules = getMainSharedModules(stats);
const vendorChunks = new Set();
sharedModules.forEach((share) => {
share?.chunks?.forEach((file) => {
vendorChunks.add(file);
});
});
const statsResult = {
sharedModules,
federatedModules,
federatedModules: [federatedModules],
};

@@ -262,0 +386,0 @@ const statsJson = JSON.stringify(statsResult);

@@ -81,3 +81,12 @@ /* eslint-disable @typescript-eslint/no-var-requires */

}
for (const c of chunk.getAllAsyncChunks()) {
if (c === chunk || chunkHasJs(c, chunkGraph))
continue;
if (c.ids) {
for (const id of c.ids)
initialChunkIds.add(id);
}
}
}
console.log('initialChunkIds', initialChunkIds);
return initialChunkIds;

@@ -176,3 +185,2 @@ };

? webpack_1.Template.indent([
'',
'var installedChunkData = installedChunks[chunkId];',

@@ -197,2 +205,3 @@ 'if(installedChunkData !== 0) { // 0 means "already installed".',

'if(fs.existsSync(filename)) {',
this._getLogger(`'chunk filename local load', chunkId`),
webpack_1.Template.indent([

@@ -210,2 +219,3 @@ "fs.readFile(filename, 'utf-8', function(err, content) {",

'} else {',
this._getLogger(`'chunk filename remote load', chunkId`),
webpack_1.Template.indent([

@@ -257,2 +267,3 @@ loadScript_1.default,

// there may still be a use case for that with promise new promise, depending on how we design it.
`console.log('requestedRemote',requestedRemote, "CURRENT NAME",${JSON.stringify(name)});`,
`var scriptUrl = new URL(requestedRemote);`,

@@ -299,3 +310,6 @@ this._getLogger(`'global.__remote_scope__'`, `global.__remote_scope__`),

'module.exports = __webpack_require__;',
`${webpack_1.RuntimeGlobals.externalInstallChunk} = installChunk;`,
`${webpack_1.RuntimeGlobals.externalInstallChunk} = function(){
console.log('node: webpack installing to install chunk id:', arguments['0'].id);
return installChunk.apply(this, arguments)
};`,
])

@@ -302,0 +316,0 @@ : '// no external install chunk',

@@ -7,2 +7,2 @@ /**

export default _default;
export declare const executeLoadTemplate = "\n function executeLoad(url, callback, name) {\n if(!name) {\n throw new Error('__webpack_require__.l name is required for ' + url);\n }\n\n if (typeof global.__remote_scope__[name] !== 'undefined') return callback(global.__remote_scope__[name]);\n\n const vm = require('vm');\n (global.webpackChunkLoad || global.fetch || require(\"node-fetch\"))(url).then(function (res) {\n return res.text();\n }).then(function (scriptContent) {\n try {\n // TODO: remove conditional in v7, this is to prevent breaking change between v6.0.x and v6.1.x\n const vmContext = typeof URLSearchParams === 'undefined' ?\n {exports, require, module, global, __filename, __dirname, URL, console, process,Buffer, ...global, remoteEntryName: name} :\n {exports, require, module, global, __filename, __dirname, URL, URLSearchParams, console, process,Buffer, ...global, remoteEntryName: name};\n\n const remote = vm.runInNewContext(scriptContent + '\\nmodule.exports', vmContext, {filename: 'node-federation-loader-' + name + '.vm'});\n const foundContainer = remote[name] || remote\n\n if(!global.__remote_scope__[name]) {\n global.__remote_scope__[name] = {\n get: foundContainer.get,\n init: function(initScope, initToken) {\n try {\n foundContainer.init(initScope, initToken)\n } catch (e) {\n // already initialized\n }\n }\n };\n global.__remote_scope__._config[name] = url;\n }\n callback(global.__remote_scope__[name]);\n } catch (e) {\n console.error('executeLoad hit catch block');\n e.target = {src: url};\n callback(e);\n }\n }).catch((e) => {\n e.target = {src: url};\n callback(e);\n });\n }\n";
export declare const executeLoadTemplate = "\n function executeLoad(url, callback, name) {\n if(!name) {\n throw new Error('__webpack_require__.l name is required for ' + url);\n }\n\n if (typeof global.__remote_scope__[name] !== 'undefined') return callback(global.__remote_scope__[name]);\n console.log('executeLoad', url, name);\n const vm = require('vm');\n (global.webpackChunkLoad || global.fetch || require(\"node-fetch\"))(url).then(function (res) {\n return res.text();\n }).then(function (scriptContent) {\n try {\n // TODO: remove conditional in v7, this is to prevent breaking change between v6.0.x and v6.1.x\n const vmContext = typeof URLSearchParams === 'undefined' ?{exports, require, module, global, __filename, __dirname, URL, URLSearchParams, console, process,Buffer, ...global, remoteEntryName: name}:\n {exports, require, module, global, __filename, __dirname, URL, URLSearchParams, console, process,Buffer, ...global, remoteEntryName: name};\n const remote = vm.runInNewContext(scriptContent + '\\nmodule.exports', vmContext, {filename: 'node-federation-loader-' + name + '.vm'});\n const foundContainer = remote[name] || remote\n\n if(!global.__remote_scope__[name]) {\n global.__remote_scope__[name] = foundContainer;\n global.__remote_scope__._config[name] = url;\n }\n callback(global.__remote_scope__[name]);\n } catch (e) {\n console.error('executeLoad hit catch block');\n e.target = {src: url};\n callback(e);\n }\n }).catch((e) => {\n e.target = {src: url};\n callback(e);\n });\n }\n";

@@ -52,3 +52,3 @@ "use strict";

if (typeof global.__remote_scope__[name] !== 'undefined') return callback(global.__remote_scope__[name]);
console.log('executeLoad', url, name);
const vm = require('vm');

@@ -60,6 +60,4 @@ (global.webpackChunkLoad || global.fetch || require("node-fetch"))(url).then(function (res) {

// TODO: remove conditional in v7, this is to prevent breaking change between v6.0.x and v6.1.x
const vmContext = typeof URLSearchParams === 'undefined' ?
{exports, require, module, global, __filename, __dirname, URL, console, process,Buffer, ...global, remoteEntryName: name} :
const vmContext = typeof URLSearchParams === 'undefined' ?{exports, require, module, global, __filename, __dirname, URL, URLSearchParams, console, process,Buffer, ...global, remoteEntryName: name}:
{exports, require, module, global, __filename, __dirname, URL, URLSearchParams, console, process,Buffer, ...global, remoteEntryName: name};
const remote = vm.runInNewContext(scriptContent + '\\nmodule.exports', vmContext, {filename: 'node-federation-loader-' + name + '.vm'});

@@ -69,12 +67,3 @@ const foundContainer = remote[name] || remote

if(!global.__remote_scope__[name]) {
global.__remote_scope__[name] = {
get: foundContainer.get,
init: function(initScope, initToken) {
try {
foundContainer.init(initScope, initToken)
} catch (e) {
// already initialized
}
}
};
global.__remote_scope__[name] = foundContainer;
global.__remote_scope__._config[name] = url;

@@ -81,0 +70,0 @@ }

@@ -78,49 +78,3 @@ 'use strict';

}
const proxy = {
get: (arg)=>{
return remote.get(arg).then((f)=>{
const m = f();
return ()=>new Proxy(m, {
get: (target, prop)=>{
if(global.usedChunks) global.usedChunks.add(${JSON.stringify(global)} + "->" + arg);
return target[prop];
}
})
})
},
init: function(shareScope) {
const handler = {
get(target, prop) {
if (target[prop]) {
Object.values(target[prop]).forEach(function(o) {
if(o.from === '_N_E') {
o.loaded = 1
}
})
}
return target[prop]
},
set(target, property, value) {
if(global.usedChunks) global.usedChunks.add(${JSON.stringify(global)} + "->" + property);
if (target[property]) {
return target[property]
}
target[property] = value
return true
}
}
try {
global.__remote_scope__[${JSON.stringify(global)}].init(new Proxy(shareScope, handler))
} catch (e) {
}
global.__remote_scope__[${JSON.stringify(global)}].__initialized = true
}
}
try {
proxy.init(__webpack_require__.S.default)
} catch(e) {
console.error('failed to init', ${JSON.stringify(global)}, e)
}
return proxy
return remote;
})`;

@@ -152,9 +106,2 @@ exports.generateRemoteTemplate = generateRemoteTemplate;

const { webpack } = compiler;
// const defs = {
// 'process.env.REMOTES': runtime,
// 'process.env.REMOTE_CONFIG': hot,
// };
// new ((webpack && webpack.DefinePlugin) || require("webpack").DefinePlugin)(
// defs
// ).apply(compiler);
const pluginOptions = {

@@ -165,6 +112,20 @@ ...this._options,

const chunkFileName = compiler.options?.output?.chunkFilename;
if (typeof chunkFileName === 'string' &&
!chunkFileName.includes('[hash]') &&
!chunkFileName.includes('[contenthash]')) {
compiler.options.output.chunkFilename = chunkFileName.replace('.js', '.[contenthash].js');
const uniqueName = compiler?.options?.output?.uniqueName || this._options.name;
if (typeof chunkFileName === 'string') {
const requiredSubstrings = [
'[chunkhash]',
'[contenthash]',
'[fullHash]',
uniqueName,
];
if (
//@ts-ignore
!requiredSubstrings.some((substring) =>
//@ts-ignore
chunkFileName.includes(substring))) {
const suffix = compiler.options.mode === 'development'
? `.[chunkhash].js`
: `.[chunkhash].js`;
compiler.options.output.chunkFilename = chunkFileName.replace('.js', suffix);
}
}

@@ -171,0 +132,0 @@ new (this.context.ModuleFederationPlugin ||

@@ -0,2 +1,6 @@

/**
* Initialize usedChunks and share it globally.
* @type {Set}
*/
export const usedChunks: Set<any>;
export function flushChunks(): Promise<any[]>;
"use strict";
/* eslint-disable no-undef */
Object.defineProperty(exports, "__esModule", { value: true });
exports.flushChunks = exports.usedChunks = void 0;
exports.usedChunks = new Set();
global.usedChunks = exports.usedChunks;
const flushChunks = async () => {
const allFlushed = await Promise.all(Array.from(exports.usedChunks).map(async (chunk) => {
const chunks = new Set();
const [remote, request] = chunk.split('->');
if (!global.__remote_scope__._config[remote]) {
return;
if (!globalThis.usedChunks) {
globalThis.usedChunks = new Set();
}
/**
* Initialize usedChunks and share it globally.
* @type {Set}
*/
exports.usedChunks = globalThis.usedChunks;
/**
* Load hostStats from the JSON file.
* @returns {object} hostStats - An object containing host stats data.
*/
const loadHostStats = () => {
try {
return __non_webpack_require__('../federated-stats.json');
}
catch (e) {
return {};
}
};
/**
* Create a shareMap based on the loaded modules.
* @returns {object} shareMap - An object containing the shareMap data.
*/
const createShareMap = () => {
// Check if __webpack_share_scopes__ is defined and has a default property
if (__webpack_share_scopes__?.default) {
// Reduce the keys of the default property to create the share map
return Object.keys(__webpack_share_scopes__.default).reduce((acc, key) => {
// Get the loaded modules for the current key
const loadedModules = Object.values(__webpack_share_scopes__.default[key])
// Filter out the modules that are not loaded
.filter((sharedModule) => sharedModule.loaded)
// Map the filtered modules to their 'from' properties
.map((sharedModule) => sharedModule.from);
// If there are any loaded modules, add them to the accumulator object
if (loadedModules.length > 0) {
acc[key] = loadedModules;
}
// Return the accumulator object for the next iteration
return acc;
}, {});
}
// If __webpack_share_scopes__ is not defined or doesn't have a default property, return an empty object
return {};
};
/**
* Process a single chunk and return an array of updated chunks.
* @param {string} chunk - A chunk string containing remote and request data.
* @param {object} shareMap - An object containing the shareMap data.
* @param {object} hostStats - An object containing host stats data.
* @returns {Promise<Array>} A promise that resolves to an array of updated chunks.
*/
const processChunk = async (chunk, shareMap, hostStats) => {
// Create a set to store the chunks
const chunks = new Set();
// Split the chunk string into remote and request
const [remote, request] = chunk.split('->');
// If the remote is not defined in the global config, return
if (!global.__remote_scope__._config[remote]) {
console.error(`flush chunks:`, `Remote ${remote} is not defined in the global config`);
return;
}
try {
// Extract the remote name from the URL
const remoteName = new URL(global.__remote_scope__._config[remote]).pathname
.split('/')
.pop();
// Construct the stats file URL from the remote config
const statsFile = global.__remote_scope__._config[remote]
.replace(remoteName, 'federated-stats.json')
.replace('ssr', 'chunks');
let stats = {};
try {
// Fetch the remote config and stats file
stats = await fetch(statsFile).then((res) => res.json());
}
// fetch the json file
try {
const statsFile = global.__remote_scope__._config[remote].replace('remoteEntry.js', 'federated-stats.json');
const stats = await fetch(statsFile).then(async (res) => await res.json());
chunks.add(global.__remote_scope__._config[remote].replace('ssr', 'chunks'));
const [prefix] = global.__remote_scope__._config[remote].split('static/');
if (stats.federatedModules) {
stats.federatedModules.forEach((modules) => {
if (modules.exposes?.[request]) {
modules.exposes[request].forEach((chunk) => {
Object.values(chunk).forEach((chunk) => {
chunk.forEach((chunk) => {
chunks.add(prefix + chunk);
catch (e) {
console.error('flush error', e);
}
// Add the main chunk to the chunks set
chunks.add(global.__remote_scope__._config[remote].replace('ssr', 'chunks'));
// Extract the prefix from the remote config
const [prefix] = global.__remote_scope__._config[remote].split('static/');
// Process federated modules from the stats object
if (stats.federatedModules) {
stats.federatedModules.forEach((modules) => {
// Process exposed modules
if (modules.exposes?.[request]) {
modules.exposes[request].forEach((chunk) => {
chunks.add([prefix, chunk].join(''));
//TODO: reimplement this
Object.values(chunk).forEach((chunk) => {
// Add files to the chunks set
if (chunk.files) {
chunk.files.forEach((file) => {
chunks.add(prefix + file);
});
});
}
// Process required modules
if (chunk.requiredModules) {
chunk.requiredModules.forEach((module) => {
// Check if the module is in the shareMap
if (shareMap[module]) {
// If the module is from the host, log the host stats
if (shareMap[module][0].startsWith('host__')) {
console.log('host', hostStats);
}
}
});
}
});
}
});
}
return Array.from(chunks);
});
}
});
}
catch (e) {
console.log(e);
}
}));
// Return the array of chunks
return Array.from(chunks);
}
catch (e) {
console.error('flush error:', e);
}
};
/**
* Flush the chunks and return a deduplicated array of chunks.
* @returns {Promise<Array>} A promise that resolves to an array of deduplicated chunks.
*/
const flushChunks = async () => {
const hostStats = loadHostStats();
const shareMap = createShareMap();
const allFlushed = await Promise.all(Array.from(exports.usedChunks).map(async (chunk) => processChunk(chunk, shareMap, hostStats)));
// Deduplicate the chunks array
const dedupe = Array.from(new Set([...allFlushed.flat()]));
// Clear usedChunks
exports.usedChunks.clear();
// Filter out any undefined or null values
return dedupe.filter(Boolean);

@@ -41,0 +142,0 @@ };

@@ -22,3 +22,3 @@ "use strict";

_config: {},
_medusa: {}
_medusa: {},
};

@@ -53,5 +53,9 @@ Object.keys(req.cache).forEach((key) => {

for (const property in remoteScope._medusa) {
fetchModule(property).then((res) => res.json()).then((medusaResponse) => {
fetchModule(property)
.then((res) => res.json())
.then((medusaResponse) => {
//@ts-ignore
if (medusaResponse.version !== remoteScope._medusa[property].version) {
if (medusaResponse.version !==
//@ts-ignore
remoteScope?._medusa[property].version) {
console.log('medusa config changed', property, 'hot reloading to refetch');

@@ -58,0 +62,0 @@ performReload(true);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc