UNPKG

@nrwl/workspace

Version:

The Workspace plugin contains executors and generators that are useful for any Nx workspace. It should be present in every Nx workspace and other plugins build on it.

159 lines • 6.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateImports = void 0; const devkit_1 = require("@nrwl/devkit"); const ts_config_1 = require("../../../utilities/ts-config"); const typescript_1 = require("nx/src/utils/typescript"); const utils_1 = require("./utils"); const path_1 = require("path"); const typescript_2 = require("../../../utilities/typescript"); let tsModule; /** * Updates all the imports in the workspace and modifies the tsconfig appropriately. * * @param schema The options provided to the schematic */ function updateImports(tree, schema, project) { if (project.projectType === 'application') { // These shouldn't be imported anywhere? return; } const { npmScope, libsDir } = (0, devkit_1.getWorkspaceLayout)(tree); const projects = (0, devkit_1.getProjects)(tree); // use the source root to find the from location // this attempts to account for libs that have been created with --importPath const tsConfigPath = (0, ts_config_1.getRootTsConfigPathInTree)(tree); let tsConfig; let fromPath; if (tree.exists(tsConfigPath)) { tsConfig = (0, devkit_1.readJson)(tree, tsConfigPath); fromPath = Object.keys(tsConfig.compilerOptions.paths).find((path) => tsConfig.compilerOptions.paths[path].some((x) => x.startsWith(project.sourceRoot))); } const projectRef = { from: fromPath || (0, utils_1.normalizeSlashes)((0, devkit_1.getImportPath)(npmScope, project.root.slice(libsDir.length).replace(/^\/|\\/, ''))), to: schema.importPath, }; if (schema.updateImportPath) { const replaceProjectRef = new RegExp(projectRef.from, 'g'); for (const [name, definition] of Array.from(projects.entries())) { if (name === schema.projectName) { continue; } (0, devkit_1.visitNotIgnoredFiles)(tree, definition.root, (file) => { const contents = tree.read(file, 'utf-8'); replaceProjectRef.lastIndex = 0; if (!replaceProjectRef.test(contents)) { return; } updateImportPaths(tree, file, projectRef.from, projectRef.to); }); } } const projectRoot = { from: project.root, to: schema.relativeToRootDestination, }; if (tsConfig) { const path = tsConfig.compilerOptions.paths[projectRef.from]; if (!path) { throw new Error([ `unable to find "${projectRef.from}" in`, `${tsConfigPath} compilerOptions.paths`, ].join(' ')); } const updatedPath = path.map((x) => (0, devkit_1.joinPathFragments)(projectRoot.to, (0, path_1.relative)(projectRoot.from, x))); if (schema.updateImportPath) { tsConfig.compilerOptions.paths[projectRef.to] = updatedPath; delete tsConfig.compilerOptions.paths[projectRef.from]; } else { tsConfig.compilerOptions.paths[projectRef.from] = updatedPath; } (0, devkit_1.writeJson)(tree, tsConfigPath, tsConfig); } } exports.updateImports = updateImports; /** * Changes imports in a file from one import to another */ function updateImportPaths(tree, path, from, to) { if (!tsModule) { tsModule = (0, typescript_2.ensureTypescript)(); } const contents = tree.read(path, 'utf-8'); const sourceFile = tsModule.createSourceFile(path, contents, tsModule.ScriptTarget.Latest, true); // Apply changes on the various types of imports const newContents = (0, devkit_1.applyChangesToString)(contents, [ ...updateImportDeclarations(sourceFile, from, to), ...updateDynamicImports(sourceFile, from, to), ]); tree.write(path, newContents); } /** * Update the module specifiers on static imports */ function updateImportDeclarations(sourceFile, from, to) { if (!tsModule) { tsModule = (0, typescript_2.ensureTypescript)(); } const importDecls = (0, typescript_1.findNodes)(sourceFile, tsModule.SyntaxKind.ImportDeclaration); const changes = []; for (const { moduleSpecifier } of importDecls) { if (tsModule.isStringLiteral(moduleSpecifier)) { changes.push(...updateModuleSpecifier(moduleSpecifier, from, to)); } } return changes; } /** * Update the module specifiers on dynamic imports and require statements */ function updateDynamicImports(sourceFile, from, to) { if (!tsModule) { tsModule = (0, typescript_2.ensureTypescript)(); } const expressions = (0, typescript_1.findNodes)(sourceFile, tsModule.SyntaxKind.CallExpression); const changes = []; for (const { expression, arguments: args } of expressions) { const moduleSpecifier = args[0]; // handle dynamic import statements if (expression.kind === tsModule.SyntaxKind.ImportKeyword && moduleSpecifier && tsModule.isStringLiteral(moduleSpecifier)) { changes.push(...updateModuleSpecifier(moduleSpecifier, from, to)); } // handle require statements if (tsModule.isIdentifier(expression) && expression.text === 'require' && moduleSpecifier && tsModule.isStringLiteral(moduleSpecifier)) { changes.push(...updateModuleSpecifier(moduleSpecifier, from, to)); } } return changes; } /** * Replace the old module specifier with a the new path */ function updateModuleSpecifier(moduleSpecifier, from, to) { if (moduleSpecifier.text === from || moduleSpecifier.text.startsWith(`${from}/`)) { return [ { type: devkit_1.ChangeType.Delete, start: moduleSpecifier.getStart() + 1, length: moduleSpecifier.text.length, }, { type: devkit_1.ChangeType.Insert, index: moduleSpecifier.getStart() + 1, text: moduleSpecifier.text.replace(new RegExp(from, 'g'), to), }, ]; } else { return []; } } //# sourceMappingURL=update-imports.js.map