@nx/react
Version:
100 lines (99 loc) • 4.72 kB
JavaScript
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);
}
;