@nrwl/workspace
Version:
159 lines • 6.21 kB
JavaScript
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
;