diff --git a/packages/workspace/src/core/affected-project-graph/affected-project-graph.spec.ts b/packages/workspace/src/core/affected-project-graph/affected-project-graph.spec.ts index b736289f4b..469238e55e 100644 --- a/packages/workspace/src/core/affected-project-graph/affected-project-graph.spec.ts +++ b/packages/workspace/src/core/affected-project-graph/affected-project-graph.spec.ts @@ -163,11 +163,6 @@ describe('project graph', () => { type: 'app', data: expect.anything(), }, - 'demo-e2e': { - name: 'demo-e2e', - type: 'e2e', - data: expect.anything(), - }, ui: { name: 'ui', type: 'lib', @@ -175,13 +170,6 @@ describe('project graph', () => { }, }, dependencies: { - 'demo-e2e': [ - { - type: 'implicit', - source: 'demo-e2e', - target: 'demo', - }, - ], demo: [ { type: 'static', @@ -240,21 +228,9 @@ describe('project graph', () => { type: 'app', data: expect.anything(), }, - 'demo-e2e': { - name: 'demo-e2e', - type: 'e2e', - data: expect.anything(), - }, }, dependencies: { 'npm:happy-nrwl': [], - 'demo-e2e': [ - { - type: 'implicit', - source: 'demo-e2e', - target: 'demo', - }, - ], demo: [ { type: 'static', @@ -286,7 +262,7 @@ describe('project graph', () => { }, ]); - expect(Object.keys(affected.nodes)).toEqual(['demo', 'demo-e2e', 'api']); + expect(Object.keys(affected.nodes)).toEqual(['demo', 'api']); }); it('should support implicit JSON file dependencies (all projects)', async () => { diff --git a/packages/workspace/src/core/nx-deps/nx-deps-cache.spec.ts b/packages/workspace/src/core/nx-deps/nx-deps-cache.spec.ts new file mode 100644 index 0000000000..e88d28b5c9 --- /dev/null +++ b/packages/workspace/src/core/nx-deps/nx-deps-cache.spec.ts @@ -0,0 +1,358 @@ +import { NxJsonConfiguration, WorkspaceJsonConfiguration } from '@nrwl/devkit'; +import { + extractCachedPartOfProjectGraph, + ProjectGraphCache, + shouldRecomputeWholeGraph, +} from './nx-deps-cache'; + +describe('nx deps utils', () => { + describe('shouldRecomputeWholeGraph', () => { + it('should be false when nothing changes', () => { + expect( + shouldRecomputeWholeGraph( + createCache({}), + createPackageJsonDeps({}), + createWorkspaceJson({}), + createNxJson({}), + createTsConfigJson() + ) + ).toEqual(false); + }); + + it('should be true when version of nrwl/workspace changes', () => { + expect( + shouldRecomputeWholeGraph( + createCache({ + deps: { + '@nrwl/workspace': '12.0.1', + plugin: '1.0.0', + }, + }), + createPackageJsonDeps({}), + createWorkspaceJson({}), + createNxJson({}), + createTsConfigJson() + ) + ).toEqual(true); + }); + + it('should be true when a cached project is missing', () => { + expect( + shouldRecomputeWholeGraph( + createCache({ + nodes: { + 'renamed-mylib': {} as any, + }, + }), + createPackageJsonDeps({}), + createWorkspaceJson({}), + createNxJson({}), + createTsConfigJson() + ) + ).toEqual(true); + }); + + it('should be true when a path mapping changes', () => { + expect( + shouldRecomputeWholeGraph( + createCache({}), + createPackageJsonDeps({}), + createWorkspaceJson({}), + createNxJson({}), + createTsConfigJson({ mylib: ['libs/mylib/changed.ts'] }) + ) + ).toEqual(true); + }); + + it('should be true when number of plugins changed', () => { + expect( + shouldRecomputeWholeGraph( + createCache({}), + createPackageJsonDeps({}), + createWorkspaceJson({}), + createNxJson({ + plugins: ['plugin', 'plugin2'], + }), + createTsConfigJson() + ) + ).toEqual(true); + }); + + it('should be true when plugin version changed', () => { + expect( + shouldRecomputeWholeGraph( + createCache({}), + createPackageJsonDeps({ plugin: '2.0.0' }), + createWorkspaceJson({}), + createNxJson({}), + createTsConfigJson() + ) + ).toEqual(true); + }); + }); + + describe('extractCachedPartOfProjectGraph', () => { + it('should return the cache project graph when nothing has changed', () => { + const cached = { + nodes: { + mylib: { + name: 'mylib', + type: 'lib', + data: { + files: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash1', + }, + ], + }, + }, + }, + dependencies: { mylib: [] }, + } as any; + const r = extractCachedPartOfProjectGraph( + { + mylib: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash1', + }, + ], + }, + createNxJson({}), + createCache({ + nodes: { ...cached.nodes }, + dependencies: { ...cached.dependencies }, + }) + ); + expect(r.filesDifferentFromCache).toEqual({}); + expect(r.cachedPartOfProjectGraph).toEqual(cached); + }); + + it('should handle cases when no projects are added', () => { + const cached = { + nodes: { + mylib: { + name: 'mylib', + type: 'lib', + data: { + files: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash1', + }, + ], + }, + }, + }, + dependencies: { mylib: [] }, + } as any; + const r = extractCachedPartOfProjectGraph( + { + mylib: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash1', + }, + ], + secondlib: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash2', + }, + ], + }, + createNxJson({}), + createCache({ + nodes: { ...cached.nodes }, + dependencies: { ...cached.dependencies }, + }) + ); + expect(r.filesDifferentFromCache).toEqual({ + secondlib: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash2', + }, + ], + }); + expect(r.cachedPartOfProjectGraph).toEqual(cached); + }); + + it('should handle cases when files change', () => { + const cached = { + nodes: { + mylib: { + name: 'mylib', + type: 'lib', + data: { + files: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash1', + }, + ], + }, + }, + }, + dependencies: { mylib: [] }, + } as any; + const r = extractCachedPartOfProjectGraph( + { + mylib: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash2', + }, + ], + }, + createNxJson({}), + createCache({ + nodes: { ...cached.nodes }, + dependencies: { ...cached.dependencies }, + }) + ); + expect(r.filesDifferentFromCache).toEqual({ + mylib: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash2', + }, + ], + }); + expect(r.cachedPartOfProjectGraph).toEqual({ + nodes: {}, + dependencies: {}, + }); + }); + + it('should handle cases when implicits change', () => { + const cached = { + nodes: { + mylib: { + name: 'mylib', + type: 'lib', + data: { + files: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash1', + }, + ], + implicitDependencies: ['otherlib'], + }, + }, + }, + dependencies: { + mylib: [{ type: 'static', source: 'mylib', target: 'otherlib' }], + }, + } as any; + const r = extractCachedPartOfProjectGraph( + { + mylib: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash1', + }, + ], + }, + createNxJson({ + projects: { + mylib: { + implicitDependencies: [], + }, + }, + }), + createCache({ + nodes: { ...cached.nodes }, + dependencies: { ...cached.dependencies }, + }) + ); + expect(r.filesDifferentFromCache).toEqual({ + mylib: [ + { + file: 'index.ts', + ext: 'ts', + hash: 'hash1', + }, + ], + }); + expect(r.cachedPartOfProjectGraph).toEqual({ + nodes: {}, + dependencies: {}, + }); + }); + }); + + function createCache(p: Partial): ProjectGraphCache { + const defaults: ProjectGraphCache = { + version: '3.0', + deps: { + '@nrwl/workspace': '12.0.0', + plugin: '1.0.0', + }, + pathMappings: { + mylib: ['libs/mylib/index.ts'], + }, + nxJsonPlugins: [{ name: 'plugin', version: '1.0.0' }], + nodes: { + mylib: {} as any, + }, + dependencies: { mylib: [] }, + }; + return { ...defaults, ...p }; + } + + function createPackageJsonDeps( + p: Record + ): Record { + const defaults = { + '@nrwl/workspace': '12.0.0', + plugin: '1.0.0', + }; + return { ...defaults, ...p }; + } + + function createWorkspaceJson(p: any): WorkspaceJsonConfiguration { + const defaults = { + projects: { mylib: {} }, + } as any; + return { ...defaults, ...p }; + } + + function createNxJson(p: Partial): NxJsonConfiguration { + const defaults: NxJsonConfiguration = { + npmScope: '', + projects: { mylib: {} }, + workspaceLayout: {} as any, + targetDependencies: {}, + plugins: ['plugin'], + }; + return { ...defaults, ...p }; + } + + function createTsConfigJson(paths?: { [k: string]: any }): any { + const r = { + compilerOptions: { + paths: { + mylib: ['libs/mylib/index.ts'], + }, + }, + } as any; + if (paths) { + r.compilerOptions.paths = paths; + } + return r; + } +}); diff --git a/packages/workspace/src/core/nx-deps/nx-deps-cache.ts b/packages/workspace/src/core/nx-deps/nx-deps-cache.ts index c864fe7987..187f73b7f2 100644 --- a/packages/workspace/src/core/nx-deps/nx-deps-cache.ts +++ b/packages/workspace/src/core/nx-deps/nx-deps-cache.ts @@ -1,8 +1,10 @@ import { FileData, filesChanged } from '../file-utils'; import type { + NxJsonConfiguration, ProjectGraph, ProjectGraphDependency, ProjectGraphNode, + WorkspaceJsonConfiguration, } from '@nrwl/devkit'; import { join } from 'path'; import { appRootPath } from '@nrwl/tao/src/utils/app-root'; @@ -23,7 +25,9 @@ import { export interface ProjectGraphCache { version: string; - rootFiles: FileData[]; + deps: Record; + pathMappings: Record; + nxJsonPlugins: { name: string; version: string }[]; nodes: Record; dependencies: Record; } @@ -74,68 +78,125 @@ export function readCache(): false | ProjectGraphCache { } export function writeCache( - rootFiles: FileData[], + packageJsonDeps: Record, + nxJson: NxJsonConfiguration, + tsConfig: { compilerOptions: { paths: { [k: string]: any } } }, projectGraph: ProjectGraph ): void { performance.mark('write cache:start'); - writeJsonFile(nxDepsPath, { - version: '2.0', - rootFiles, + const nxJsonPlugins = (nxJson.plugins || []).map((p) => ({ + name: p, + version: packageJsonDeps[p], + })); + const newValue: ProjectGraphCache = { + version: '3.0', + deps: packageJsonDeps, + pathMappings: tsConfig.compilerOptions.paths, + nxJsonPlugins, nodes: projectGraph.nodes, dependencies: projectGraph.dependencies, - }); + }; + writeJsonFile(nxDepsPath, newValue); performance.mark('write cache:end'); performance.measure('write cache', 'write cache:start', 'write cache:end'); } -export function differentFromCache( - fileMap: ProjectFileMap, - c: ProjectGraphCache -): { - noDifference: boolean; - filesDifferentFromCache: ProjectFileMap; - partiallyConstructedProjectGraph?: ProjectGraph; -} { - const currentProjects = Object.keys(fileMap) - .sort() - .filter((name) => fileMap[name].length > 0); - const previousProjects = Object.keys(c.nodes) - .sort() - .filter((name) => c.nodes[name].data.files.length > 0); - - // Projects changed -> compute entire graph - if ( - currentProjects.length !== previousProjects.length || - currentProjects.some((val, idx) => val !== previousProjects[idx]) - ) { - return { - filesDifferentFromCache: fileMap, - partiallyConstructedProjectGraph: null, - noDifference: false, - }; +export function shouldRecomputeWholeGraph( + cache: ProjectGraphCache, + packageJsonDeps: Record, + workspaceJson: WorkspaceJsonConfiguration, + nxJson: NxJsonConfiguration, + tsConfig: { compilerOptions: { paths: { [k: string]: any } } } +): boolean { + if (cache.deps['@nrwl/workspace'] !== packageJsonDeps['@nrwl/workspace']) { + return true; } - // Projects are same -> compute projects with file changes + // we have a cached project that is no longer present + if ( + Object.keys(cache.nodes).some( + (p) => + cache.nodes[p].type != 'app' && + cache.nodes[p].type != 'lib' && + !workspaceJson.projects[p] + ) + ) { + return true; + } + + // a path mapping for an existing project has changed + if ( + Object.keys(cache.pathMappings).some( + (t) => + JSON.stringify(cache.pathMappings[t]) != + JSON.stringify(tsConfig.compilerOptions.paths[t]) + ) + ) { + return true; + } + + // a new plugin has been added + if ((nxJson.plugins || []).length !== cache.nxJsonPlugins.length) return true; + + // a plugin has changed + if ( + (nxJson.plugins || []).some((t) => { + const matchingPlugin = cache.nxJsonPlugins.find((p) => p.name === t); + if (!matchingPlugin) return true; + return matchingPlugin.version !== packageJsonDeps[t]; + }) + ) { + return true; + } + + return false; +} + +/* +This can only be invoked when the list of projects is either the same +or new projects have been added, so every project in the cache has a corresponding +project in fileMap +*/ +export function extractCachedPartOfProjectGraph( + fileMap: ProjectFileMap, + nxJson: NxJsonConfiguration, + c: ProjectGraphCache +): { + filesDifferentFromCache: ProjectFileMap; + cachedPartOfProjectGraph: ProjectGraph; +} { + const currentProjects = Object.keys(fileMap).filter( + (name) => fileMap[name].length > 0 + ); + const filesDifferentFromCache: ProjectFileMap = {}; + // Re-compute nodes and dependencies for projects whose files changed currentProjects.forEach((p) => { - if (filesChanged(c.nodes[p].data.files, fileMap[p])) { + if (!c.nodes[p] || filesChanged(c.nodes[p].data.files, fileMap[p])) { filesDifferentFromCache[p] = fileMap[p]; + delete c.dependencies[p]; + delete c.nodes[p]; } }); - // Re-compute nodes and dependencies for each project in file map. - Object.keys(filesDifferentFromCache).forEach((key) => { - delete c.dependencies[key]; + // Re-compute nodes and dependencies for projects whose implicit deps changed + Object.keys(nxJson.projects || {}).forEach((p) => { + if ( + nxJson.projects[p]?.implicitDependencies && + JSON.stringify(c.nodes[p].data.implicitDependencies) !== + JSON.stringify(nxJson.projects[p].implicitDependencies) + ) { + filesDifferentFromCache[p] = fileMap[p]; + delete c.dependencies[p]; + delete c.nodes[p]; + } }); - const partiallyConstructedProjectGraph = { - nodes: c.nodes, - dependencies: c.dependencies, - }; - return { filesDifferentFromCache, - partiallyConstructedProjectGraph, - noDifference: Object.keys(filesDifferentFromCache).length === 0, + cachedPartOfProjectGraph: { + nodes: c.nodes, + dependencies: c.dependencies, + }, }; } diff --git a/packages/workspace/src/core/project-graph/build-dependencies/implicit-project-dependencies.ts b/packages/workspace/src/core/project-graph/build-dependencies/implicit-project-dependencies.ts index 9523c0fc10..6f1209a7e6 100644 --- a/packages/workspace/src/core/project-graph/build-dependencies/implicit-project-dependencies.ts +++ b/packages/workspace/src/core/project-graph/build-dependencies/implicit-project-dependencies.ts @@ -17,14 +17,5 @@ export function buildImplicitProjectDependencies( addDependency(DependencyType.implicit, source, target); }); } - - // TODO(v10): remove this because implicit dependencies are generated now.. - if (source.endsWith('-e2e')) { - const target = source.replace(/-e2e$/, ''); - // Only add if expected source actually exists, otherwise this will error out. - if (nodes[target]) { - addDependency(DependencyType.implicit, source, target); - } - } }); } diff --git a/packages/workspace/src/core/project-graph/project-graph-models.ts b/packages/workspace/src/core/project-graph/project-graph-models.ts index ad873df8b4..0a2ddf1bdf 100644 --- a/packages/workspace/src/core/project-graph/project-graph-models.ts +++ b/packages/workspace/src/core/project-graph/project-graph-models.ts @@ -11,28 +11,16 @@ export { DependencyType, } from '@nrwl/devkit'; -/** - * @deprecated - */ export type ProjectGraphNodeRecords = Record; -/** - * @deprecated - */ export type AddProjectNode = (node: ProjectGraphNode) => void; -/** - * @deprecated - */ export type AddProjectDependency = ( type: DependencyType | string, source: string, target: string ) => void; -/** - * @deprecated - */ export interface ProjectGraphContext { workspaceJson: any; nxJson: NxJsonConfiguration; diff --git a/packages/workspace/src/core/project-graph/project-graph.spec.ts b/packages/workspace/src/core/project-graph/project-graph.spec.ts index 821bcaa30d..cbaf19025a 100644 --- a/packages/workspace/src/core/project-graph/project-graph.spec.ts +++ b/packages/workspace/src/core/project-graph/project-graph.spec.ts @@ -162,9 +162,7 @@ describe('project graph', () => { api: [ { type: DependencyType.static, source: 'api', target: 'npm:express' }, ], - 'demo-e2e': [ - { type: DependencyType.implicit, source: 'demo-e2e', target: 'demo' }, - ], + 'demo-e2e': [], demo: [ { type: DependencyType.static, source: 'demo', target: 'ui' }, { @@ -193,21 +191,19 @@ describe('project graph', () => { }); }); - it('should update the graph if the workspace file changes ', async () => { + it('should update the graph if a project got renamed', async () => { let graph = await createProjectGraphAsync(); expect(graph.nodes).toMatchObject({ demo: { name: 'demo', type: 'app' }, }); - workspaceJson.projects.demo.projectType = 'library'; - //wait a tick to ensure the modified time of workspace.json will be after the creation of the project graph file - await new Promise((resolve) => setTimeout(resolve, 1)); + workspaceJson.projects.renamed = workspaceJson.projects.demo; fs.writeFileSync('/root/workspace.json', JSON.stringify(workspaceJson)); defaultFileHasher.init(); graph = await createProjectGraphAsync(); expect(graph.nodes).toMatchObject({ - demo: { name: 'demo', type: 'lib' }, + renamed: { name: 'renamed', type: 'app' }, }); }); diff --git a/packages/workspace/src/core/project-graph/project-graph.ts b/packages/workspace/src/core/project-graph/project-graph.ts index 0cf83a3003..69a644731f 100644 --- a/packages/workspace/src/core/project-graph/project-graph.ts +++ b/packages/workspace/src/core/project-graph/project-graph.ts @@ -2,27 +2,31 @@ import type { FileData, NxJsonConfiguration, NxJsonProjectConfiguration, + NxPlugin, ProjectConfiguration, ProjectFileMap, - WorkspaceJsonConfiguration, - ProjectGraphProcessorContext, - NxPlugin, ProjectGraph, + ProjectGraphProcessorContext, + WorkspaceJsonConfiguration, } from '@nrwl/devkit'; - -import { ProjectGraphBuilder } from '@nrwl/devkit'; - +import { ProjectGraphBuilder, readJsonFile } from '@nrwl/devkit'; import { appRootPath } from '@nrwl/tao/src/utils/app-root'; +import { join } from 'path'; +import { performance } from 'perf_hooks'; import { assertWorkspaceValidity } from '../assert-workspace-validity'; import { createProjectFileMap } from '../file-graph'; import { - filesChanged, readNxJson, readWorkspaceFiles, readWorkspaceJson, - rootWorkspaceFileData, } from '../file-utils'; import { normalizeNxJson } from '../normalize-nx-json'; +import { + extractCachedPartOfProjectGraph, + readCache, + shouldRecomputeWholeGraph, + writeCache, +} from '../nx-deps/nx-deps-cache'; import { BuildDependencies, buildExplicitPackageJsonDependencies, @@ -34,17 +38,16 @@ import { buildNpmPackageNodes, buildWorkspaceProjectNodes, } from './build-nodes'; -import { - differentFromCache, - readCache, - writeCache, -} from '../nx-deps/nx-deps-cache'; -import { performance } from 'perf_hooks'; export async function createProjectGraphAsync(): Promise { return createProjectGraph(); } +function readCombinedDeps() { + const json = readJsonFile(join(appRootPath, 'package.json')); + return { ...json.dependencies, ...json.devDependencies }; +} + // TODO(v13): remove this deprecated function /** * @deprecated This function is deprecated in favor of the new asynchronous version {@link createProjectGraphAsync} @@ -58,30 +61,29 @@ export function createProjectGraph( let cache = cacheEnabled ? readCache() : false; assertWorkspaceValidity(workspaceJson, nxJson); const normalizedNxJson = normalizeNxJson(nxJson); - - const rootFiles = rootWorkspaceFileData(); const projectFileMap = createProjectFileMap(workspaceJson, workspaceFiles); - - if (cache && !filesChanged(rootFiles, cache.rootFiles)) { - const diff = differentFromCache(projectFileMap, cache); - if (diff.noDifference) { - return addWorkspaceFiles( - diff.partiallyConstructedProjectGraph, - workspaceFiles - ); - } - + const packageJsonDeps = readCombinedDeps(); + const rootTsConfig = readRootTsConfig(); + if ( + cache && + cache.version === '3.0' && + !shouldRecomputeWholeGraph( + cache, + packageJsonDeps, + workspaceJson, + normalizedNxJson, + rootTsConfig + ) + ) { + const diff = extractCachedPartOfProjectGraph(projectFileMap, nxJson, cache); const ctx = { workspaceJson, nxJson: normalizedNxJson, fileMap: diff.filesDifferentFromCache, }; - const projectGraph = buildProjectGraph( - ctx, - diff.partiallyConstructedProjectGraph - ); + const projectGraph = buildProjectGraph(ctx, diff.cachedPartOfProjectGraph); if (cacheEnabled) { - writeCache(rootFiles, projectGraph); + writeCache(packageJsonDeps, nxJson, rootTsConfig, projectGraph); } return addWorkspaceFiles(projectGraph, workspaceFiles); } else { @@ -92,7 +94,7 @@ export function createProjectGraph( }; const projectGraph = buildProjectGraph(ctx, null); if (cacheEnabled) { - writeCache(rootFiles, projectGraph); + writeCache(packageJsonDeps, nxJson, rootTsConfig, projectGraph); } return addWorkspaceFiles(projectGraph, workspaceFiles); } @@ -110,31 +112,41 @@ function addWorkspaceFiles( return { ...projectGraph, allWorkspaceFiles }; } -function buildProjectGraph( - ctx: { - nxJson: NxJsonConfiguration; - workspaceJson: WorkspaceJsonConfiguration; - fileMap: ProjectFileMap; - }, - projectGraph: ProjectGraph -) { - performance.mark('build project graph:start'); - const builder = new ProjectGraphBuilder(projectGraph); - const buildNodesFns: BuildNodes[] = [ - buildWorkspaceProjectNodes, - buildNpmPackageNodes, - ]; - const buildDependenciesFns: BuildDependencies[] = [ - buildExplicitTypeScriptDependencies, - buildImplicitProjectDependencies, - buildExplicitPackageJsonDependencies, - ]; - buildNodesFns.forEach((f) => f(ctx, builder.addNode.bind(builder))); - buildDependenciesFns.forEach((f) => - f(ctx, builder.nodes, builder.addDependency.bind(builder)) - ); - const r = builder.getProjectGraph(); +type BuilderContext = { + nxJson: NxJsonConfiguration; + workspaceJson: WorkspaceJsonConfiguration; + fileMap: ProjectFileMap; +}; +function buildProjectGraph(ctx: BuilderContext, projectGraph: ProjectGraph) { + performance.mark('build project graph:start'); + + const builder = new ProjectGraphBuilder(projectGraph); + const addNode = builder.addNode.bind(builder); + const addDependency = builder.addDependency.bind(builder); + buildWorkspaceProjectNodes(ctx, addNode); + buildNpmPackageNodes(ctx, addNode); + buildExplicitTypeScriptDependencies(ctx, builder.nodes, addDependency); + buildExplicitPackageJsonDependencies(ctx, builder.nodes, addDependency); + buildImplicitProjectDependencies(ctx, builder.nodes, addDependency); + const initProjectGraph = builder.getProjectGraph(); + + const r = updateProjectGraphWithPlugins(ctx, initProjectGraph); + + performance.mark('build project graph:end'); + performance.measure( + 'build project graph', + 'build project graph:start', + 'build project graph:end' + ); + + return r; +} + +function updateProjectGraphWithPlugins( + ctx: BuilderContext, + initProjectGraph: ProjectGraph +) { const plugins = (ctx.nxJson.plugins || []).map((path) => { const pluginPath = require.resolve(path, { paths: [appRootPath], @@ -161,19 +173,18 @@ function buildProjectGraph( fileMap: ctx.fileMap, }; - const result = plugins.reduce((graph, plugin) => { + return plugins.reduce((graph, plugin) => { if (!plugin.processProjectGraph) { return graph; } - return plugin.processProjectGraph(graph, context); - }, r); - - performance.mark('build project graph:end'); - performance.measure( - 'build project graph', - 'build project graph:start', - 'build project graph:end' - ); - return result; + }, initProjectGraph); +} + +function readRootTsConfig() { + try { + return readJsonFile(join(appRootPath, 'tsconfig.base.json')); + } catch (e) { + return readJsonFile(join(appRootPath, 'tsconfig.json')); + } }