UNPKG

@nx/react

Version:

The React plugin for Nx contains executors and generators for managing React applications and libraries within an Nx workspace. It provides: - Integration with libraries such as Jest, Vitest, Playwright, Cypress, and Storybook. - Generators for applica

100 lines (99 loc) 4.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addPathToExposes = addPathToExposes; exports.checkRemoteExists = checkRemoteExists; exports.getRemote = getRemote; exports.findExposes = findExposes; exports.createObjectEntry = createObjectEntry; exports.updateExposesPropertyinAST = updateExposesPropertyinAST; exports.writeToConfig = writeToConfig; exports.updateExposesProperty = updateExposesProperty; const devkit_1 = require("@nx/devkit"); const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript"); let tsModule; if (!tsModule) { tsModule = (0, ensure_typescript_1.ensureTypescript)(); } /** * Adds a Module Federation path to the exposes property of the module federation config * The assumption here is made the we will only update a TypeScript Module Federation file namely 'module-federation.config.js' * @param tree Tree for the workspace * @param projectPath Project path relative to the workspace * @param moduleName The name of the module to expose * @param modulePath The path to the module to expose (e.g. './src/my-lib/my-lib.ts') */ function addPathToExposes(tree, projectPath, moduleName, modulePath) { const moduleFederationConfigPath = (0, devkit_1.joinPathFragments)(projectPath, tree.exists((0, devkit_1.joinPathFragments)(projectPath, 'module-federation.config.ts')) ? 'module-federation.config.ts' : 'module-federation.config.js'); updateExposesProperty(tree, moduleFederationConfigPath, moduleName, modulePath); } /** * @param tree The workspace tree * @param remoteName The name of the remote to check * @returns Remote ProjectConfig if it exists, false otherwise */ function checkRemoteExists(tree, remoteName) { const remote = getRemote(tree, remoteName); if (!remote) return false; const hasModuleFederationConfig = tree.exists((0, devkit_1.joinPathFragments)(remote.root, 'module-federation.config.js')) || tree.exists((0, devkit_1.joinPathFragments)(remote.root, 'module-federation.config.ts')); return hasModuleFederationConfig ? remote : false; } function getRemote(tree, remoteName) { const projects = (0, devkit_1.getProjects)(tree); const remote = projects.get(remoteName); return remote; } // Check if the exposes property exists in the AST function findExposes(sourceFile) { let exposesObject = null; const visit = (node) => { if (tsModule.isPropertyAssignment(node) && tsModule.isIdentifier(node.name) && node.name.text === 'exposes' && tsModule.isObjectLiteralExpression(node.initializer)) { exposesObject = node.initializer; } else { tsModule.forEachChild(node, visit); } }; tsModule.forEachChild(sourceFile, visit); return exposesObject; } // Create a new property assignment function createObjectEntry(moduleName, modulePath) { return tsModule.factory.createPropertyAssignment(tsModule.factory.createStringLiteral(`./${moduleName}`, true), tsModule.factory.createStringLiteral(modulePath, true)); } // Update the exposes property in the AST function updateExposesPropertyinAST(source, exposesObject, newEntry) { const updatedExposes = tsModule.factory.updateObjectLiteralExpression(exposesObject, [...exposesObject.properties, newEntry]); const transform = (context) => { const visit = (node) => { // Comparing nodes indirectly to ensure type compatibility. You must ensure that the nodes are identical. return tsModule.isObjectLiteralExpression(node) && node === exposesObject ? updatedExposes : tsModule.visitEachChild(node, visit, context); }; return (node) => tsModule.visitNode(node, visit); }; return tsModule.transform(source, [transform]).transformed[0]; } // Write the updated AST to the file (module-federation.config.js) function writeToConfig(tree, filename, source, updatedSourceFile) { const printer = tsModule.createPrinter(); const update = printer.printNode(tsModule.EmitHint.Unspecified, updatedSourceFile, source); tree.write(filename, update); } function updateExposesProperty(tree, filename, moduleName, modulePath) { const fileContent = tree.read(filename).toString(); const source = tsModule.createSourceFile(filename, fileContent, tsModule.ScriptTarget.ES2015, true); const exposesObject = findExposes(source); if (!exposesObject) return; const newEntry = createObjectEntry(moduleName, modulePath); const updatedSourceFile = updateExposesPropertyinAST(source, exposesObject, newEntry); writeToConfig(tree, filename, source, updatedSourceFile); }