From d4bcde20445f9a8cef2be41eab08663ac6b289b2 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 24 Feb 2023 14:36:44 -0800 Subject: [PATCH 01/32] feat: next plugin --- dashboard-plugin/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index 78bacb11..b7e7bcc3 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.7.0", + "version": "2.7.2", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0", @@ -23,6 +23,7 @@ "bin", "helpers", "FederationDashboardPlugin.js", + "medusa-delegate.js", "convertToGraph.js", "mergeGraphs.js", "client-version.js", From 9b9e12d1cda44ba8871286b5814f5b4d2ab2253d Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 24 Feb 2023 14:37:15 -0800 Subject: [PATCH 02/32] feat: next plugin --- dashboard-plugin/FederationDashboardPlugin.js | 275 ++++++------------ dashboard-plugin/convertToGraph.js | 9 +- dashboard-plugin/medusa-delegate.js | 2 + 3 files changed, 93 insertions(+), 193 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index f0080fca..18c095bd 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -93,8 +93,11 @@ class FederationDashboardPlugin { */ apply(compiler) { compiler.options.output.uniqueName = `v${Date.now()}`; + new AddRuntimeRequiremetToPromiseExternal().apply(compiler); - const FederationPlugin = compiler.options.plugins.find((plugin) => plugin.constructor.name === "ModuleFederationPlugin"); + const FederationPlugin = compiler.options.plugins.find((plugin) => { + return plugin.constructor.name === "ModuleFederationPlugin" || plugin.constructor.name === "NextFederationPlugin"; + }); if (FederationPlugin) { this.FederationPluginOptions = Object.assign( {}, @@ -117,7 +120,9 @@ class FederationDashboardPlugin { name: PLUGIN_NAME, stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT, }, - () => this.processWebpackGraph(compilation) + (assets) => { + return this.processWebpackGraph(compilation, assets); + } ); }); @@ -131,98 +136,10 @@ class FederationDashboardPlugin { } } - parseModuleAst(compilation, callback) { - const filePaths = []; - const allArgumentsUsed = []; - // Explore each chunk (build output): - compilation.chunks.forEach((chunk) => { - // Explore each module within the chunk (built inputs): - chunk.getModules().forEach((module) => { - // Loop through all the dependencies that has the named export that we are looking for - const matchedNamedExports = module.dependencies.filter((dep) => dep.name === "federateComponent"); - - if (matchedNamedExports.length > 0 && module.resource) { - filePaths.push({ - resource: module.resource, - file: module.resourceResolveData.relativePath, - }); - } - }); - - filePaths.forEach(({ resource, file }) => { - const sourceCode = fs.readFileSync(resource).toString("utf-8"); - const ast = parser.parse(sourceCode, { - sourceType: "unambiguous", - plugins: ["jsx", "typescript"], - }); - - // traverse the abstract syntax tree - traverse(ast, { - /** - * We want to run a function depending on a found nodeType - * More node types are documented here: https://babeljs.io/docs/en/babel-types#api - */ - CallExpression: (path) => { - const { node } = path; - const { callee, arguments: args } = node; - - if (callee.loc.identifierName === "federateComponent") { - const argsAreStrings = args.every((arg) => arg.type === "StringLiteral"); - if (!argsAreStrings) { - return; - } - const argsValue = [file]; - - // we collect the JS representation of each argument used in this function call - for (let i = 0; i < args.length; i++) { - const a = args[i]; - let { code } = generate(a); - - if (code.startsWith("{")) { - // wrap it in parentheses, so when it's eval-ed, it is eval-ed correctly into an JS object - code = `(${code})`; - } - - const value = eval(code); - - // If the value is a Node, that means it was a variable name - // There is no easy way to resolve the variable real value, so we just skip any function calls - // that has variable as its args - if (isNode(value)) { - // by breaking out of the loop here, - // we also prevent this args to be pushed to `allArgumentsUsed` - break; - } else { - argsValue.push(value); - } - - if (i === args.length - 1) { - // push to the top level array - allArgumentsUsed.push(argsValue); - } - } - } - }, - }); - }); - }); - const uniqueArgs = allArgumentsUsed.reduce((acc, current) => { - const id = current.join("|"); - acc[id] = current; - return acc; - }, {}); - this.allArgumentsUsed = Object.values(uniqueArgs); - if (callback) callback(); - } - processWebpackGraph(curCompiler, callback) { + processWebpackGraph(curCompiler, assets) { const liveStats = curCompiler.getStats(); const stats = liveStats.toJson(); - if (this._options.useAST) { - this.parseModuleAst(curCompiler); - } - - // fs.writeFileSync('stats.json', JSON.stringify(stats, null, 2)) // get RemoteEntryChunk const RemoteEntryChunk = this.getRemoteEntryChunk( @@ -233,9 +150,10 @@ class FederationDashboardPlugin { liveStats, this.FederationPluginOptions ); + + const chunkDependencies = this.getChunkDependencies(validChunkArray); const vendorFederation = this.buildVendorFederationMap(liveStats); - const rawData = { name: this.FederationPluginOptions.name, remotes: this.FederationPluginOptions.remotes, @@ -262,9 +180,10 @@ class FederationDashboardPlugin { console.warn(err); } + if (graphData) { const dashData = (this._dashData = JSON.stringify(graphData)); - this.writeStatsFiles(stats, dashData); + if (this._options.dashboardURL && !this._options.nextjs) { this.postDashboardData(dashData).catch((err) => { if (err) { @@ -274,6 +193,7 @@ class FederationDashboardPlugin { } }); } + return Promise.resolve().then(() => { const statsBuf = Buffer.from(dashData || "{}", "utf-8"); @@ -294,6 +214,7 @@ class FederationDashboardPlugin { curCompiler.emitAsset(this._options.filename, source); } } + // for versioned remote if ( curCompiler.emitAsset && @@ -303,8 +224,10 @@ class FederationDashboardPlugin { const remoteEntry = curCompiler.getAsset( this.FederationPluginOptions.filename ); + if(!remoteEntry) { + return Promise.resolve(); + } const cleanVersion = typeof rawData.version === "string" ? `_${rawData.version.split(".").join("_")}` : `_${rawData.version.toString()}`; - let codeSource; if (!remoteEntry.source._value && remoteEntry.source.source) { codeSource = remoteEntry.source.source(); @@ -337,33 +260,30 @@ class FederationDashboardPlugin { ); if (remoteEntry && graphData.version) { + const basename = path.basename(this.FederationPluginOptions.filename) + const bustedName = this.FederationPluginOptions.filename.replace(basename, [graphData.version, basename].join(".")); curCompiler.updateAsset( this.FederationPluginOptions.filename, originalRemoteEntrySource ); curCompiler.emitAsset( - [graphData.version, this.FederationPluginOptions.filename].join( - "." - ), + bustedName, remoteEntrySource ); } } - if (callback) { - return void callback(); - } }); } } getRemoteEntryChunk(stats, FederationPluginOptions) { - + return stats.chunks.find((chunk) => chunk.names.find((name) => name === FederationPluginOptions.name)); } getChunkDependencies(validChunkArray) { - + return validChunkArray.reduce((acc, chunk) => { const subset = chunk.getAllReferencedChunks(); const stringifiableChunk = Array.from(subset).map((sub) => { @@ -476,63 +396,68 @@ class FederationDashboardPlugin { } // This is no longer needed - can be deleted or used for refactoring the asset emitter - writeStatsFiles(stats, dashData) { + writeStatsFiles(stats, dashData, assets) { if (this._options.filename) { const hashPath = path.join(stats.outputPath, this._options.filename); if (!fs.existsSync(stats.outputPath)) { - fs.mkdirSync(stats.outputPath); + fs.mkdirSync(stats.outputPath, { recursive: true }) } - fs.writeFile(hashPath, dashData, { encoding: "utf-8" }, () => {}); - } - if (this._options.debug) { - console.log( - path.join(stats.outputPath, this.FederationPluginOptions.filename) - ); + fs.writeFileSync(hashPath, dashData, { encoding: "utf-8" }); } - const file = fs.readFileSync( + // if (this._options.debug) { + console.log( path.join(stats.outputPath, this.FederationPluginOptions.filename) ); - const { version } = JSON.parse(dashData); - if (!version) { - throw new Error("no version provided, cannot version remote"); - } - if (this._options.debug) { - console.log( - path.join( - stats.outputPath, - version, - this.FederationPluginOptions.filename - ) - ); - } - fs.mkdir( - path.join(stats.outputPath, version), - { recursive: true }, - (err) => { - if (err) throw err; - fs.writeFile( + // } + let file + + try { + file = assets[this.FederationPluginOptions.filename]._value + + const { version } = JSON.parse(dashData); + if (!version) { + throw new Error("no version provided, cannot version remote"); + } + if (this._options.debug) { + console.log( path.join( stats.outputPath, version, this.FederationPluginOptions.filename - ), - file, - (err) => { - if (this._options.debug) { - console.trace(err); - console.log( - "wrote versioned remote", - path.join( - stats.outputPath, - version, - this.FederationPluginOptions.filename - ) - ); - } - } + ) ); } - ); + fs.mkdir( + path.join(stats.outputPath, version), + { recursive: true }, + (err) => { + if (err) throw err; + fs.writeFile( + path.join( + stats.outputPath, + version, + this.FederationPluginOptions.filename + ), + file, + (err) => { + if (this._options.debug) { + console.trace(err); + console.log( + "wrote versioned remote", + path.join( + stats.outputPath, + version, + this.FederationPluginOptions.filename + ) + ); + } + } + ); + } + ); + } catch(e) { + console.log(e) + } const statsPath = path.join(stats.outputPath, "stats.json"); fs.writeFile( @@ -544,6 +469,7 @@ class FederationDashboardPlugin { } async postDashboardData(dashData) { + console.log('should post to dashboard') if (!this._options.dashboardURL) { return Promise.resolve(); } @@ -574,33 +500,29 @@ class NextMedusaPlugin { } apply(compiler) { - const sidecarData = this._options.filename.includes("sidecar") - ? path.join(compiler.options.output.path, this._options.filename) - : path.join( - compiler.options.output.path, - `sidecar-${this._options.filename}` - ); - const hostData = path.join( - compiler.options.output.path, - this._options.filename.replace("sidecar-", "") - ); + if(compiler.name === 'ChildFederationPlugin') return + const MedusaPlugin = new FederationDashboardPlugin({ ...this._options, - nextjs: true, }); MedusaPlugin.apply(compiler); + console.log('compiler name', compiler.name) - compiler.hooks.afterEmit.tap(PLUGIN_NAME, () => { +return + compiler.hooks.done.tap(PLUGIN_NAME, () => { const sidecarData = path.join( compiler.options.output.path, - `sidecar-${this._options.filename}` + `child-dashboard.json` ); const hostData = path.join( compiler.options.output.path, - this._options.filename.replace("sidecar-", "") + 'dashboard.json' ); + console.log('sidecar data',sidecarData); + console.log('host data', hostData); if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { + console.log('will write merged files'); fs.writeFileSync( hostData, JSON.stringify(mergeGraphs(require(sidecarData), require(hostData))) @@ -608,7 +530,7 @@ class NextMedusaPlugin { } }); - compiler.hooks.done.tapAsync("NextMedusaPlugin", (stats, done) => { + compiler.hooks.afterDone.tap("NextMedusaPlugin", (stats, done) => { if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { const dashboardData = fs.readFileSync(hostData, "utf8"); MedusaPlugin.postDashboardData(dashboardData).then(done).catch(done); @@ -619,37 +541,6 @@ class NextMedusaPlugin { } } -const withMedusa = - ({ name, ...medusaConfig }) => - (nextConfig = {}) => Object.assign({}, nextConfig, { - webpack(config, options) { - if ( - options.nextRuntime !== "edge" && - !options.isServer && - process.env.NODE_ENV === "production" - ) { - if (!name) { - throw new Error( - "Medusa needs a name for the app, please ensure plugin options has {name: }" - ); - } - config.plugins.push( - new NextMedusaPlugin({ - standalone: { name }, - ...medusaConfig, - }) - ); - } - - if (typeof nextConfig.webpack === "function") { - return nextConfig.webpack(config, options); - } - - return config; - }, - }); - module.exports = FederationDashboardPlugin; module.exports.clientVersion = require("./client-version"); module.exports.NextMedusaPlugin = NextMedusaPlugin; -module.exports.withMedusa = withMedusa; diff --git a/dashboard-plugin/convertToGraph.js b/dashboard-plugin/convertToGraph.js index 8eec647f..0dad1a4f 100644 --- a/dashboard-plugin/convertToGraph.js +++ b/dashboard-plugin/convertToGraph.js @@ -62,7 +62,14 @@ const convertToGraph = ( const name = data[3].replace("./", ""); let applicationID = data[2].replace("webpack/container/reference/", "") if(applicationID.includes("?")){ - applicationID = new URLSearchParams(applicationID.split('?')[1]).get('remoteName'); + const params = new URLSearchParams(applicationID.split('?')[1]); + const remoteReference = params.get("remoteName") || params.get("remote"); + if(remoteReference && remoteReference.includes("@")) { + const [global] = remoteReference.split('@') + applicationID = global + } else { + applicationID = remoteReference + } } const consume = { consumingApplicationID: name, diff --git a/dashboard-plugin/medusa-delegate.js b/dashboard-plugin/medusa-delegate.js index 7db3823f..dbb8163c 100644 --- a/dashboard-plugin/medusa-delegate.js +++ b/dashboard-plugin/medusa-delegate.js @@ -7,6 +7,8 @@ module.exports = ({fetchClient, currentHost, remoteName, dashboardURL})=> new Pr }) .then((res) => res.json()) .then((data) => { + console.log(data); + return null const name = `${data.name}_${data.version}`; const filename = `${data.version}.remoteEntry.js`; const url = new URL(filename, data.remoteURL); From 77b53d0bd941db0a71fa52e80d0cabe7be3b5082 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 24 Feb 2023 14:38:41 -0800 Subject: [PATCH 03/32] remove ast parser --- dashboard-plugin/FederationDashboardPlugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 18c095bd..6f9b8a09 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -81,7 +81,7 @@ class FederationDashboardPlugin { */ constructor(options) { this._options = Object.assign( - { debug: false, filename: "dashboard.json", useAST: false, fetchClient: false }, + { debug: false, filename: "dashboard.json", fetchClient: false }, options ); this._dashData = null; From 9761e3c5a1e258d11e6b53667f2a2f6d0716ca80 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 24 Feb 2023 14:40:21 -0800 Subject: [PATCH 04/32] remove unused deps --- dashboard-plugin/FederationDashboardPlugin.js | 4 ---- dashboard-plugin/package.json | 6 ------ 2 files changed, 10 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 6f9b8a09..0f201fc5 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -5,10 +5,6 @@ const AutomaticVendorFederation = require("@module-federation/automatic-vendor-f const convertToGraph = require("./convertToGraph"); const mergeGraphs = require("./mergeGraphs"); const DefinePlugin = require("webpack/lib/DefinePlugin"); -const parser = require("@babel/parser"); -const generate = require("@babel/generator").default; -const traverse = require("@babel/traverse").default; -const { isNode } = require("@babel/types"); const webpack = require("webpack"); const PLUGIN_NAME = "FederationDashboardPlugin"; diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index b7e7bcc3..fa885eb9 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -30,13 +30,7 @@ "LICENSE" ], "dependencies": { - "@babel/generator": "^7.15.4", - "@babel/parser": "^7.15.5", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4", "@module-federation/automatic-vendor-federation": "^1.2.1", - "deepmerge": "^4.2.2", - "flatted": "^3.0.0", "node-fetch": "^2.6.0" }, "peerDependencies": { From 6f553f725df24490fb249b99ff3f7d475054abf0 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 24 Feb 2023 14:47:09 -0800 Subject: [PATCH 05/32] remove unused deps --- dashboard-plugin/FederationDashboardPlugin.js | 52 +------------------ yarn.lock | 13 ++--- 2 files changed, 6 insertions(+), 59 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 0f201fc5..e7b078ba 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -400,11 +400,11 @@ class FederationDashboardPlugin { } fs.writeFileSync(hashPath, dashData, { encoding: "utf-8" }); } - // if (this._options.debug) { + if (this._options.debug) { console.log( path.join(stats.outputPath, this.FederationPluginOptions.filename) ); - // } + } let file try { @@ -465,7 +465,6 @@ class FederationDashboardPlugin { } async postDashboardData(dashData) { - console.log('should post to dashboard') if (!this._options.dashboardURL) { return Promise.resolve(); } @@ -490,53 +489,6 @@ class FederationDashboardPlugin { } } -class NextMedusaPlugin { - constructor(options) { - this._options = options; - } - - apply(compiler) { - if(compiler.name === 'ChildFederationPlugin') return - - - const MedusaPlugin = new FederationDashboardPlugin({ - ...this._options, - }); - MedusaPlugin.apply(compiler); - console.log('compiler name', compiler.name) - -return - compiler.hooks.done.tap(PLUGIN_NAME, () => { - const sidecarData = path.join( - compiler.options.output.path, - `child-dashboard.json` - ); - const hostData = path.join( - compiler.options.output.path, - 'dashboard.json' - ); - console.log('sidecar data',sidecarData); - console.log('host data', hostData); - if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { - console.log('will write merged files'); - fs.writeFileSync( - hostData, - JSON.stringify(mergeGraphs(require(sidecarData), require(hostData))) - ); - } - }); - - compiler.hooks.afterDone.tap("NextMedusaPlugin", (stats, done) => { - if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { - const dashboardData = fs.readFileSync(hostData, "utf8"); - MedusaPlugin.postDashboardData(dashboardData).then(done).catch(done); - } else { - done(); - } - }); - } -} module.exports = FederationDashboardPlugin; module.exports.clientVersion = require("./client-version"); -module.exports.NextMedusaPlugin = NextMedusaPlugin; diff --git a/yarn.lock b/yarn.lock index b810d286..17e06323 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,7 +42,7 @@ json5 "^2.1.2" semver "^6.3.0" -"@babel/generator@^7.15.4", "@babel/generator@^7.17.3", "@babel/generator@^7.17.7": +"@babel/generator@^7.17.3", "@babel/generator@^7.17.7": version "7.17.7" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz" integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w== @@ -159,7 +159,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.15.5", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.7": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.7": version "7.17.7" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.17.7.tgz" integrity sha512-bm3AQf45vR4gKggRfvJdYJ0gFLoCbsPxiFLSH6hTVYABptNHY6l9NrhnucVjQ/X+SPtLANT9lc0fFhikj+VBRA== @@ -264,7 +264,7 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.17.3": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.17.3": version "7.17.3" resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz" integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== @@ -280,7 +280,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.15.4", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": +"@babel/types@^7.0.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.17.0" resolved "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz" integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== @@ -3579,11 +3579,6 @@ find-yarn-workspace-root2@1.2.16: micromatch "^4.0.2" pkg-dir "^4.2.0" -flatted@^3.0.0: - version "3.2.5" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== - for-in@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" From 2303162292189a91ad7f3e50ff200eb001d596d6 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 24 Feb 2023 14:48:31 -0800 Subject: [PATCH 06/32] remove unused deps --- dashboard-plugin/medusa-delegate.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/dashboard-plugin/medusa-delegate.js b/dashboard-plugin/medusa-delegate.js index dbb8163c..7db3823f 100644 --- a/dashboard-plugin/medusa-delegate.js +++ b/dashboard-plugin/medusa-delegate.js @@ -7,8 +7,6 @@ module.exports = ({fetchClient, currentHost, remoteName, dashboardURL})=> new Pr }) .then((res) => res.json()) .then((data) => { - console.log(data); - return null const name = `${data.name}_${data.version}`; const filename = `${data.version}.remoteEntry.js`; const url = new URL(filename, data.remoteURL); From dbca1c0548ffd9a1f0ff96aa9c3961f7aab3405e Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Wed, 1 Mar 2023 15:48:39 -0800 Subject: [PATCH 07/32] Next Support --- dashboard-plugin/FederationDashboardPlugin.js | 66 ++++++++++++++++++- dashboard-plugin/index.d.ts | 22 +++++++ dashboard-plugin/medusa-delegate.js | 58 +++++++--------- dashboard-plugin/mergeGraphs.js | 45 ++++++++++--- dashboard-plugin/package.json | 3 + dashboard-plugin/postDashboardData.js | 24 +++++++ yarn.lock | 5 ++ 7 files changed, 180 insertions(+), 43 deletions(-) create mode 100644 dashboard-plugin/index.d.ts create mode 100644 dashboard-plugin/postDashboardData.js diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index e7b078ba..07b89d7f 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -76,6 +76,7 @@ class FederationDashboardPlugin { * @param {FederationDashboardPluginOptions} options */ constructor(options) { + console.log("constructing federation dashboard", options) this._options = Object.assign( { debug: false, filename: "dashboard.json", fetchClient: false }, options @@ -94,6 +95,13 @@ class FederationDashboardPlugin { const FederationPlugin = compiler.options.plugins.find((plugin) => { return plugin.constructor.name === "ModuleFederationPlugin" || plugin.constructor.name === "NextFederationPlugin"; }); + + if(compiler.name) { + console.log('what plugin got') + compiler.options.plugins.map((plugin) => { + console.log(plugin.constructor.name) + }) + } if (FederationPlugin) { this.FederationPluginOptions = Object.assign( {}, @@ -122,7 +130,7 @@ class FederationDashboardPlugin { ); }); - if (this.FederationPluginOptions.name) { + if (this.FederationPluginOptions.name && compiler.name !== "ChildFederationPlugin") { new DefinePlugin({ 'process.dashboardURL': JSON.stringify(this._options.dashboardURL), "process.CURRENT_HOST": JSON.stringify( @@ -205,8 +213,10 @@ class FederationDashboardPlugin { if (curCompiler.emitAsset && this._options.filename) { const asset = curCompiler.getAsset(this._options.filename); if (asset) { + console.log("updateAsset", this._options.filename); curCompiler.updateAsset(this._options.filename, source); } else { + console.log("emitAsset", this._options.filename); curCompiler.emitAsset(this._options.filename, source); } } @@ -489,6 +499,60 @@ class FederationDashboardPlugin { } } +class NextMedusaPlugin { + constructor(options) { + console.log('medusa plugin constructor', options); + this._options = options; + } + + apply(compiler) { + if(!(compiler.options.name === 'client' || compiler.options.name === 'server' || compiler.name === "ChildFederationPlugin")) { + console.log('not applying medusa plugin', compiler.options.name, compiler.name); + return + } else { + console.log('applying medusa plugin', compiler.options.name, compiler.name); + } + const filename = (compiler.name === "ChildFederationPlugin") ? "dashboard-child.json" : "dashboard.json"; + + new FederationDashboardPlugin({ + ...this._options, + filename:compiler.options.name +'-'+filename, + nextjs: true, + }).apply(compiler); + + + return + compiler.hooks.done.tap(PLUGIN_NAME, () => { + const sidecarData = path.join( + compiler.options.output.path, + `child-dashboard.json` + ); + const hostData = path.join( + compiler.options.output.path, + 'dashboard.json' + ); + console.log('sidecar data',sidecarData); + console.log('host data', hostData); + if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { + console.log('will write merged files'); + fs.writeFileSync( + hostData, + JSON.stringify(mergeGraphs(require(sidecarData), require(hostData))) + ); + } + }); + + compiler.hooks.afterDone.tap("NextMedusaPlugin", (stats, done) => { + if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { + const dashboardData = fs.readFileSync(hostData, "utf8"); + MedusaPlugin.postDashboardData(dashboardData).then(done).catch(done); + } else { + done(); + } + }); + } +} module.exports = FederationDashboardPlugin; module.exports.clientVersion = require("./client-version"); +module.exports.NextMedusaPlugin = NextMedusaPlugin; diff --git a/dashboard-plugin/index.d.ts b/dashboard-plugin/index.d.ts new file mode 100644 index 00000000..18abdc7d --- /dev/null +++ b/dashboard-plugin/index.d.ts @@ -0,0 +1,22 @@ +declare module "upload" { + import { RequestInit, Response } from "node-fetch"; + + type PostDashboardDataOptions = { + data: object; + headers: object; + }; + + type PostDashboardDataClient = (url: string, options: RequestInit) => Promise; + + type PostDashboardDataFunction = (options: PostDashboardDataOptions) => Promise; + + export default function postDashboardData( + this: { + _options: { + fetchClient?: PostDashboardDataClient; + dashboardURL: string; + }; + }, + options: PostDashboardDataOptions, + ): Promise; +} diff --git a/dashboard-plugin/medusa-delegate.js b/dashboard-plugin/medusa-delegate.js index 7db3823f..e646bb8e 100644 --- a/dashboard-plugin/medusa-delegate.js +++ b/dashboard-plugin/medusa-delegate.js @@ -1,36 +1,26 @@ -module.exports = ({fetchClient, currentHost, remoteName, dashboardURL})=> new Promise((resolve, reject) => { - fetchClient(`${dashboardURL}¤tHost=${currentHost}&remoteName=${remoteName}`, { - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - }) - .then((res) => res.json()) - .then((data) => { - const name = `${data.name}_${data.version}`; - const filename = `${data.version}.remoteEntry.js`; - const url = new URL(filename, data.remoteURL); +const {importDelegatedModule} = require('@module-federation/utilities'); + +module.exports = ({fetchClient, environment, currentHost, remote,token})=>new Promise((resolve, reject) => { - new Promise((resolve, reject) => { - const __webpack_error__ = new Error(); - if (typeof window[name] !== 'undefined') return resolve( window[name] ); - __webpack_require__.l( - url.href, - (event) => { - if (typeof window[name] !== 'undefined') return resolve( window[name] ); - const errorType = event && (event.type === 'load' ? 'missing' : event.type); - const realSrc = event?.target?.src; - __webpack_error__.message = - `Loading script failed.\\n(${errorType}: ${realSrc})`; - __webpack_error__.name = 'ScriptExternalLoadError'; - __webpack_error__.type = errorType; - __webpack_error__.request = realSrc; - reject(__webpack_error__); - }, - name, - ); - }).then(() => { - resolve(window[name]) - }).catch(reject) - }) + let f = fetchClient || fetch; + let env = environment || process.env.NODE_ENV + return f(`https://api.medusa.codes/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()).then((remote) => { + console.log('medusaResponse', remote); + }); + //Splitting the currentRequest using "@" as the separator and assigning the values to "global" and "url" + const [global, url] = currentRequest.split('@'); + //importing the delegated module + importDelegatedModule({ + global, + url, }) + .then(async (remote) => { + //resolving the remote + resolve(remote) + }) + .catch((err) => { + //catching the error and rejecting it + reject(err); + }); +}); + diff --git a/dashboard-plugin/mergeGraphs.js b/dashboard-plugin/mergeGraphs.js index 51277200..4a4e8c0f 100644 --- a/dashboard-plugin/mergeGraphs.js +++ b/dashboard-plugin/mergeGraphs.js @@ -14,15 +14,44 @@ const mergeWithoutDupe = (source) => } return acc; }, []); + +function mergeArrays(arr1, arr2) { + const merged = {}; + + // Merge arr1 into merged + arr1.forEach(obj => { + const key = obj.name + obj.version; + if (!merged[key]) { + merged[key] = obj; + } + }); + + // Merge arr2 into merged + arr2.forEach(obj => { + const key = obj.name + obj.version; + if (!merged[key]) { + merged[key] = obj; + } + }); + + // Convert merged object to array + const result = []; + Object.keys(merged).forEach(key => { + result.push(merged[key]); + }); + + return result; +} + module.exports = (graph1, graph2) => { - graph1.devDependencies = mergeWithoutDupe([ - ...graph2.devDependencies, - ...graph1.devDependencies, - ]); - graph1.dependencies = mergeWithoutDupe([ - ...graph2.dependencies, - ...graph1.dependencies, - ]); + graph1.devDependencies = mergeArrays( + graph2.devDependencies, + graph1.devDependencies, + ); + graph1.dependencies = mergeArrays( + graph2.dependencies, + graph1.dependencies, + ); //exposed graph2.modules.forEach((hostModules) => { const existing = graph1.modules.find((sidecarModules) => { diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index fa885eb9..062b55dd 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -26,11 +26,14 @@ "medusa-delegate.js", "convertToGraph.js", "mergeGraphs.js", + "index.d.ts", + "postDashboardData.js", "client-version.js", "LICENSE" ], "dependencies": { "@module-federation/automatic-vendor-federation": "^1.2.1", + "@module-federation/utilities": "^1.3.0", "node-fetch": "^2.6.0" }, "peerDependencies": { diff --git a/dashboard-plugin/postDashboardData.js b/dashboard-plugin/postDashboardData.js new file mode 100644 index 00000000..281ef610 --- /dev/null +++ b/dashboard-plugin/postDashboardData.js @@ -0,0 +1,24 @@ +const fetch = require("node-fetch"); +async function postDashboardData({data, headers}) { + const client = this._options.fetchClient ? this._options.fetchClient : fetch; + try { + const res = await client(this._options.dashboardURL, { + method: "POST", + body: data, + headers: { + Accept: "application/json", + "Content-type": "application/json", + ...headers, + }, + }); + + if (!res.ok) throw new Error(res.statusText); + } catch (err) { + console.warn( + `Error posting data to dashboard URL: ${this._options.dashboardURL}` + ); + console.error(err); + } +} + +module.exports = postDashboardData; diff --git a/yarn.lock b/yarn.lock index 17e06323..0d35d919 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1405,6 +1405,11 @@ dependencies: find-package-json "^1.2.0" +"@module-federation/utilities@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@module-federation/utilities/-/utilities-1.3.0.tgz#018071b630cb000f79397ad458bfd7d4dd9104fe" + integrity sha512-GGSuC0t5BsoXa58dSiP8MxXItMixWT5FbzWMndhtqLQMmJVdLpVFROiIH4eKXpfjOkKViRri7CfQ8MaNUn8JqQ== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" From 2122dd3146aca931ebb4838ef33ef37156ff66d2 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 6 Mar 2023 12:01:28 -0800 Subject: [PATCH 08/32] Next Support --- dashboard-plugin/FederationDashboardPlugin.js | 14 +++++++------- dashboard-plugin/medusa-delegate.js | 15 +++++++++++++-- dashboard-plugin/package.json | 2 +- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 07b89d7f..867fd66f 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -96,12 +96,12 @@ class FederationDashboardPlugin { return plugin.constructor.name === "ModuleFederationPlugin" || plugin.constructor.name === "NextFederationPlugin"; }); - if(compiler.name) { - console.log('what plugin got') - compiler.options.plugins.map((plugin) => { - console.log(plugin.constructor.name) - }) - } + // if(compiler.name) { + // console.log('what plugin got') + // compiler.options.plugins.map((plugin) => { + // console.log(plugin.constructor.name) + // }) + // } if (FederationPlugin) { this.FederationPluginOptions = Object.assign( {}, @@ -133,7 +133,7 @@ class FederationDashboardPlugin { if (this.FederationPluginOptions.name && compiler.name !== "ChildFederationPlugin") { new DefinePlugin({ 'process.dashboardURL': JSON.stringify(this._options.dashboardURL), - "process.CURRENT_HOST": JSON.stringify( + "process.env.CURRENT_HOST": JSON.stringify( this.FederationPluginOptions.name ), }).apply(compiler); diff --git a/dashboard-plugin/medusa-delegate.js b/dashboard-plugin/medusa-delegate.js index e646bb8e..2badb7b3 100644 --- a/dashboard-plugin/medusa-delegate.js +++ b/dashboard-plugin/medusa-delegate.js @@ -1,9 +1,20 @@ const {importDelegatedModule} = require('@module-federation/utilities'); module.exports = ({fetchClient, environment, currentHost, remote,token})=>new Promise((resolve, reject) => { - let f = fetchClient || fetch; - let env = environment || process.env.NODE_ENV + let env = environment || process.env.NODE_ENV; + console.log('####medusa internals'); + console.log({ + 'process.env.CURRENT_HOST': process.env.CURRENT_HOST, + 'currentHost': currentHost, + 'process.env.NODE_ENV': process.env.NODE_ENV, + 'environment': environment, + 'remote': remote, + 'token': token, + requestURL: `https://api.medusa.codes/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`, + fetchClient: fetchClient, + }); + console.log('#########') return f(`https://api.medusa.codes/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()).then((remote) => { console.log('medusaResponse', remote); }); diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index 062b55dd..e156c378 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.7.2", + "version": "2.8.0", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0", From 72753c62fb661a26eb0d8357032f92efee73a3f9 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 10 Mar 2023 15:59:41 -0800 Subject: [PATCH 09/32] updating delegate module for next support --- dashboard-plugin/medusa-delegate.js | 35 ++--------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/dashboard-plugin/medusa-delegate.js b/dashboard-plugin/medusa-delegate.js index 2badb7b3..d9ce8030 100644 --- a/dashboard-plugin/medusa-delegate.js +++ b/dashboard-plugin/medusa-delegate.js @@ -1,37 +1,6 @@ -const {importDelegatedModule} = require('@module-federation/utilities'); - -module.exports = ({fetchClient, environment, currentHost, remote,token})=>new Promise((resolve, reject) => { +module.exports = ({fetchClient, environment, currentHost, remote,token, apiHost = "https://api.medusa.codes"})=>new Promise((resolve, reject) => { let f = fetchClient || fetch; let env = environment || process.env.NODE_ENV; - console.log('####medusa internals'); - console.log({ - 'process.env.CURRENT_HOST': process.env.CURRENT_HOST, - 'currentHost': currentHost, - 'process.env.NODE_ENV': process.env.NODE_ENV, - 'environment': environment, - 'remote': remote, - 'token': token, - requestURL: `https://api.medusa.codes/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`, - fetchClient: fetchClient, - }); - console.log('#########') - return f(`https://api.medusa.codes/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()).then((remote) => { - console.log('medusaResponse', remote); - }); - //Splitting the currentRequest using "@" as the separator and assigning the values to "global" and "url" - const [global, url] = currentRequest.split('@'); - //importing the delegated module - importDelegatedModule({ - global, - url, - }) - .then(async (remote) => { - //resolving the remote - resolve(remote) - }) - .catch((err) => { - //catching the error and rejecting it - reject(err); - }); + f(`${apiHost}/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()).then(resolve).catch(reject); }); From 4ae1064428f3e1d803178674f6eeb3a256b5eaa3 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 13 Mar 2023 17:56:26 -0700 Subject: [PATCH 10/32] feat: adding medusa-client.js for headless use medusa client only implements the fetch functionality for talking to medusa - useful in custom delegate modules --- dashboard-plugin/medusa-client.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 dashboard-plugin/medusa-client.js diff --git a/dashboard-plugin/medusa-client.js b/dashboard-plugin/medusa-client.js new file mode 100644 index 00000000..d9ce8030 --- /dev/null +++ b/dashboard-plugin/medusa-client.js @@ -0,0 +1,6 @@ +module.exports = ({fetchClient, environment, currentHost, remote,token, apiHost = "https://api.medusa.codes"})=>new Promise((resolve, reject) => { + let f = fetchClient || fetch; + let env = environment || process.env.NODE_ENV; + f(`${apiHost}/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()).then(resolve).catch(reject); +}); + From 92eff8d10533a3869bd0c32775d4c8ccd294af4b Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 13 Mar 2023 18:00:39 -0700 Subject: [PATCH 11/32] feat: implement updated api into medusa delegate --- dashboard-plugin/medusa-delegate.js | 30 +++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/dashboard-plugin/medusa-delegate.js b/dashboard-plugin/medusa-delegate.js index d9ce8030..c111c213 100644 --- a/dashboard-plugin/medusa-delegate.js +++ b/dashboard-plugin/medusa-delegate.js @@ -1,6 +1,32 @@ module.exports = ({fetchClient, environment, currentHost, remote,token, apiHost = "https://api.medusa.codes"})=>new Promise((resolve, reject) => { let f = fetchClient || fetch; let env = environment || process.env.NODE_ENV; - f(`${apiHost}/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()).then(resolve).catch(reject); -}); + f(`${apiHost}/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()) + .then((data) => { + const name = `${data.name}_${data.version}`; + const filename = `${data.version}.remoteEntry.js`; + const url = new URL(filename, data.remoteURL); + new Promise((resolve, reject) => { + const __webpack_error__ = new Error(); + if (typeof window[name] !== 'undefined') return resolve( window[name] ); + __webpack_require__.l( + url.href, + (event) => { + if (typeof window[name] !== 'undefined') return resolve( window[name] ); + const errorType = event && (event.type === 'load' ? 'missing' : event.type); + const realSrc = event?.target?.src; + __webpack_error__.message = + `Loading script failed.\\n(${errorType}: ${realSrc})`; + __webpack_error__.name = 'ScriptExternalLoadError'; + __webpack_error__.type = errorType; + __webpack_error__.request = realSrc; + reject(__webpack_error__); + }, + name, + ); + }).then(() => { + resolve(window[name]) + }).catch(reject) + }) + }) From a8bf2dee4b10f593f7216389a88fd7980ae33e17 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 13 Mar 2023 18:16:12 -0700 Subject: [PATCH 12/32] chore: update files to publish --- dashboard-plugin/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index e156c378..d7430862 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -24,6 +24,7 @@ "helpers", "FederationDashboardPlugin.js", "medusa-delegate.js", + "medusa-client.js", "convertToGraph.js", "mergeGraphs.js", "index.d.ts", From cf71994accf408252b715738d51bdcd6335430b8 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 13 Mar 2023 18:20:21 -0700 Subject: [PATCH 13/32] fix: hide logs behind debug flag --- dashboard-plugin/FederationDashboardPlugin.js | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 867fd66f..63c09007 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -76,13 +76,15 @@ class FederationDashboardPlugin { * @param {FederationDashboardPluginOptions} options */ constructor(options) { - console.log("constructing federation dashboard", options) this._options = Object.assign( { debug: false, filename: "dashboard.json", fetchClient: false }, options ); this._dashData = null; this.allArgumentsUsed = []; + if(this._options.debug){ + console.log("constructing federation dashboard", options) + } } /** @@ -96,12 +98,6 @@ class FederationDashboardPlugin { return plugin.constructor.name === "ModuleFederationPlugin" || plugin.constructor.name === "NextFederationPlugin"; }); - // if(compiler.name) { - // console.log('what plugin got') - // compiler.options.plugins.map((plugin) => { - // console.log(plugin.constructor.name) - // }) - // } if (FederationPlugin) { this.FederationPluginOptions = Object.assign( {}, @@ -213,10 +209,14 @@ class FederationDashboardPlugin { if (curCompiler.emitAsset && this._options.filename) { const asset = curCompiler.getAsset(this._options.filename); if (asset) { - console.log("updateAsset", this._options.filename); + if(this._options.debug) { + console.log("updateAsset", this._options.filename); + } curCompiler.updateAsset(this._options.filename, source); } else { - console.log("emitAsset", this._options.filename); + if(this._options.debug) { + console.log("emitAsset", this._options.filename); + } curCompiler.emitAsset(this._options.filename, source); } } @@ -501,8 +501,10 @@ class FederationDashboardPlugin { class NextMedusaPlugin { constructor(options) { - console.log('medusa plugin constructor', options); this._options = options; + if(this._options.debug) { + console.log('medusa plugin constructor', options); + } } apply(compiler) { From b5f41bdc713279e67eda828204a732ca55b3285f Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 13 Mar 2023 18:28:53 -0700 Subject: [PATCH 14/32] fix: bring back early return removed by debugger check --- dashboard-plugin/FederationDashboardPlugin.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 63c09007..fb5ed080 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -508,10 +508,12 @@ class NextMedusaPlugin { } apply(compiler) { - if(!(compiler.options.name === 'client' || compiler.options.name === 'server' || compiler.name === "ChildFederationPlugin")) { - console.log('not applying medusa plugin', compiler.options.name, compiler.name); + if (!(compiler.options.name === 'client' || compiler.options.name === 'server' || compiler.name === "ChildFederationPlugin")) { + if(this._options.debug) { + console.log('not applying medusa plugin', compiler.options.name, compiler.name); + } return - } else { + } else if(this._options.debug) { console.log('applying medusa plugin', compiler.options.name, compiler.name); } const filename = (compiler.name === "ChildFederationPlugin") ? "dashboard-child.json" : "dashboard.json"; From 195bbf9f496aaecb1641c01b486b2dbca6f08e0f Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 13 Mar 2023 18:43:45 -0700 Subject: [PATCH 15/32] chore: update TS defs --- dashboard-plugin/index.d.ts | 22 ---------------------- dashboard-plugin/postDashboardData.d.ts | 10 ++++++++++ 2 files changed, 10 insertions(+), 22 deletions(-) delete mode 100644 dashboard-plugin/index.d.ts create mode 100644 dashboard-plugin/postDashboardData.d.ts diff --git a/dashboard-plugin/index.d.ts b/dashboard-plugin/index.d.ts deleted file mode 100644 index 18abdc7d..00000000 --- a/dashboard-plugin/index.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -declare module "upload" { - import { RequestInit, Response } from "node-fetch"; - - type PostDashboardDataOptions = { - data: object; - headers: object; - }; - - type PostDashboardDataClient = (url: string, options: RequestInit) => Promise; - - type PostDashboardDataFunction = (options: PostDashboardDataOptions) => Promise; - - export default function postDashboardData( - this: { - _options: { - fetchClient?: PostDashboardDataClient; - dashboardURL: string; - }; - }, - options: PostDashboardDataOptions, - ): Promise; -} diff --git a/dashboard-plugin/postDashboardData.d.ts b/dashboard-plugin/postDashboardData.d.ts new file mode 100644 index 00000000..a48f462c --- /dev/null +++ b/dashboard-plugin/postDashboardData.d.ts @@ -0,0 +1,10 @@ +declare module "postDashboardData" { + import { HeadersInit } from "node-fetch"; + + interface PostDashboardDataOptions { + data: string; + headers?: HeadersInit; + } + + export default function postDashboardData(options: PostDashboardDataOptions): Promise; +} From d2fa66d0ed72f92e4dd0d5c75d8d0a33ad53e963 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 13 Mar 2023 18:52:58 -0700 Subject: [PATCH 16/32] publish all d.ts files --- dashboard-plugin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index d7430862..ad7ff0df 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -27,7 +27,7 @@ "medusa-client.js", "convertToGraph.js", "mergeGraphs.js", - "index.d.ts", + "*.d.ts", "postDashboardData.js", "client-version.js", "LICENSE" From e861454c23645a87fde2dddcd72ce51137c9ff4f Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 13 Mar 2023 19:47:49 -0700 Subject: [PATCH 17/32] v2.8.0-beta.1 --- dashboard-plugin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index ad7ff0df..460e4e34 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.8.0", + "version": "2.8.0-beta.1", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0", From ed2e6db3db1f2e51d987c968579f21238cec6954 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 14 Mar 2023 11:01:55 -0700 Subject: [PATCH 18/32] add d.ts files to client delegates, format the codebase --- dashboard-plugin/FederationDashboardPlugin.js | 174 ++++++++++-------- dashboard-plugin/README.md | 37 ++-- dashboard-plugin/convertToGraph.js | 82 +++++---- dashboard-plugin/medusa-client.d.ts | 28 +++ dashboard-plugin/medusa-client.js | 25 ++- dashboard-plugin/medusa-delegate.d.ts | 28 +++ dashboard-plugin/medusa-delegate.js | 58 ++++-- dashboard-plugin/mergeGraphs.js | 25 ++- dashboard-plugin/postDashboardData.d.ts | 14 +- dashboard-plugin/postDashboardData.js | 6 +- 10 files changed, 301 insertions(+), 176 deletions(-) create mode 100644 dashboard-plugin/medusa-client.d.ts create mode 100644 dashboard-plugin/medusa-delegate.d.ts diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index fb5ed080..47c3a625 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -18,7 +18,7 @@ try { console.error(e); } -const findPackageJson = (filePath) => { +const findPackageJson = filePath => { if (filePath.length === 0) { return false; } @@ -45,7 +45,7 @@ class AddRuntimeRequiremetToPromiseExternal { apply(compiler) { compiler.hooks.compilation.tap( "AddRuntimeRequiremetToPromiseExternal", - (compilation) => { + compilation => { const { RuntimeGlobals } = compiler.webpack; if (compilation.outputOptions.trustedTypes) { compilation.hooks.additionalModuleRuntimeRequirements.tap( @@ -82,8 +82,8 @@ class FederationDashboardPlugin { ); this._dashData = null; this.allArgumentsUsed = []; - if(this._options.debug){ - console.log("constructing federation dashboard", options) + if (this._options.debug) { + console.log("constructing federation dashboard", options); } } @@ -94,8 +94,11 @@ class FederationDashboardPlugin { compiler.options.output.uniqueName = `v${Date.now()}`; new AddRuntimeRequiremetToPromiseExternal().apply(compiler); - const FederationPlugin = compiler.options.plugins.find((plugin) => { - return plugin.constructor.name === "ModuleFederationPlugin" || plugin.constructor.name === "NextFederationPlugin"; + const FederationPlugin = compiler.options.plugins.find(plugin => { + return ( + plugin.constructor.name === "ModuleFederationPlugin" || + plugin.constructor.name === "NextFederationPlugin" + ); }); if (FederationPlugin) { @@ -112,31 +115,35 @@ class FederationDashboardPlugin { ); } - this.FederationPluginOptions.name = - this.FederationPluginOptions.name.replace("__REMOTE_VERSION__", ""); - compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => { + this.FederationPluginOptions.name = this.FederationPluginOptions.name.replace( + "__REMOTE_VERSION__", + "" + ); + compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => { compilation.hooks.processAssets.tapPromise( { name: PLUGIN_NAME, - stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT, + stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT }, - (assets) => { + assets => { return this.processWebpackGraph(compilation, assets); } ); }); - if (this.FederationPluginOptions.name && compiler.name !== "ChildFederationPlugin") { + if ( + this.FederationPluginOptions.name && + compiler.name !== "ChildFederationPlugin" + ) { new DefinePlugin({ - 'process.dashboardURL': JSON.stringify(this._options.dashboardURL), + "process.dashboardURL": JSON.stringify(this._options.dashboardURL), "process.env.CURRENT_HOST": JSON.stringify( this.FederationPluginOptions.name - ), + ) }).apply(compiler); } } - processWebpackGraph(curCompiler, assets) { const liveStats = curCompiler.getStats(); const stats = liveStats.toJson(); @@ -151,7 +158,6 @@ class FederationDashboardPlugin { this.FederationPluginOptions ); - const chunkDependencies = this.getChunkDependencies(validChunkArray); const vendorFederation = this.buildVendorFederationMap(liveStats); const rawData = { @@ -169,7 +175,7 @@ class FederationDashboardPlugin { sha: gitSha, modules: stats.modules, chunkDependencies, - functionRemotes: this.allArgumentsUsed, + functionRemotes: this.allArgumentsUsed }; let graphData = null; @@ -180,12 +186,11 @@ class FederationDashboardPlugin { console.warn(err); } - if (graphData) { const dashData = (this._dashData = JSON.stringify(graphData)); if (this._options.dashboardURL && !this._options.nextjs) { - this.postDashboardData(dashData).catch((err) => { + this.postDashboardData(dashData).catch(err => { if (err) { curCompiler.errors.push(err); // eslint-disable-next-line promise/no-callback-in-promise @@ -203,18 +208,18 @@ class FederationDashboardPlugin { }, size() { return statsBuf.length; - }, + } }; // for dashboard.json if (curCompiler.emitAsset && this._options.filename) { const asset = curCompiler.getAsset(this._options.filename); if (asset) { - if(this._options.debug) { + if (this._options.debug) { console.log("updateAsset", this._options.filename); } curCompiler.updateAsset(this._options.filename, source); } else { - if(this._options.debug) { + if (this._options.debug) { console.log("emitAsset", this._options.filename); } curCompiler.emitAsset(this._options.filename, source); @@ -230,10 +235,13 @@ class FederationDashboardPlugin { const remoteEntry = curCompiler.getAsset( this.FederationPluginOptions.filename ); - if(!remoteEntry) { + if (!remoteEntry) { return Promise.resolve(); } - const cleanVersion = typeof rawData.version === "string" ? `_${rawData.version.split(".").join("_")}` : `_${rawData.version.toString()}`; + const cleanVersion = + typeof rawData.version === "string" + ? `_${rawData.version.split(".").join("_")}` + : `_${rawData.version.toString()}`; let codeSource; if (!remoteEntry.source._value && remoteEntry.source.source) { codeSource = remoteEntry.source.source(); @@ -266,17 +274,19 @@ class FederationDashboardPlugin { ); if (remoteEntry && graphData.version) { - const basename = path.basename(this.FederationPluginOptions.filename) - const bustedName = this.FederationPluginOptions.filename.replace(basename, [graphData.version, basename].join(".")); + const basename = path.basename( + this.FederationPluginOptions.filename + ); + const bustedName = this.FederationPluginOptions.filename.replace( + basename, + [graphData.version, basename].join(".") + ); curCompiler.updateAsset( this.FederationPluginOptions.filename, originalRemoteEntrySource ); - curCompiler.emitAsset( - bustedName, - remoteEntrySource - ); + curCompiler.emitAsset(bustedName, remoteEntrySource); } } }); @@ -284,15 +294,15 @@ class FederationDashboardPlugin { } getRemoteEntryChunk(stats, FederationPluginOptions) { - - return stats.chunks.find((chunk) => chunk.names.find((name) => name === FederationPluginOptions.name)); + return stats.chunks.find(chunk => + chunk.names.find(name => name === FederationPluginOptions.name) + ); } getChunkDependencies(validChunkArray) { - return validChunkArray.reduce((acc, chunk) => { const subset = chunk.getAllReferencedChunks(); - const stringifiableChunk = Array.from(subset).map((sub) => { + const stringifiableChunk = Array.from(subset).map(sub => { const cleanSet = Object.getOwnPropertyNames(sub).reduce((acc, key) => { if (key === "_groups") return acc; return Object.assign(acc, { [key]: sub[key] }); @@ -302,7 +312,7 @@ class FederationDashboardPlugin { }); return Object.assign(acc, { - [chunk.id]: stringifiableChunk, + [chunk.id]: stringifiableChunk }); }, {}); } @@ -324,7 +334,7 @@ class FederationDashboardPlugin { packageJson, // subPackages: this.directReasons(modules), shareFrom: ["dependencies"], - ignorePatchversion: false, + ignorePatchversion: false }); vendorFederation.devDependencies = AutomaticVendorFederation({ exclude: [], @@ -332,7 +342,7 @@ class FederationDashboardPlugin { packageJson, // subPackages: this.directReasons(modules), shareFrom: ["devDependencies"], - ignorePatchversion: false, + ignorePatchversion: false }); vendorFederation.optionalDependencies = AutomaticVendorFederation({ exclude: [], @@ -340,7 +350,7 @@ class FederationDashboardPlugin { packageJson, // subPackages: this.directReasons(modules), shareFrom: ["optionalDependencies"], - ignorePatchversion: false, + ignorePatchversion: false }); } @@ -370,7 +380,7 @@ class FederationDashboardPlugin { ? namedChunkRefs.getAllReferencedChunks() : []; - AllReferencedChunksByRemote.forEach((chunk) => { + AllReferencedChunksByRemote.forEach(chunk => { if (chunk.id !== FederationPluginOptions.name) { validChunkArray.push(chunk); } @@ -382,9 +392,9 @@ class FederationDashboardPlugin { directReasons(modules) { const directReasons = new Set(); - modules.forEach((module) => { + modules.forEach(module => { if (module.reasons) { - module.reasons.forEach((reason) => { + module.reasons.forEach(reason => { if (reason.userRequest) { try { // grab user required package.json @@ -406,19 +416,19 @@ class FederationDashboardPlugin { if (this._options.filename) { const hashPath = path.join(stats.outputPath, this._options.filename); if (!fs.existsSync(stats.outputPath)) { - fs.mkdirSync(stats.outputPath, { recursive: true }) + fs.mkdirSync(stats.outputPath, { recursive: true }); } fs.writeFileSync(hashPath, dashData, { encoding: "utf-8" }); } if (this._options.debug) { - console.log( - path.join(stats.outputPath, this.FederationPluginOptions.filename) - ); + console.log( + path.join(stats.outputPath, this.FederationPluginOptions.filename) + ); } - let file + let file; try { - file = assets[this.FederationPluginOptions.filename]._value + file = assets[this.FederationPluginOptions.filename]._value; const { version } = JSON.parse(dashData); if (!version) { @@ -436,7 +446,7 @@ class FederationDashboardPlugin { fs.mkdir( path.join(stats.outputPath, version), { recursive: true }, - (err) => { + err => { if (err) throw err; fs.writeFile( path.join( @@ -445,7 +455,7 @@ class FederationDashboardPlugin { this.FederationPluginOptions.filename ), file, - (err) => { + err => { if (this._options.debug) { console.trace(err); console.log( @@ -461,8 +471,8 @@ class FederationDashboardPlugin { ); } ); - } catch(e) { - console.log(e) + } catch (e) { + console.log(e); } const statsPath = path.join(stats.outputPath, "stats.json"); @@ -478,15 +488,17 @@ class FederationDashboardPlugin { if (!this._options.dashboardURL) { return Promise.resolve(); } - const client = this._options.fetchClient ? this._options.fetchClient : fetch; + const client = this._options.fetchClient + ? this._options.fetchClient + : fetch; try { const res = await client(this._options.dashboardURL, { method: "POST", body: dashData, headers: { Accept: "application/json", - "Content-type": "application/json", - }, + "Content-type": "application/json" + } }); if (!res.ok) throw new Error(res.statusText); @@ -502,30 +514,46 @@ class FederationDashboardPlugin { class NextMedusaPlugin { constructor(options) { this._options = options; - if(this._options.debug) { - console.log('medusa plugin constructor', options); + if (this._options.debug) { + console.log("medusa plugin constructor", options); } } apply(compiler) { - if (!(compiler.options.name === 'client' || compiler.options.name === 'server' || compiler.name === "ChildFederationPlugin")) { - if(this._options.debug) { - console.log('not applying medusa plugin', compiler.options.name, compiler.name); + if ( + !( + compiler.options.name === "client" || + compiler.options.name === "server" || + compiler.name === "ChildFederationPlugin" + ) + ) { + if (this._options.debug) { + console.log( + "not applying medusa plugin", + compiler.options.name, + compiler.name + ); } - return - } else if(this._options.debug) { - console.log('applying medusa plugin', compiler.options.name, compiler.name); + return; + } else if (this._options.debug) { + console.log( + "applying medusa plugin", + compiler.options.name, + compiler.name + ); } - const filename = (compiler.name === "ChildFederationPlugin") ? "dashboard-child.json" : "dashboard.json"; + const filename = + compiler.name === "ChildFederationPlugin" + ? "dashboard-child.json" + : "dashboard.json"; new FederationDashboardPlugin({ ...this._options, - filename:compiler.options.name +'-'+filename, - nextjs: true, + filename: compiler.options.name + "-" + filename, + nextjs: true }).apply(compiler); - - return + return; compiler.hooks.done.tap(PLUGIN_NAME, () => { const sidecarData = path.join( compiler.options.output.path, @@ -533,12 +561,12 @@ class NextMedusaPlugin { ); const hostData = path.join( compiler.options.output.path, - 'dashboard.json' + "dashboard.json" ); - console.log('sidecar data',sidecarData); - console.log('host data', hostData); + console.log("sidecar data", sidecarData); + console.log("host data", hostData); if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { - console.log('will write merged files'); + console.log("will write merged files"); fs.writeFileSync( hostData, JSON.stringify(mergeGraphs(require(sidecarData), require(hostData))) @@ -549,7 +577,9 @@ class NextMedusaPlugin { compiler.hooks.afterDone.tap("NextMedusaPlugin", (stats, done) => { if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { const dashboardData = fs.readFileSync(hostData, "utf8"); - MedusaPlugin.postDashboardData(dashboardData).then(done).catch(done); + MedusaPlugin.postDashboardData(dashboardData) + .then(done) + .catch(done); } else { done(); } diff --git a/dashboard-plugin/README.md b/dashboard-plugin/README.md index 6a4d357b..8c73241a 100644 --- a/dashboard-plugin/README.md +++ b/dashboard-plugin/README.md @@ -17,8 +17,8 @@ const DashboardPlugin = require("@module-federation/dashboard-plugin"); ```js plugins: [ ...new DashboardPlugin({ - dashboardURL: "https://api.medusa.codes/update?token=writeToken", - }), + dashboardURL: "https://api.medusa.codes/update?token=writeToken" + }) ]; ``` @@ -47,11 +47,11 @@ plugins: [ dashboardURL: "https://api.medusa.codes/update?token=writeToken", metadata: { source: { - url: "http://github.com/myorg/myproject/tree/master", + url: "http://github.com/myorg/myproject/tree/master" }, - remote: "http://localhost:8081/remoteEntry.js", - }, - }), + remote: "http://localhost:8081/remoteEntry.js" + } + }) ]; ``` @@ -100,28 +100,28 @@ module.exports = withPlugins( lodash: { import: "lodash", requiredVersion: require("lodash").version, - singleton: true, + singleton: true }, chakra: { shareKey: "@chakra-ui/react", - import: "@chakra-ui/react", + import: "@chakra-ui/react" }, "use-sse": { singleton: true, - requiredVersion: false, - }, - }, + requiredVersion: false + } + } }, { experiments: { flushChunks: true, - hot: true, - }, + hot: true + } } ), withMedusa({ name: "home", - + publishVersion: require("./package.json").version, filename: "dashboard.json", dashboardURL: `https://api.medusa.codes/update?token=${process.env.DASHBOARD_WRITE_TOKEN}`, @@ -131,13 +131,14 @@ module.exports = withPlugins( ? "https://" + process.env.VERCEL_URL : "http://localhost:3001", source: { - url: "https://github.com/module-federation/federation-dashboard/tree/master/dashboard-example/home", + url: + "https://github.com/module-federation/federation-dashboard/tree/master/dashboard-example/home" }, remote: process.env.VERCEL_URL ? "https://" + process.env.VERCEL_URL + "/remoteEntry.js" - : "http://localhost:3001/remoteEntry.js", - }, - }), + : "http://localhost:3001/remoteEntry.js" + } + }) ], nextConfig ); diff --git a/dashboard-plugin/convertToGraph.js b/dashboard-plugin/convertToGraph.js index 0dad1a4f..dd9d2c63 100644 --- a/dashboard-plugin/convertToGraph.js +++ b/dashboard-plugin/convertToGraph.js @@ -10,7 +10,7 @@ const fs = require("fs"); */ function getLicenses(packageJson) { if (packageJson.licenses && packageJson.licenses instanceof Array) { - return packageJson.licenses.map((license) => license.type).join(", "); + return packageJson.licenses.map(license => license.type).join(", "); } else if (packageJson.licenses) { // TODO: Refactor this to reduce duplicate code. Note "licenses" vs "license". return ( @@ -38,7 +38,7 @@ const convertToGraph = ( group, functionRemotes, sha, - buildHash, + buildHash }, standalone ) => { @@ -53,29 +53,30 @@ const convertToGraph = ( const modulesObj = {}; const npmModules = new Map(); - modules.forEach((mod) => { + modules.forEach(mod => { const { identifier, reasons, moduleType, nameForCondition, size } = mod; const data = identifier.split(" "); if (moduleType === "remote-module") { if (data.length === 4) { const name = data[3].replace("./", ""); - let applicationID = data[2].replace("webpack/container/reference/", "") - if(applicationID.includes("?")){ - const params = new URLSearchParams(applicationID.split('?')[1]); - const remoteReference = params.get("remoteName") || params.get("remote"); - if(remoteReference && remoteReference.includes("@")) { - const [global] = remoteReference.split('@') - applicationID = global + let applicationID = data[2].replace("webpack/container/reference/", ""); + if (applicationID.includes("?")) { + const params = new URLSearchParams(applicationID.split("?")[1]); + const remoteReference = + params.get("remoteName") || params.get("remote"); + if (remoteReference && remoteReference.includes("@")) { + const [global] = remoteReference.split("@"); + applicationID = global; } else { - applicationID = remoteReference + applicationID = remoteReference; } } const consume = { consumingApplicationID: name, applicationID, name, - usedIn: new Set(), + usedIn: new Set() }; consumes.push(consume); @@ -98,7 +99,7 @@ const convertToGraph = ( name, applicationID: name, requires: new Set(), - file: file.import[0], + file: file.import[0] }; }); } else if (nameForCondition && nameForCondition.includes("node_modules")) { @@ -122,7 +123,7 @@ const convertToGraph = ( version: packageJson.version, homepage: packageJson.homepage, license: getLicenses(packageJson), - size: ((existingReference && existingReference.size) || 0) + size, + size: ((existingReference && existingReference.size) || 0) + size }; if (existingReference) { Object.assign(existingReference, data); @@ -137,8 +138,8 @@ const convertToGraph = ( version: packageJson.version, homepage: packageJson.homepage, license: getLicenses(packageJson), - size, - }, + size + } }; npmModules.set(packageJson.name, newDep); } @@ -151,7 +152,9 @@ const convertToGraph = ( const versionVal = version.replace(`${name}-`, ""); if (dataFromGraph) { - const foundInGraph = Object.values(dataFromGraph).find((depData) => depData.version.startsWith(versionVal)); + const foundInGraph = Object.values(dataFromGraph).find(depData => + depData.version.startsWith(versionVal) + ); if (foundInGraph) { const { name, version, license, size } = foundInGraph; @@ -159,22 +162,22 @@ const convertToGraph = ( name, version, license, - size, + size }; } } return { name, - version: versionVal, + version: versionVal }; }); const convertedDeps = { dependencies: convertDeps(topLevelPackage.dependencies), devDependencies: convertDeps(topLevelPackage.devDependencies), - optionalDependencies: convertDeps(topLevelPackage.optionalDependencies), + optionalDependencies: convertDeps(topLevelPackage.optionalDependencies) }; - modules.forEach((mod) => { + modules.forEach(mod => { const { identifier, issuerName, reasons, moduleType } = mod; if (moduleType === "provide-module") { @@ -210,8 +213,8 @@ const convertToGraph = ( [ convertedDeps.dependencies, convertedDeps.devDependencies, - convertedDeps.optionalDependencies, - ].forEach((deps) => { + convertedDeps.optionalDependencies + ].forEach(deps => { const dep = deps.find(({ name }) => name === data[2]); if (dep) { version = dep.version; @@ -224,7 +227,7 @@ const convertToGraph = ( name, version, location: name, - applicationID: name, + applicationID: name }; } @@ -258,8 +261,8 @@ const convertToGraph = ( [ convertedDeps.dependencies, convertedDeps.devDependencies, - convertedDeps.optionalDependencies, - ].forEach((deps) => { + convertedDeps.optionalDependencies + ].forEach(deps => { const dep = deps.find(({ name }) => name === data[2]); if (dep) { version = dep.version; @@ -271,7 +274,7 @@ const convertToGraph = ( name: data[2], version, location: data[2], - applicationID: name, + applicationID: name }; }); @@ -282,10 +285,11 @@ const convertToGraph = ( const cleanName = name.replace("./", ""); const objectId = `${applicationID}/${cleanName}`; const cleanFile = file.replace("./", ""); - const foundExistingConsume = consumes.find((consumeObj) => ( - consumeObj.applicationID === applicationID && - consumeObj.name === cleanName - )); + const foundExistingConsume = consumes.find( + consumeObj => + consumeObj.applicationID === applicationID && + consumeObj.name === cleanName + ); if (foundExistingConsume) { foundExistingConsume.usedIn.add(cleanFile); return acc; @@ -298,7 +302,7 @@ const convertToGraph = ( applicationID, name: cleanName, consumingApplicationID: name, - usedIn: new Set([cleanFile]), + usedIn: new Set([cleanFile]) }; return acc; }, {}) @@ -317,23 +321,23 @@ const convertToGraph = ( metadata, versionData, overrides: Object.values(overrides), - consumes: consumes.map((con) => ({ + consumes: consumes.map(con => ({ ...con, - usedIn: Array.from(con.usedIn.values()).map((file) => ({ + usedIn: Array.from(con.usedIn.values()).map(file => ({ file, - url: `${sourceUrl}/${file}`, - })), + url: `${sourceUrl}/${file}` + })) })), - modules: Object.values(modulesObj).map((mod) => ({ + modules: Object.values(modulesObj).map(mod => ({ ...mod, - requires: Array.from(mod.requires.values()), + requires: Array.from(mod.requires.values()) })), environment, version, posted, group, sha, - buildHash, + buildHash }; }; diff --git a/dashboard-plugin/medusa-client.d.ts b/dashboard-plugin/medusa-client.d.ts new file mode 100644 index 00000000..f2526b9f --- /dev/null +++ b/dashboard-plugin/medusa-client.d.ts @@ -0,0 +1,28 @@ +declare module "medusa-client" { + type FetchClient = typeof fetch; + type Environment = string | undefined; + + interface RemoteResponse { + // Define the shape of the response object here + } + + type RemoteRequestOptions = { + fetchClient?: FetchClient; + environment?: Environment; + currentHost?: string; + remote: string; + token: string; + apiHost?: string; + }; + + function getRemote({ + fetchClient, + environment, + currentHost, + remote, + token, + apiHost + }: RemoteRequestOptions): Promise; + + export default getRemote; +} diff --git a/dashboard-plugin/medusa-client.js b/dashboard-plugin/medusa-client.js index d9ce8030..8762057b 100644 --- a/dashboard-plugin/medusa-client.js +++ b/dashboard-plugin/medusa-client.js @@ -1,6 +1,19 @@ -module.exports = ({fetchClient, environment, currentHost, remote,token, apiHost = "https://api.medusa.codes"})=>new Promise((resolve, reject) => { - let f = fetchClient || fetch; - let env = environment || process.env.NODE_ENV; - f(`${apiHost}/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()).then(resolve).catch(reject); -}); - +module.exports = ({ + fetchClient, + environment, + currentHost, + remote, + token, + apiHost = "https://api.medusa.codes" +}) => + new Promise((resolve, reject) => { + let f = fetchClient || fetch; + let env = environment || process.env.NODE_ENV; + f( + `${apiHost}/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || + process.env.CURRENT_HOST}` + ) + .then(res => res.json()) + .then(resolve) + .catch(reject); + }); diff --git a/dashboard-plugin/medusa-delegate.d.ts b/dashboard-plugin/medusa-delegate.d.ts new file mode 100644 index 00000000..f90695ca --- /dev/null +++ b/dashboard-plugin/medusa-delegate.d.ts @@ -0,0 +1,28 @@ +declare module "medusa-delegate" { + type FetchClient = typeof fetch; + type Environment = string | undefined; + + interface RemoteResponse { + // Define the shape of the response object here + } + + interface DelegateOptions { + fetchClient?: FetchClient; + environment?: Environment; + currentHost?: string; + remote: string; + token: string; + apiHost?: string; + } + + function medusaDelegate({ + fetchClient, + environment, + currentHost, + remote, + token, + apiHost + }: DelegateOptions): Promise; + + export default medusaDelegate; +} diff --git a/dashboard-plugin/medusa-delegate.js b/dashboard-plugin/medusa-delegate.js index c111c213..e2ebdc81 100644 --- a/dashboard-plugin/medusa-delegate.js +++ b/dashboard-plugin/medusa-delegate.js @@ -1,32 +1,54 @@ -module.exports = ({fetchClient, environment, currentHost, remote,token, apiHost = "https://api.medusa.codes"})=>new Promise((resolve, reject) => { - let f = fetchClient || fetch; - let env = environment || process.env.NODE_ENV; - f(`${apiHost}/env/${env}/get-remote?token=${token}&remoteName=${remote}¤tHost=${currentHost || process.env.CURRENT_HOST}`).then(res=>res.json()) - .then((data) => { +module.exports = ({ + fetchClient, + environment, + currentHost, + remote, + token, + apiHost = "https://api.medusa.codes", + remoteName, + dashboardURL +}) => + new Promise((resolve, reject) => { + if (dashboardURL) { + console.error( + "medusa-delegate: dashboardURL is deprecated. Please use apiHost instead. Defaults to: https://api.medusa.codes" + ); + } + let f = fetchClient || fetch; + let env = environment || process.env.NODE_ENV; + f( + `${apiHost}/env/${env}/get-remote?token=${token}&remoteName=${remote || + remoteName}¤tHost=${currentHost || process.env.CURRENT_HOST}` + ) + .then(res => res.json()) + .then(data => { const name = `${data.name}_${data.version}`; const filename = `${data.version}.remoteEntry.js`; const url = new URL(filename, data.remoteURL); new Promise((resolve, reject) => { const __webpack_error__ = new Error(); - if (typeof window[name] !== 'undefined') return resolve( window[name] ); + if (typeof window[name] !== "undefined") return resolve(window[name]); __webpack_require__.l( url.href, - (event) => { - if (typeof window[name] !== 'undefined') return resolve( window[name] ); - const errorType = event && (event.type === 'load' ? 'missing' : event.type); + event => { + if (typeof window[name] !== "undefined") + return resolve(window[name]); + const errorType = + event && (event.type === "load" ? "missing" : event.type); const realSrc = event?.target?.src; - __webpack_error__.message = - `Loading script failed.\\n(${errorType}: ${realSrc})`; - __webpack_error__.name = 'ScriptExternalLoadError'; + __webpack_error__.message = `Loading script failed.\\n(${errorType}: ${realSrc})`; + __webpack_error__.name = "ScriptExternalLoadError"; __webpack_error__.type = errorType; __webpack_error__.request = realSrc; reject(__webpack_error__); }, - name, + name ); - }).then(() => { - resolve(window[name]) - }).catch(reject) - }) - }) + }) + .then(() => { + resolve(window[name]); + }) + .catch(reject); + }); + }); diff --git a/dashboard-plugin/mergeGraphs.js b/dashboard-plugin/mergeGraphs.js index 4a4e8c0f..ed43fab2 100644 --- a/dashboard-plugin/mergeGraphs.js +++ b/dashboard-plugin/mergeGraphs.js @@ -1,7 +1,7 @@ -const mergeWithoutDupe = (source) => +const mergeWithoutDupe = source => source.reduce((acc, item) => { if (typeof item === "object") { - const isDupe = acc.find((existing) => { + const isDupe = acc.find(existing => { return Object.entries(existing).every(([key, value]) => { return item[key] === value; }); @@ -46,15 +46,12 @@ function mergeArrays(arr1, arr2) { module.exports = (graph1, graph2) => { graph1.devDependencies = mergeArrays( graph2.devDependencies, - graph1.devDependencies, - ); - graph1.dependencies = mergeArrays( - graph2.dependencies, - graph1.dependencies, + graph1.devDependencies ); + graph1.dependencies = mergeArrays(graph2.dependencies, graph1.dependencies); //exposed - graph2.modules.forEach((hostModules) => { - const existing = graph1.modules.find((sidecarModules) => { + graph2.modules.forEach(hostModules => { + const existing = graph1.modules.find(sidecarModules => { return ( hostModules.id === sidecarModules.id && hostModules.name === sidecarModules.name && @@ -71,8 +68,8 @@ module.exports = (graph1, graph2) => { } }); //shares - graph2.overrides.forEach((hostOverrides) => { - const existing = graph1.overrides.find((sidecarOverrides) => { + graph2.overrides.forEach(hostOverrides => { + const existing = graph1.overrides.find(sidecarOverrides => { return ( sidecarOverrides.id === hostOverrides.id && sidecarOverrides.name === hostOverrides.name && @@ -86,8 +83,8 @@ module.exports = (graph1, graph2) => { } }); //consumes - graph2.consumes.forEach((hostConsumedModule) => { - const existing = graph1.consumes.find((sidecarConsumedModule) => { + graph2.consumes.forEach(hostConsumedModule => { + const existing = graph1.consumes.find(sidecarConsumedModule => { return ( sidecarConsumedModule.consumingApplicationID === hostConsumedModule.consumingApplicationID && @@ -98,7 +95,7 @@ module.exports = (graph1, graph2) => { }); if (existing) { - hostConsumedModule.usedIn.forEach((consumedModule) => { + hostConsumedModule.usedIn.forEach(consumedModule => { const alreadyExists = existing.usedIn.find(({ file, url }) => { return consumedModule.file === file && consumedModule.url === url; }); diff --git a/dashboard-plugin/postDashboardData.d.ts b/dashboard-plugin/postDashboardData.d.ts index a48f462c..9300eb21 100644 --- a/dashboard-plugin/postDashboardData.d.ts +++ b/dashboard-plugin/postDashboardData.d.ts @@ -1,10 +1,12 @@ declare module "postDashboardData" { - import { HeadersInit } from "node-fetch"; + import { HeadersInit } from "node-fetch"; - interface PostDashboardDataOptions { - data: string; - headers?: HeadersInit; - } + interface PostDashboardDataOptions { + data: string; + headers?: HeadersInit; + } - export default function postDashboardData(options: PostDashboardDataOptions): Promise; + export default function postDashboardData( + options: PostDashboardDataOptions + ): Promise; } diff --git a/dashboard-plugin/postDashboardData.js b/dashboard-plugin/postDashboardData.js index 281ef610..a1d5da36 100644 --- a/dashboard-plugin/postDashboardData.js +++ b/dashboard-plugin/postDashboardData.js @@ -1,5 +1,5 @@ const fetch = require("node-fetch"); -async function postDashboardData({data, headers}) { +async function postDashboardData({ data, headers }) { const client = this._options.fetchClient ? this._options.fetchClient : fetch; try { const res = await client(this._options.dashboardURL, { @@ -8,8 +8,8 @@ async function postDashboardData({data, headers}) { headers: { Accept: "application/json", "Content-type": "application/json", - ...headers, - }, + ...headers + } }); if (!res.ok) throw new Error(res.statusText); From 2d8f2c4a72a0f5f13ff0bd15123ba89272b19f34 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 14 Mar 2023 11:04:17 -0700 Subject: [PATCH 19/32] update readme --- dashboard-plugin/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dashboard-plugin/README.md b/dashboard-plugin/README.md index 8c73241a..a2c21495 100644 --- a/dashboard-plugin/README.md +++ b/dashboard-plugin/README.md @@ -46,6 +46,8 @@ plugins: [ ...new DashboardPlugin({ dashboardURL: "https://api.medusa.codes/update?token=writeToken", metadata: { + // baseurl is needed in order for medusa to know where to find the remoteEntry.js file + baseUrl: 'http://localhost:3001/_next/static/chunks/', source: { url: "http://github.com/myorg/myproject/tree/master" }, From 1b9112c8ddbdff6540ac9d6ae8315d1bd6d1baec Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 14 Mar 2023 11:04:37 -0700 Subject: [PATCH 20/32] update readme --- dashboard-plugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/README.md b/dashboard-plugin/README.md index a2c21495..c93e3b7a 100644 --- a/dashboard-plugin/README.md +++ b/dashboard-plugin/README.md @@ -47,7 +47,7 @@ plugins: [ dashboardURL: "https://api.medusa.codes/update?token=writeToken", metadata: { // baseurl is needed in order for medusa to know where to find the remoteEntry.js file - baseUrl: 'http://localhost:3001/_next/static/chunks/', + baseUrl: 'http://localhost:3001/assets/', source: { url: "http://github.com/myorg/myproject/tree/master" }, From 365a46cf4101c26f1aedc9d19a60d45b9abc5941 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 14 Mar 2023 11:06:38 -0700 Subject: [PATCH 21/32] v2.8.0-beta.2 --- dashboard-plugin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index 460e4e34..69a475c2 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.8.0-beta.1", + "version": "2.8.0-beta.2", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0", From d79d99a6259984b996af319a8786c6b3bc215ca5 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 16 Mar 2023 15:35:56 -0700 Subject: [PATCH 22/32] v2.8.0-beta.3 --- dashboard-plugin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index 69a475c2..9a767be2 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.8.0-beta.2", + "version": "2.8.0-beta.3", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0", From bb0d7cdc9cf37a3202854eb63849b2eae9917af5 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 16 Mar 2023 15:36:09 -0700 Subject: [PATCH 23/32] fix: prevent merge graphs from crashing --- dashboard-plugin/mergeGraphs.js | 124 +++++++++++++++++--------------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/dashboard-plugin/mergeGraphs.js b/dashboard-plugin/mergeGraphs.js index ed43fab2..fc23909a 100644 --- a/dashboard-plugin/mergeGraphs.js +++ b/dashboard-plugin/mergeGraphs.js @@ -44,69 +44,79 @@ function mergeArrays(arr1, arr2) { } module.exports = (graph1, graph2) => { - graph1.devDependencies = mergeArrays( - graph2.devDependencies, - graph1.devDependencies - ); - graph1.dependencies = mergeArrays(graph2.dependencies, graph1.dependencies); - //exposed - graph2.modules.forEach(hostModules => { - const existing = graph1.modules.find(sidecarModules => { - return ( - hostModules.id === sidecarModules.id && - hostModules.name === sidecarModules.name && - hostModules.file === sidecarModules.file && - hostModules.applicationID === sidecarModules.applicationID - ); + if(graph2 && graph2.devDependencies) { + graph1.devDependencies = mergeArrays( + graph2.devDependencies, + graph1.devDependencies + ); + } + if(graph2 && graph2.dependencies) { + graph1.dependencies = mergeArrays(graph2.dependencies, graph1.dependencies); + } + if(graph2 && graph2.modules) { + //exposed + graph2.modules.forEach(hostModules => { + const existing = graph1.modules.find(sidecarModules => { + return ( + hostModules.id === sidecarModules.id && + hostModules.name === sidecarModules.name && + hostModules.file === sidecarModules.file && + hostModules.applicationID === sidecarModules.applicationID + ); + }); + if (existing) { + existing.requires = Array.from( + new Set([...existing.requires, ...hostModules.requires]) + ); + } else { + graph1.modules.push(hostModules); + } }); - if (existing) { - existing.requires = Array.from( - new Set([...existing.requires, ...hostModules.requires]) - ); - } else { - graph1.modules.push(hostModules); - } - }); - //shares - graph2.overrides.forEach(hostOverrides => { - const existing = graph1.overrides.find(sidecarOverrides => { - return ( - sidecarOverrides.id === hostOverrides.id && - sidecarOverrides.name === hostOverrides.name && - sidecarOverrides.version === hostOverrides.version && - sidecarOverrides.location === hostOverrides.location && - sidecarOverrides.applicationID === hostOverrides.applicationID - ); + } + if(graph2 && graph2.overrides) { + //shares + graph2.overrides.forEach(hostOverrides => { + const existing = graph1.overrides.find(sidecarOverrides => { + return ( + sidecarOverrides.id === hostOverrides.id && + sidecarOverrides.name === hostOverrides.name && + sidecarOverrides.version === hostOverrides.version && + sidecarOverrides.location === hostOverrides.location && + sidecarOverrides.applicationID === hostOverrides.applicationID + ); + }); + if (!existing) { + graph1.overrides.push(hostOverrides); + } }); - if (!existing) { - graph1.overrides.push(hostOverrides); - } - }); - //consumes - graph2.consumes.forEach(hostConsumedModule => { - const existing = graph1.consumes.find(sidecarConsumedModule => { - return ( - sidecarConsumedModule.consumingApplicationID === + } + if(graph2 && graph2.consumes) { + //consumes + graph2.consumes.forEach(hostConsumedModule => { + const existing = graph1.consumes.find(sidecarConsumedModule => { + return ( + sidecarConsumedModule.consumingApplicationID === hostConsumedModule.consumingApplicationID && - sidecarConsumedModule.applicationID === + sidecarConsumedModule.applicationID === hostConsumedModule.applicationID && - sidecarConsumedModule.name === hostConsumedModule.name - ); - }); + sidecarConsumedModule.name === hostConsumedModule.name + ); + }); - if (existing) { - hostConsumedModule.usedIn.forEach(consumedModule => { - const alreadyExists = existing.usedIn.find(({ file, url }) => { - return consumedModule.file === file && consumedModule.url === url; + if (existing) { + hostConsumedModule.usedIn.forEach(consumedModule => { + const alreadyExists = existing.usedIn.find(({file, url}) => { + return consumedModule.file === file && consumedModule.url === url; + }); + if (!alreadyExists) { + existing.usedIn.push(consumedModule); + } }); - if (!alreadyExists) { - existing.usedIn.push(consumedModule); - } - }); - } else { - graph1.consumes.push(hostConsumedModule); - } - }); + } else { + graph1.consumes.push(hostConsumedModule); + } + }); + } return graph1; }; From 2f63ad5760bc7262b657d4cb3fa2773cc8adad0a Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 17 Mar 2023 16:06:57 -0700 Subject: [PATCH 24/32] v2.8.0-beta.4 --- dashboard-plugin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index 9a767be2..25ea995b 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.8.0-beta.3", + "version": "2.8.0-beta.4", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0", From 5bf5a4a83ae8630605854144f3decbef4f552a33 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Fri, 17 Mar 2023 18:06:35 -0700 Subject: [PATCH 25/32] fix: prevent merge graphs from crashing --- dashboard-plugin/FederationDashboardPlugin.js | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 47c3a625..3af62c22 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -23,7 +23,11 @@ const findPackageJson = filePath => { return false; } if (fs.existsSync(path.join(filePath.join(path.sep), "package.json"))) { - return require(path.join(filePath.join(path.sep), "package.json")); + try { + return require(path.join(filePath.join(path.sep), "package.json")); + } catch (e) { + + } } filePath.pop(); findPackageJson(filePath); @@ -46,7 +50,7 @@ class AddRuntimeRequiremetToPromiseExternal { compiler.hooks.compilation.tap( "AddRuntimeRequiremetToPromiseExternal", compilation => { - const { RuntimeGlobals } = compiler.webpack; + const {RuntimeGlobals} = compiler.webpack; if (compilation.outputOptions.trustedTypes) { compilation.hooks.additionalModuleRuntimeRequirements.tap( "AddRuntimeRequiremetToPromiseExternal", @@ -63,6 +67,7 @@ class AddRuntimeRequiremetToPromiseExternal { } /** @typedef {import("webpack/lib/Compilation")} Compilation */ + /** @typedef {import("webpack/lib/Compiler")} Compiler */ /** @@ -77,7 +82,7 @@ class FederationDashboardPlugin { */ constructor(options) { this._options = Object.assign( - { debug: false, filename: "dashboard.json", fetchClient: false }, + {debug: false, filename: "dashboard.json", fetchClient: false}, options ); this._dashData = null; @@ -305,7 +310,7 @@ class FederationDashboardPlugin { const stringifiableChunk = Array.from(subset).map(sub => { const cleanSet = Object.getOwnPropertyNames(sub).reduce((acc, key) => { if (key === "_groups") return acc; - return Object.assign(acc, { [key]: sub[key] }); + return Object.assign(acc, {[key]: sub[key]}); }, {}); return this.mapToObjectRec(cleanSet); @@ -398,11 +403,11 @@ class FederationDashboardPlugin { if (reason.userRequest) { try { // grab user required package.json - const subsetPackage = require(reason.userRequest + - "/package.json"); + const subsetPackage = require(path.join(reason.userRequest, "package.json")); directReasons.add(subsetPackage); - } catch (e) {} + } catch (e) { + } } }); } @@ -416,9 +421,9 @@ class FederationDashboardPlugin { if (this._options.filename) { const hashPath = path.join(stats.outputPath, this._options.filename); if (!fs.existsSync(stats.outputPath)) { - fs.mkdirSync(stats.outputPath, { recursive: true }); + fs.mkdirSync(stats.outputPath, {recursive: true}); } - fs.writeFileSync(hashPath, dashData, { encoding: "utf-8" }); + fs.writeFileSync(hashPath, dashData, {encoding: "utf-8"}); } if (this._options.debug) { console.log( @@ -430,7 +435,7 @@ class FederationDashboardPlugin { try { file = assets[this.FederationPluginOptions.filename]._value; - const { version } = JSON.parse(dashData); + const {version} = JSON.parse(dashData); if (!version) { throw new Error("no version provided, cannot version remote"); } @@ -445,7 +450,7 @@ class FederationDashboardPlugin { } fs.mkdir( path.join(stats.outputPath, version), - { recursive: true }, + {recursive: true}, err => { if (err) throw err; fs.writeFile( @@ -479,8 +484,9 @@ class FederationDashboardPlugin { fs.writeFile( statsPath, JSON.stringify(stats), - { encoding: "utf-8" }, - () => {} + {encoding: "utf-8"}, + () => { + } ); } From 02c1fc773de161e358ff730b0ce3ae23cf652a84 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 20 Mar 2023 13:00:21 -0700 Subject: [PATCH 26/32] fix: prevent merge graphs from crashing --- dashboard-plugin/FederationDashboardPlugin.js | 1 + 1 file changed, 1 insertion(+) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 3af62c22..efea5062 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -29,6 +29,7 @@ const findPackageJson = filePath => { } } + filePath.pop(); findPackageJson(filePath); }; From 58024cea609890edb7595435b7675ba72a5ad09a Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 20 Mar 2023 15:25:54 -0700 Subject: [PATCH 27/32] v2.8.0-beta.5 --- dashboard-plugin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index 25ea995b..85a7bc61 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.8.0-beta.4", + "version": "2.8.0-beta.5", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0", From a99c0f094518a71cf5a93ee5fffbd924dc15d4f9 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Mon, 20 Mar 2023 15:26:15 -0700 Subject: [PATCH 28/32] fix: prevent bad package path from crashing windows builds --- dashboard-plugin/convertToGraph.js | 49 ++++++++++++++++-------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/dashboard-plugin/convertToGraph.js b/dashboard-plugin/convertToGraph.js index dd9d2c63..bb60fac4 100644 --- a/dashboard-plugin/convertToGraph.js +++ b/dashboard-plugin/convertToGraph.js @@ -113,35 +113,38 @@ const convertToGraph = ( const npmModule = contextArray[contextArray.indexOf("node_modules") + 1]; const packageJsonFile = path.join(context, "package.json"); - const packageJson = JSON.parse(fs.readFileSync(packageJsonFile, "UTF-8")); + // if the package.json file exists, we can use it to get the name and version + if(!fs.existsSync(packageJsonFile)) { + const packageJson = JSON.parse(fs.readFileSync(packageJsonFile, "UTF-8")); - const existingPackage = npmModules.get(packageJson.name); - if (existingPackage) { - const existingReference = existingPackage[packageJson.version]; - const data = { - name: packageJson.name, - version: packageJson.version, - homepage: packageJson.homepage, - license: getLicenses(packageJson), - size: ((existingReference && existingReference.size) || 0) + size - }; - if (existingReference) { - Object.assign(existingReference, data); - } else { - existingPackage[packageJson.version] = data; - } - npmModules.set(packageJson.name, existingPackage); - } else { - const newDep = { - [packageJson.version]: { + const existingPackage = npmModules.get(packageJson.name); + if (existingPackage) { + const existingReference = existingPackage[packageJson.version]; + const data = { name: packageJson.name, version: packageJson.version, homepage: packageJson.homepage, license: getLicenses(packageJson), - size + size: ((existingReference && existingReference.size) || 0) + size + }; + if (existingReference) { + Object.assign(existingReference, data); + } else { + existingPackage[packageJson.version] = data; } - }; - npmModules.set(packageJson.name, newDep); + npmModules.set(packageJson.name, existingPackage); + } else { + const newDep = { + [packageJson.version]: { + name: packageJson.name, + version: packageJson.version, + homepage: packageJson.homepage, + license: getLicenses(packageJson), + size + } + }; + npmModules.set(packageJson.name, newDep); + } } } }); From 919e4a52710892bb7582c6a79d8488bf35b29334 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Tue, 21 Nov 2023 20:55:51 -0300 Subject: [PATCH 29/32] fix/solve medusa next plugin post issues (#471) * fix: solve NextMedusaPlugin issues * chore: add remoteBasePath option * chore: add skipPost option --- dashboard-plugin/FederationDashboardPlugin.js | 102 ++++++++++-------- dashboard-plugin/client-version.js | 7 +- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index efea5062..4fb90970 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -51,7 +51,7 @@ class AddRuntimeRequiremetToPromiseExternal { compiler.hooks.compilation.tap( "AddRuntimeRequiremetToPromiseExternal", compilation => { - const {RuntimeGlobals} = compiler.webpack; + const { RuntimeGlobals } = compiler.webpack; if (compilation.outputOptions.trustedTypes) { compilation.hooks.additionalModuleRuntimeRequirements.tap( "AddRuntimeRequiremetToPromiseExternal", @@ -83,7 +83,7 @@ class FederationDashboardPlugin { */ constructor(options) { this._options = Object.assign( - {debug: false, filename: "dashboard.json", fetchClient: false}, + { debug: false, filename: "dashboard.json", fetchClient: false }, options ); this._dashData = null; @@ -125,6 +125,7 @@ class FederationDashboardPlugin { "__REMOTE_VERSION__", "" ); + compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => { compilation.hooks.processAssets.tapPromise( { @@ -195,14 +196,18 @@ class FederationDashboardPlugin { if (graphData) { const dashData = (this._dashData = JSON.stringify(graphData)); - if (this._options.dashboardURL && !this._options.nextjs) { - this.postDashboardData(dashData).catch(err => { - if (err) { - curCompiler.errors.push(err); - // eslint-disable-next-line promise/no-callback-in-promise - throw err; - } - }); + if (this._options.skipPost) { + console.info('Skipping post to dashboard') + } else { + if (this._options.dashboardURL && !this._options.nextjs) { + this.postDashboardData(dashData).catch(err => { + if (err) { + curCompiler.errors.push(err); + // eslint-disable-next-line promise/no-callback-in-promise + throw err; + } + }); + } } return Promise.resolve().then(() => { @@ -248,6 +253,7 @@ class FederationDashboardPlugin { typeof rawData.version === "string" ? `_${rawData.version.split(".").join("_")}` : `_${rawData.version.toString()}`; + let codeSource; if (!remoteEntry.source._value && remoteEntry.source.source) { codeSource = remoteEntry.source.source(); @@ -311,7 +317,7 @@ class FederationDashboardPlugin { const stringifiableChunk = Array.from(subset).map(sub => { const cleanSet = Object.getOwnPropertyNames(sub).reduce((acc, key) => { if (key === "_groups") return acc; - return Object.assign(acc, {[key]: sub[key]}); + return Object.assign(acc, { [key]: sub[key] }); }, {}); return this.mapToObjectRec(cleanSet); @@ -422,9 +428,9 @@ class FederationDashboardPlugin { if (this._options.filename) { const hashPath = path.join(stats.outputPath, this._options.filename); if (!fs.existsSync(stats.outputPath)) { - fs.mkdirSync(stats.outputPath, {recursive: true}); + fs.mkdirSync(stats.outputPath, { recursive: true }); } - fs.writeFileSync(hashPath, dashData, {encoding: "utf-8"}); + fs.writeFileSync(hashPath, dashData, { encoding: "utf-8" }); } if (this._options.debug) { console.log( @@ -436,7 +442,7 @@ class FederationDashboardPlugin { try { file = assets[this.FederationPluginOptions.filename]._value; - const {version} = JSON.parse(dashData); + const { version } = JSON.parse(dashData); if (!version) { throw new Error("no version provided, cannot version remote"); } @@ -451,7 +457,7 @@ class FederationDashboardPlugin { } fs.mkdir( path.join(stats.outputPath, version), - {recursive: true}, + { recursive: true }, err => { if (err) throw err; fs.writeFile( @@ -485,16 +491,26 @@ class FederationDashboardPlugin { fs.writeFile( statsPath, JSON.stringify(stats), - {encoding: "utf-8"}, + { encoding: "utf-8" }, () => { } ); } +} +class NextMedusaPlugin { + constructor(options) { + this._options = options; + if (this._options.debug) { + console.log("NextMedusaPlugin constructor", options); + } + } async postDashboardData(dashData) { + if (!this._options.dashboardURL) { return Promise.resolve(); } + const client = this._options.fetchClient ? this._options.fetchClient : fetch; @@ -509,6 +525,8 @@ class FederationDashboardPlugin { }); if (!res.ok) throw new Error(res.statusText); + + return res } catch (err) { console.warn( `Error posting data to dashboard URL: ${this._options.dashboardURL}` @@ -516,15 +534,6 @@ class FederationDashboardPlugin { console.error(err); } } -} - -class NextMedusaPlugin { - constructor(options) { - this._options = options; - if (this._options.debug) { - console.log("medusa plugin constructor", options); - } - } apply(compiler) { if ( @@ -560,40 +569,39 @@ class NextMedusaPlugin { nextjs: true }).apply(compiler); - return; + const hostData = path.join( + compiler.options.output.path, + compiler.options.name + "-" + filename + ); compiler.hooks.done.tap(PLUGIN_NAME, () => { - const sidecarData = path.join( - compiler.options.output.path, - `child-dashboard.json` - ); - const hostData = path.join( - compiler.options.output.path, - "dashboard.json" - ); - console.log("sidecar data", sidecarData); - console.log("host data", hostData); - if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { - console.log("will write merged files"); + if (fs.existsSync(hostData)) { fs.writeFileSync( hostData, - JSON.stringify(mergeGraphs(require(sidecarData), require(hostData))) + JSON.stringify(require(hostData)) ); } }); - compiler.hooks.afterDone.tap("NextMedusaPlugin", (stats, done) => { - if (fs.existsSync(sidecarData) && fs.existsSync(hostData)) { + compiler.hooks.afterDone.tap("NextMedusaPlugin", (stats) => { + if (fs.existsSync(hostData)) { const dashboardData = fs.readFileSync(hostData, "utf8"); - MedusaPlugin.postDashboardData(dashboardData) - .then(done) - .catch(done); - } else { - done(); + if (this._options.skipPost) { + console.info('Skipping post to dashboard') + } else { + this.postDashboardData(dashboardData) + .then(() => { + console.info('Data has been successfully sent to the dashboard') + }) + .catch((error) => { + console.error('Failed to send data to the dashboard:', error) + }); + } } }); + } } module.exports = FederationDashboardPlugin; module.exports.clientVersion = require("./client-version"); -module.exports.NextMedusaPlugin = NextMedusaPlugin; +module.exports.NextMedusaPlugin = NextMedusaPlugin; \ No newline at end of file diff --git a/dashboard-plugin/client-version.js b/dashboard-plugin/client-version.js index 95a6af1a..09f121ad 100644 --- a/dashboard-plugin/client-version.js +++ b/dashboard-plugin/client-version.js @@ -1,4 +1,4 @@ -module.exports = ({ currentHost, remoteName, dashboardURL }) => { +module.exports = ({ currentHost, remoteName, dashboardURL, remoteBasePath }) => { //language=JS return `promise new Promise((resolve, reject) => { fetch("${dashboardURL}¤tHost=${currentHost}&remoteName=${remoteName}", { @@ -13,8 +13,9 @@ module.exports = ({ currentHost, remoteName, dashboardURL }) => { .then(function (data) { var name = data.name + "_" + data.version; var filename = data.version + '.remoteEntry.js'; - var url = new URL(filename, data.remoteURL) - + var path = \`${remoteBasePath}/\${filename}\`.replace(/\\/\\/+/g, '/'); + var url = new URL(path, data.remoteURL); + new Promise(function (resolve, reject) { var __webpack_error__ = new Error() if (typeof window[name] !== 'undefined') return resolve(); From 70ee8e78504f051ddfbdaf1505a7c72261ff689e Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 21 Nov 2023 16:44:52 -0800 Subject: [PATCH 30/32] update plugin --- dashboard-plugin/package.json | 3 +-- yarn.lock | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index 85a7bc61..79db0404 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.8.0-beta.5", + "version": "2.8.0-beta.7", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0", @@ -34,7 +34,6 @@ ], "dependencies": { "@module-federation/automatic-vendor-federation": "^1.2.1", - "@module-federation/utilities": "^1.3.0", "node-fetch": "^2.6.0" }, "peerDependencies": { diff --git a/yarn.lock b/yarn.lock index 0d35d919..a143705c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1406,9 +1406,9 @@ find-package-json "^1.2.0" "@module-federation/utilities@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@module-federation/utilities/-/utilities-1.3.0.tgz#018071b630cb000f79397ad458bfd7d4dd9104fe" - integrity sha512-GGSuC0t5BsoXa58dSiP8MxXItMixWT5FbzWMndhtqLQMmJVdLpVFROiIH4eKXpfjOkKViRri7CfQ8MaNUn8JqQ== + version "1.9.1" + resolved "https://registry.npmjs.org/@module-federation/utilities/-/utilities-1.9.1.tgz" + integrity sha512-EVPV90TSK+tSG6R7Kw65w7pRuI2phff8YFIazzGWNViZPRlTYS3c9pZWVPYGiwIz1+96P+yeNp/WQZrkyS8kpA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1655,9 +1655,9 @@ "@babel/types" "^7.3.0" "@types/eslint-scope@^3.7.0": - version "3.7.3" - resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz" - integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== + version "3.7.7" + resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" @@ -1943,9 +1943,9 @@ acorn-globals@^6.0.0: acorn-walk "^7.1.1" acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + version "1.9.0" + resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== acorn-walk@^7.1.1: version "7.2.0" @@ -3170,9 +3170,9 @@ end-of-stream@^1.1.0: once "^1.4.0" enhanced-resolve@^5.8.3: - version "5.9.2" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz" - integrity sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA== + version "5.15.0" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3668,7 +3668,7 @@ fs.realpath@^1.0.0: fsevents@^2.1.2: version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: @@ -7845,9 +7845,9 @@ walker@^1.0.7, walker@~1.0.5: makeerror "1.0.12" watchpack@^2.2.0: - version "2.3.1" - resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz" - integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== + version "2.4.0" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" From 3343440cf6e49453deba1ab8995ff4c0f8e9dcaf Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Fri, 24 Nov 2023 10:52:55 -0300 Subject: [PATCH 31/32] fix: remove skipPost from the main plugin --- dashboard-plugin/FederationDashboardPlugin.js | 106 ++++++++---------- 1 file changed, 47 insertions(+), 59 deletions(-) diff --git a/dashboard-plugin/FederationDashboardPlugin.js b/dashboard-plugin/FederationDashboardPlugin.js index 4fb90970..a8d93f9f 100644 --- a/dashboard-plugin/FederationDashboardPlugin.js +++ b/dashboard-plugin/FederationDashboardPlugin.js @@ -18,16 +18,14 @@ try { console.error(e); } -const findPackageJson = filePath => { +const findPackageJson = (filePath) => { if (filePath.length === 0) { return false; } if (fs.existsSync(path.join(filePath.join(path.sep), "package.json"))) { try { return require(path.join(filePath.join(path.sep), "package.json")); - } catch (e) { - - } + } catch (e) {} } filePath.pop(); @@ -50,7 +48,7 @@ class AddRuntimeRequiremetToPromiseExternal { apply(compiler) { compiler.hooks.compilation.tap( "AddRuntimeRequiremetToPromiseExternal", - compilation => { + (compilation) => { const { RuntimeGlobals } = compiler.webpack; if (compilation.outputOptions.trustedTypes) { compilation.hooks.additionalModuleRuntimeRequirements.tap( @@ -100,7 +98,7 @@ class FederationDashboardPlugin { compiler.options.output.uniqueName = `v${Date.now()}`; new AddRuntimeRequiremetToPromiseExternal().apply(compiler); - const FederationPlugin = compiler.options.plugins.find(plugin => { + const FederationPlugin = compiler.options.plugins.find((plugin) => { return ( plugin.constructor.name === "ModuleFederationPlugin" || plugin.constructor.name === "NextFederationPlugin" @@ -121,18 +119,16 @@ class FederationDashboardPlugin { ); } - this.FederationPluginOptions.name = this.FederationPluginOptions.name.replace( - "__REMOTE_VERSION__", - "" - ); + this.FederationPluginOptions.name = + this.FederationPluginOptions.name.replace("__REMOTE_VERSION__", ""); - compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => { + compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => { compilation.hooks.processAssets.tapPromise( { name: PLUGIN_NAME, - stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT + stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT, }, - assets => { + (assets) => { return this.processWebpackGraph(compilation, assets); } ); @@ -146,7 +142,7 @@ class FederationDashboardPlugin { "process.dashboardURL": JSON.stringify(this._options.dashboardURL), "process.env.CURRENT_HOST": JSON.stringify( this.FederationPluginOptions.name - ) + ), }).apply(compiler); } } @@ -182,7 +178,7 @@ class FederationDashboardPlugin { sha: gitSha, modules: stats.modules, chunkDependencies, - functionRemotes: this.allArgumentsUsed + functionRemotes: this.allArgumentsUsed, }; let graphData = null; @@ -196,18 +192,14 @@ class FederationDashboardPlugin { if (graphData) { const dashData = (this._dashData = JSON.stringify(graphData)); - if (this._options.skipPost) { - console.info('Skipping post to dashboard') - } else { - if (this._options.dashboardURL && !this._options.nextjs) { - this.postDashboardData(dashData).catch(err => { - if (err) { - curCompiler.errors.push(err); - // eslint-disable-next-line promise/no-callback-in-promise - throw err; - } - }); - } + if (this._options.dashboardURL && !this._options.nextjs) { + this.postDashboardData(dashData).catch((err) => { + if (err) { + curCompiler.errors.push(err); + // eslint-disable-next-line promise/no-callback-in-promise + throw err; + } + }); } return Promise.resolve().then(() => { @@ -219,7 +211,7 @@ class FederationDashboardPlugin { }, size() { return statsBuf.length; - } + }, }; // for dashboard.json if (curCompiler.emitAsset && this._options.filename) { @@ -306,15 +298,15 @@ class FederationDashboardPlugin { } getRemoteEntryChunk(stats, FederationPluginOptions) { - return stats.chunks.find(chunk => - chunk.names.find(name => name === FederationPluginOptions.name) + return stats.chunks.find((chunk) => + chunk.names.find((name) => name === FederationPluginOptions.name) ); } getChunkDependencies(validChunkArray) { return validChunkArray.reduce((acc, chunk) => { const subset = chunk.getAllReferencedChunks(); - const stringifiableChunk = Array.from(subset).map(sub => { + const stringifiableChunk = Array.from(subset).map((sub) => { const cleanSet = Object.getOwnPropertyNames(sub).reduce((acc, key) => { if (key === "_groups") return acc; return Object.assign(acc, { [key]: sub[key] }); @@ -324,7 +316,7 @@ class FederationDashboardPlugin { }); return Object.assign(acc, { - [chunk.id]: stringifiableChunk + [chunk.id]: stringifiableChunk, }); }, {}); } @@ -346,7 +338,7 @@ class FederationDashboardPlugin { packageJson, // subPackages: this.directReasons(modules), shareFrom: ["dependencies"], - ignorePatchversion: false + ignorePatchversion: false, }); vendorFederation.devDependencies = AutomaticVendorFederation({ exclude: [], @@ -354,7 +346,7 @@ class FederationDashboardPlugin { packageJson, // subPackages: this.directReasons(modules), shareFrom: ["devDependencies"], - ignorePatchversion: false + ignorePatchversion: false, }); vendorFederation.optionalDependencies = AutomaticVendorFederation({ exclude: [], @@ -362,7 +354,7 @@ class FederationDashboardPlugin { packageJson, // subPackages: this.directReasons(modules), shareFrom: ["optionalDependencies"], - ignorePatchversion: false + ignorePatchversion: false, }); } @@ -392,7 +384,7 @@ class FederationDashboardPlugin { ? namedChunkRefs.getAllReferencedChunks() : []; - AllReferencedChunksByRemote.forEach(chunk => { + AllReferencedChunksByRemote.forEach((chunk) => { if (chunk.id !== FederationPluginOptions.name) { validChunkArray.push(chunk); } @@ -404,17 +396,19 @@ class FederationDashboardPlugin { directReasons(modules) { const directReasons = new Set(); - modules.forEach(module => { + modules.forEach((module) => { if (module.reasons) { - module.reasons.forEach(reason => { + module.reasons.forEach((reason) => { if (reason.userRequest) { try { // grab user required package.json - const subsetPackage = require(path.join(reason.userRequest, "package.json")); + const subsetPackage = require(path.join( + reason.userRequest, + "package.json" + )); directReasons.add(subsetPackage); - } catch (e) { - } + } catch (e) {} } }); } @@ -458,7 +452,7 @@ class FederationDashboardPlugin { fs.mkdir( path.join(stats.outputPath, version), { recursive: true }, - err => { + (err) => { if (err) throw err; fs.writeFile( path.join( @@ -467,7 +461,7 @@ class FederationDashboardPlugin { this.FederationPluginOptions.filename ), file, - err => { + (err) => { if (this._options.debug) { console.trace(err); console.log( @@ -492,8 +486,7 @@ class FederationDashboardPlugin { statsPath, JSON.stringify(stats), { encoding: "utf-8" }, - () => { - } + () => {} ); } } @@ -506,7 +499,6 @@ class NextMedusaPlugin { } } async postDashboardData(dashData) { - if (!this._options.dashboardURL) { return Promise.resolve(); } @@ -520,13 +512,13 @@ class NextMedusaPlugin { body: dashData, headers: { Accept: "application/json", - "Content-type": "application/json" - } + "Content-type": "application/json", + }, }); if (!res.ok) throw new Error(res.statusText); - return res + return res; } catch (err) { console.warn( `Error posting data to dashboard URL: ${this._options.dashboardURL}` @@ -566,7 +558,7 @@ class NextMedusaPlugin { new FederationDashboardPlugin({ ...this._options, filename: compiler.options.name + "-" + filename, - nextjs: true + nextjs: true, }).apply(compiler); const hostData = path.join( @@ -575,10 +567,7 @@ class NextMedusaPlugin { ); compiler.hooks.done.tap(PLUGIN_NAME, () => { if (fs.existsSync(hostData)) { - fs.writeFileSync( - hostData, - JSON.stringify(require(hostData)) - ); + fs.writeFileSync(hostData, JSON.stringify(require(hostData))); } }); @@ -586,22 +575,21 @@ class NextMedusaPlugin { if (fs.existsSync(hostData)) { const dashboardData = fs.readFileSync(hostData, "utf8"); if (this._options.skipPost) { - console.info('Skipping post to dashboard') + console.info("Skipping post to dashboard"); } else { this.postDashboardData(dashboardData) .then(() => { - console.info('Data has been successfully sent to the dashboard') + console.info("Data has been successfully sent to the dashboard"); }) .catch((error) => { - console.error('Failed to send data to the dashboard:', error) + console.error("Failed to send data to the dashboard:", error); }); } } }); - } } module.exports = FederationDashboardPlugin; module.exports.clientVersion = require("./client-version"); -module.exports.NextMedusaPlugin = NextMedusaPlugin; \ No newline at end of file +module.exports.NextMedusaPlugin = NextMedusaPlugin; From 6bda86ee04ae3f9da05cfcf0700e634aac691a8c Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 28 Nov 2023 01:42:53 -0800 Subject: [PATCH 32/32] publish --- dashboard-plugin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard-plugin/package.json b/dashboard-plugin/package.json index 79db0404..688e4e64 100644 --- a/dashboard-plugin/package.json +++ b/dashboard-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dashboard-plugin", - "version": "2.8.0-beta.7", + "version": "2.8.0-beta.8", "main": "FederationDashboardPlugin.js", "bin": "bin/federation-report.js", "license": "Apache-2.0",