From 5b23923cbb1153090349f70514ee359f8c7eaee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Jona=C5=A1?= Date: Thu, 29 Jul 2021 17:17:31 +0200 Subject: [PATCH] cleanup(core): use isNpmProject and cleanup project graph utils (#6522) * cleanup(core): use isNpmProject and cleanup project graph utils * chore(core): mark utils/buildable-libs-utils as deprecated --- ...-template-support-and-presets-to-eslint.ts | 7 ++- .../migrations/update-9-4-0/babelrc-9-4-0.ts | 17 +++++--- .../locators/npm-packages.ts | 5 +-- .../src/core/file-graph/project-file-map.ts | 13 +++--- .../workspace/src/core/normalize-nx-json.ts | 43 +++++++++++++------ .../explicit-project-dependencies.ts | 2 +- .../src/utilities/buildable-libs-utils.ts | 18 +++----- .../src/utilities/create-package-json.ts | 5 ++- .../src/utilities/project-graph-utils.ts | 8 ++-- .../src/utils/buildable-libs-utils.spec.ts | 2 + .../src/utils/buildable-libs-utils.ts | 22 ++++++++++ 11 files changed, 92 insertions(+), 50 deletions(-) diff --git a/packages/angular/src/migrations/update-10-5-0/add-template-support-and-presets-to-eslint.ts b/packages/angular/src/migrations/update-10-5-0/add-template-support-and-presets-to-eslint.ts index 0aaa8a0a072d73..1a50314d61e1f3 100644 --- a/packages/angular/src/migrations/update-10-5-0/add-template-support-and-presets-to-eslint.ts +++ b/packages/angular/src/migrations/update-10-5-0/add-template-support-and-presets-to-eslint.ts @@ -11,7 +11,10 @@ import { } from '@nrwl/workspace'; import { join } from 'path'; import { offsetFromRoot } from '@nrwl/devkit'; -import { createProjectGraphAsync } from '@nrwl/workspace/src/core/project-graph'; +import { + createProjectGraphAsync, + isNpmProject, +} from '@nrwl/workspace/src/core/project-graph'; /** * It was decided with Jason that we would do a simple replacement in this migration @@ -67,7 +70,7 @@ async function updateProjectESLintConfigsAndBuilders( !graph.dependencies[projectName].some( (dependency) => dependency.target.startsWith('npm:@angular/') && - graph.nodes[dependency.target].type === 'npm' + isNpmProject(graph.nodes[dependency.target]) ) ) { return; diff --git a/packages/react/src/migrations/update-9-4-0/babelrc-9-4-0.ts b/packages/react/src/migrations/update-9-4-0/babelrc-9-4-0.ts index 1435390c1e4a64..53124f43d86ac1 100644 --- a/packages/react/src/migrations/update-9-4-0/babelrc-9-4-0.ts +++ b/packages/react/src/migrations/update-9-4-0/babelrc-9-4-0.ts @@ -10,7 +10,10 @@ import { } from '@angular-devkit/core/src/utils/literals'; import { initRootBabelConfig } from '../utils/rules'; import { addDepsToPackageJson, formatFiles } from '@nrwl/workspace'; -import { createProjectGraphAsync } from '@nrwl/workspace/src/core/project-graph'; +import { + createProjectGraphAsync, + isNpmProject, +} from '@nrwl/workspace/src/core/project-graph'; let addedEmotionPreset = false; @@ -30,7 +33,7 @@ export default function update(): Rule { context.logger.info( ` Found an existing babel.config.json file so we skipped creating it. - + You may want to update it to include the Nx preset "@nrwl/web/babel". ` ); @@ -38,7 +41,7 @@ export default function update(): Rule { context.logger.info( ` Found an existing babel.config.js file so we skipped creating it. - + You may want to update it to include the Nx preset "@nrwl/web/babel". ` ); @@ -51,7 +54,7 @@ export default function update(): Rule { const deps = projectGraph.dependencies[name]; const isReact = deps.some( (d) => - projectGraph.nodes[d.target].type === 'npm' && + isNpmProject(projectGraph.nodes[d.target]) && d.target.indexOf('react') !== -1 ); if (isReact) { @@ -69,11 +72,11 @@ export default function update(): Rule { if (conflicts.length > 0) { context.logger.info(stripIndent` The following projects already have .babelrc so we did not create them: - + ${conflicts .map(([name, babelrc]) => `${name} - ${babelrc}`) .join('\n ')} - + You may want to update them to include the Nx preset "@nrwl/react/babel". `); } @@ -109,7 +112,7 @@ function createBabelrc(host, context, babelrcPath, deps) { context.logger.warn( stripIndents`We created a babel config at ${babelrcPath} with both styled-components and emotion plugins. Only one should be used, please remove the unused plugin. - + For example, if you don't use styled-components, then remove that plugin from the .babelrc file. ` ); diff --git a/packages/workspace/src/core/affected-project-graph/locators/npm-packages.ts b/packages/workspace/src/core/affected-project-graph/locators/npm-packages.ts index 6796670353d55c..1233817c40623e 100644 --- a/packages/workspace/src/core/affected-project-graph/locators/npm-packages.ts +++ b/packages/workspace/src/core/affected-project-graph/locators/npm-packages.ts @@ -5,6 +5,7 @@ import { JsonChange, } from '../../../utilities/json-diff'; import { TouchedProjectLocator } from '../affected-project-graph-models'; +import { isNpmProject } from '../../project-graph/operators'; export const getTouchedNpmPackages: TouchedProjectLocator< WholeFileChange | JsonChange @@ -21,9 +22,7 @@ export const getTouchedNpmPackages: TouchedProjectLocator< let touched = []; const changes = packageJsonChange.getChanges(); - const npmPackages = Object.values(projectGraph.nodes).filter( - (node) => node.type === 'npm' - ); + const npmPackages = Object.values(projectGraph.nodes).filter(isNpmProject); for (const c of changes) { if ( diff --git a/packages/workspace/src/core/file-graph/project-file-map.ts b/packages/workspace/src/core/file-graph/project-file-map.ts index 3f6804b12f313c..1a01e04fb056f5 100644 --- a/packages/workspace/src/core/file-graph/project-file-map.ts +++ b/packages/workspace/src/core/file-graph/project-file-map.ts @@ -10,16 +10,15 @@ export function createProjectFileMap( // a chance to match prefix first. Object.keys(workspaceJson.projects) .sort((a, b) => { - if (!workspaceJson.projects[a].root) return -1; - if (!workspaceJson.projects[b].root) return -1; - return workspaceJson.projects[a].root.length > - workspaceJson.projects[b].root.length - ? -1 - : 1; + const projectA = workspaceJson.projects[a]; + const projectB = workspaceJson.projects[b]; + if (!projectA.root) return -1; + if (!projectB.root) return -1; + return projectA.root.length > projectB.root.length ? -1 : 1; }) .forEach((projectName) => { const p = workspaceJson.projects[projectName]; - fileMap[projectName] = fileMap[projectName] || []; + fileMap[projectName] = []; files.forEach((f) => { if (seen.has(f.file)) { return; diff --git a/packages/workspace/src/core/normalize-nx-json.ts b/packages/workspace/src/core/normalize-nx-json.ts index 0c4f2b433c5887..06812f14230d89 100644 --- a/packages/workspace/src/core/normalize-nx-json.ts +++ b/packages/workspace/src/core/normalize-nx-json.ts @@ -1,5 +1,11 @@ import { NxJsonConfiguration } from '@nrwl/devkit'; +/** + * Normalize nx json by replacing wildcard `*` implicit dependencies + * to an array of all project names + * @param {NxJsonConfiguration} nxJson + * @returns {NxJsonConfiguration} + */ export function normalizeNxJson( nxJson: NxJsonConfiguration ): NxJsonConfiguration { @@ -9,22 +15,31 @@ export function normalizeNxJson( implicitDependencies: Object.entries( nxJson.implicitDependencies ).reduce((acc, [key, val]) => { - acc[key] = recur(val); + acc[key] = recur(nxJson, val); return acc; - - function recur(v: '*' | string[] | {}): string[] | {} { - if (v === '*') { - return Object.keys(nxJson.projects); - } else if (Array.isArray(v)) { - return v; - } else { - return Object.keys(v).reduce((xs, x) => { - xs[x] = recur(v[x]); - return xs; - }, {}); - } - } }, {}), } : (nxJson as NxJsonConfiguration); } + +/** + * Map recursively wildcard `*` to project names + * @param {NxJsonConfiguration} nxJson + * @param {'*' | string[] | {}} v + * @returns {string[] | {}} + */ +function recur( + nxJson: NxJsonConfiguration, + v: '*' | string[] | {} +): string[] | {} { + if (v === '*') { + return Object.keys(nxJson.projects); + } else if (Array.isArray(v)) { + return v; + } else { + return Object.keys(v).reduce((acc, key) => { + acc[key] = recur(nxJson, v[key]); + return acc; + }, {}); + } +} diff --git a/packages/workspace/src/core/project-graph/build-dependencies/explicit-project-dependencies.ts b/packages/workspace/src/core/project-graph/build-dependencies/explicit-project-dependencies.ts index f4e3bc364cfbf2..562e619e34897d 100644 --- a/packages/workspace/src/core/project-graph/build-dependencies/explicit-project-dependencies.ts +++ b/packages/workspace/src/core/project-graph/build-dependencies/explicit-project-dependencies.ts @@ -22,7 +22,7 @@ export function buildExplicitTypeScriptDependencies( f.file, ctx.workspace.npmScope ); - if (source && target) { + if (target) { builder.addExplicitDependency(source, f.file, target); } } diff --git a/packages/workspace/src/utilities/buildable-libs-utils.ts b/packages/workspace/src/utilities/buildable-libs-utils.ts index 2b3e1db3bbe27c..1f4c4e43bec41b 100644 --- a/packages/workspace/src/utilities/buildable-libs-utils.ts +++ b/packages/workspace/src/utilities/buildable-libs-utils.ts @@ -1,11 +1,6 @@ -import { ProjectType } from '../core/project-graph'; +import { isNpmProject, ProjectType } from '../core/project-graph'; import { join, resolve, dirname, relative } from 'path'; -import { - directoryExists, - fileExists, - readJsonFile, - writeJsonFile, -} from './fileutils'; +import { directoryExists, readJsonFile, writeJsonFile } from './fileutils'; import { stripIndents } from '@nrwl/devkit'; import type { ProjectGraph, ProjectGraphNode } from '@nrwl/devkit'; import { getOutputsForTargetAndConfiguration } from '../tasks-runner/utils'; @@ -66,7 +61,7 @@ export function calculateProjectDependencies( ), node: depNode, }; - } else if (depNode.type === 'npm') { + } else if (isNpmProject(depNode)) { return { name: depNode.data.packageName, outputs: [], @@ -286,8 +281,9 @@ export function updateBuildableProjectPackageJsonDependencies( let updatePackageJson = false; dependencies.forEach((entry) => { - const packageName = - entry.node.type === 'npm' ? entry.node.data.packageName : entry.name; + const packageName = isNpmProject(entry.node) + ? entry.node.data.packageName + : entry.name; if ( !hasDependency(packageJson, 'dependencies', packageName) && @@ -313,7 +309,7 @@ export function updateBuildableProjectPackageJsonDependencies( depVersion = readJsonFile(depPackageJsonPath).version; packageJson[typeOfDependency][packageName] = depVersion; - } else if (entry.node.type === 'npm') { + } else if (isNpmProject(entry.node)) { // If an npm dep is part of the workspace devDependencies, do not include it the library if ( !!workspacePackageJson.devDependencies?.[ diff --git a/packages/workspace/src/utilities/create-package-json.ts b/packages/workspace/src/utilities/create-package-json.ts index d611fa6d561d17..10374cbcaef9f9 100644 --- a/packages/workspace/src/utilities/create-package-json.ts +++ b/packages/workspace/src/utilities/create-package-json.ts @@ -1,4 +1,5 @@ import type { ProjectGraph } from '@nrwl/devkit'; +import { isNpmProject } from '../core/project-graph'; import { readJsonFile } from './fileutils'; /** @@ -58,7 +59,7 @@ function findAllNpmDeps( const node = graph.nodes[projectName]; - if (node.type === 'npm') { + if (isNpmProject(node)) { list[node.data.packageName] = node.data.version; recursivelyCollectPeerDependencies(node.name, graph, list); } @@ -77,7 +78,7 @@ function recursivelyCollectPeerDependencies( ) { if ( !graph.nodes[projectName] || - graph.nodes[projectName].type !== 'npm' || + !isNpmProject(graph.nodes[projectName]) || seen.has(projectName) ) { return list; diff --git a/packages/workspace/src/utilities/project-graph-utils.ts b/packages/workspace/src/utilities/project-graph-utils.ts index 9a41ef6666092e..c528403b378f91 100644 --- a/packages/workspace/src/utilities/project-graph-utils.ts +++ b/packages/workspace/src/utilities/project-graph-utils.ts @@ -67,9 +67,11 @@ export function getProjectNameFromDirPath( } /** - * Takes a filename and figures out the belonging app and from there - * collects all dependent - * @param filename name of a file in some workspace app / lib + * Find all internal project dependencies. + * All the external (npm) dependencies will be filtered out + * @param {string} parentNodeName + * @param {ProjectGraph} projectGraph + * @returns {string[]} */ function findAllProjectNodeDependencies( parentNodeName: string, diff --git a/packages/workspace/src/utils/buildable-libs-utils.spec.ts b/packages/workspace/src/utils/buildable-libs-utils.spec.ts index 216d3f6322f117..bdfbf8b522ce53 100644 --- a/packages/workspace/src/utils/buildable-libs-utils.spec.ts +++ b/packages/workspace/src/utils/buildable-libs-utils.spec.ts @@ -10,6 +10,8 @@ import { } from '../core/project-graph'; import { getMockContext } from './testing'; +// TODO(v13): remove this deprecated file + describe('updatePaths', () => { const deps: DependentBuildableProjectNode[] = [ { name: '@proj/lib', node: {} as any, outputs: ['dist/libs/lib'] }, diff --git a/packages/workspace/src/utils/buildable-libs-utils.ts b/packages/workspace/src/utils/buildable-libs-utils.ts index 778d7b9ad035ff..a119fdc54ad7d4 100644 --- a/packages/workspace/src/utils/buildable-libs-utils.ts +++ b/packages/workspace/src/utils/buildable-libs-utils.ts @@ -12,6 +12,8 @@ import { getOutputsForTargetAndConfiguration } from '../tasks-runner/utils'; import * as ts from 'typescript'; import { unlinkSync } from 'fs'; +// TODO(v13): remove this deprecated file + function isBuildable(target: string, node: ProjectGraphNode): boolean { return ( node.data.targets && @@ -20,12 +22,18 @@ function isBuildable(target: string, node: ProjectGraphNode): boolean { ); } +/** + * @deprecated will be removed in v13. Use `{@link DependentBuildableProjectNode}` from `utilities/buildable-libs-utils` + */ export type DependentBuildableProjectNode = { name: string; outputs: string[]; node: ProjectGraphNode; }; +/** + * @deprecated will be removed in v13. Use `{@link calculateProjectDependencies}` from `utilities/buildable-libs-utils` + */ export function calculateProjectDependencies( projGraph: ProjectGraph, context: BuilderContext @@ -103,6 +111,9 @@ function readTsConfigWithRemappedPaths( return generatedTsConfig; } +/** + * @deprecated will be removed in v13. Use `{@link computeCompilerOptionsPaths}` from `utilities/buildable-libs-utils` + */ export function computeCompilerOptionsPaths(tsConfig, dependencies) { const paths = readPaths(tsConfig) || {}; updatePaths(dependencies, paths); @@ -127,6 +138,9 @@ function readPaths(tsConfig: string) { } } +/** + * @deprecated will be removed in v13. Use `{@link createTmpTsConfig}` from `utilities/buildable-libs-utils` + */ export function createTmpTsConfig( tsconfigPath: string, workspaceRoot: string, @@ -159,6 +173,9 @@ function cleanupTmpTsConfigFile(tmpTsConfigPath) { } catch (e) {} } +/** + * @deprecated will be removed in v13. Use `{@link checkDependentProjectsHaveBeenBuilt}` from `utilities/buildable-libs-utils` + */ export function checkDependentProjectsHaveBeenBuilt( context: BuilderContext, projectDependencies: DependentBuildableProjectNode[] @@ -196,6 +213,9 @@ export function checkDependentProjectsHaveBeenBuilt( } } +/** + * @deprecated will be removed in v13. Use `{@link updatePaths}` from `utilities/buildable-libs-utils` + */ export function updatePaths( dependencies: DependentBuildableProjectNode[], paths: Record @@ -218,6 +238,8 @@ export function updatePaths( /** * Updates the peerDependencies section in the `dist/lib/xyz/package.json` with * the proper dependency and version + * + * @deprecated will be removed in v13. Use `{@link updateBuildableProjectPackageJsonDependencies}` from `utilities/buildable-libs-utils` */ export function updateBuildableProjectPackageJsonDependencies( context: BuilderContext,