diff --git a/src/Umbraco.Web.UI.Client/devops/module-dependencies/index.js b/src/Umbraco.Web.UI.Client/devops/module-dependencies/index.js index dec355fce2..bb8d82077f 100644 --- a/src/Umbraco.Web.UI.Client/devops/module-dependencies/index.js +++ b/src/Umbraco.Web.UI.Client/devops/module-dependencies/index.js @@ -4,6 +4,7 @@ import { createImportMap } from '../importmap/index.js'; const ILLEGAL_CORE_IMPORTS_THRESHOLD = 6; const SELF_IMPORTS_THRESHOLD = 0; +const BIDIRECTIONAL_IMPORTS_THRESHOLD = 18; const clientProjectRoot = path.resolve(import.meta.dirname, '../../'); const modulePrefix = '@umbraco-cms/backoffice/'; @@ -186,9 +187,54 @@ function reportSelfImportsFromModules() { console.log(`\n\n`); } +function reportBidirectionalModuleImports() { + console.error(`🔍 Scanning all modules for bidirectional imports...`); + console.log(`\n`); + + let entries = []; + + packageModules.forEach(([alias, path]) => { + const importsInModule = getUmbracoModuleImportsInModule(alias); + + // Check imports for all the modules + importsInModule.forEach((importedModule) => { + // Check if the imported module imports the current module + const importedModuleImports = getUmbracoModuleImportsInModule(importedModule); + if (importedModuleImports.includes(alias)) { + const entry = [alias, importedModule].sort(); + entries = [...entries, entry]; + } + }); + }); + + // Remove duplicates + const uniqueEntries = [...new Set(entries.map(JSON.stringify))].map(JSON.parse); + const total = uniqueEntries.length; + + uniqueEntries.forEach((entry) => { + const [moduleA, moduleB] = entry; + console.error(`🚨 ${moduleA} and ${moduleB} are importing each other`); + }); + + if (total > BIDIRECTIONAL_IMPORTS_THRESHOLD) { + throw new Error( + `Bidirectional imports found in ${total} modules. ${total - BIDIRECTIONAL_IMPORTS_THRESHOLD} more than the threshold.`, + ); + } else if (total === 0) { + console.log(`✅ Success! No bidirectional imports found.`); + } else { + console.log( + `✅ Success! Still (${total}) under the threshold of ${BIDIRECTIONAL_IMPORTS_THRESHOLD} bidirectional imports.`, + ); + } + + console.log(`\n\n`); +} + function report() { reportIllegalImportsFromCore(); reportSelfImportsFromModules(); + reportBidirectionalModuleImports(); } report();