import type { GeneratorCallback, Tree } from '@nrwl/devkit'; import { addDependenciesToPackageJson, installPackagesTask, readJson, updateJson, } from '@nrwl/devkit'; import { prettierVersion } from '@nrwl/workspace/src/utils/versions'; import { nxVersion } from '../../utils/versions'; import type { ProjectMigrator } from './migrators'; import { AppMigrator, LibMigrator } from './migrators'; import type { GeneratorOptions } from './schema'; import { cleanupEsLintPackages, convertAllToNxProjects, createNxJson, createRootKarmaConfig, createWorkspaceFiles, deleteAngularJson, deleteGitKeepFilesIfNotNeeded, ensureAngularDevKitPeerDependenciesAreInstalled, formatFilesTask, getAllProjects, getWorkspaceRootFileTypesInfo, normalizeOptions, updatePackageJson, updatePrettierConfig, updateRootEsLintConfig, updateRootTsConfig, updateVsCodeRecommendedExtensions, updateWorkspaceConfigDefaults, validateWorkspace, } from './utilities'; export async function migrateFromAngularCli( tree: Tree, rawOptions: GeneratorOptions ): Promise { validateWorkspace(tree); const projects = getAllProjects(tree); const options = normalizeOptions(tree, rawOptions, projects); const angularJson = readJson(tree, 'angular.json') as any; ensureAngularDevKitPeerDependenciesAreInstalled(tree); if (options.preserveAngularCliLayout) { addDependenciesToPackageJson( tree, {}, { nx: nxVersion, '@nrwl/workspace': nxVersion, prettier: prettierVersion, } ); createNxJson(tree, options, angularJson.defaultProject); updateVsCodeRecommendedExtensions(tree); await updatePrettierConfig(tree); // convert workspace config format to standalone project configs updateJson(tree, 'angular.json', (json) => ({ ...json, version: 2, $schema: undefined, })); convertAllToNxProjects(tree); } else { const migrators: ProjectMigrator[] = [ ...projects.apps.map((app) => new AppMigrator(tree, options, app)), ...projects.libs.map((lib) => new LibMigrator(tree, options, lib)), ]; const workspaceRootFileTypesInfo = getWorkspaceRootFileTypesInfo( tree, migrators ); /** * Keep a copy of the root eslint config to restore it later. We need to * do this because the root config can also be the config for the app at * the root of the Angular CLI workspace and it will be moved as part of * the app migration. */ let eslintConfig = workspaceRootFileTypesInfo.eslint && tree.exists('.eslintrc.json') ? readJson(tree, '.eslintrc.json') : undefined; // create and update root files and configurations updateJson(tree, 'angular.json', (json) => ({ ...json, version: 2, $schema: undefined, })); createNxJson(tree, options, angularJson.defaultProject); updateWorkspaceConfigDefaults(tree); updateRootTsConfig(tree); updatePackageJson(tree); await createWorkspaceFiles(tree); // migrate all projects for (const migrator of migrators) { await migrator.migrate(); } /** * This needs to be done last because the Angular CLI workspace can have * these files in the root for the root application, so we wait until * those root config files are moved when the projects are migrated. */ if (workspaceRootFileTypesInfo.karma) { createRootKarmaConfig(tree); } if (workspaceRootFileTypesInfo.eslint) { updateRootEsLintConfig(tree, eslintConfig, options.unitTestRunner); cleanupEsLintPackages(tree); } deleteGitKeepFilesIfNotNeeded(tree); } deleteAngularJson(tree); if (!options.skipInstall) { return () => { installPackagesTask(tree); formatFilesTask(tree); }; } }