From 30d94f76ee29f9e88a034f9dfb86f80edd2ee646 Mon Sep 17 00:00:00 2001 From: Craigory Coppola Date: Fri, 17 Nov 2023 15:31:03 -0500 Subject: [PATCH] cleanup(core): remove async flag from signature of buildProjectsConfigurationsFromProjectPathsAndPlugins (#20228) --- docs/generated/devkit/CreateNodesAsync.md | 9 - docs/generated/devkit/CreateNodesFunction.md | 6 +- docs/generated/devkit/NxPluginV2.md | 13 +- docs/generated/devkit/README.md | 1 - .../packages/devkit/documents/nx_devkit.md | 1 - .../recipes/plugins/project-graph-plugins.md | 2 +- graph/client/tsconfig.app.json | 2 +- jest.preset.js | 1 + nx-dev/models-document/jest.config.ts | 1 - nx-dev/models-menu/jest.config.ts | 1 - nx-dev/models-package/jest.config.ts | 1 - nx-dev/ui-sponsor-card/jest.config.ts | 1 + nx-dev/util-ai/jest.config.ts | 1 - packages/angular/jest.config.ts | 1 - packages/create-nx-plugin/jest.config.ts | 1 - packages/create-nx-workspace/jest.config.ts | 1 - packages/cypress/jest.config.ts | 1 - .../add-nx-cypress-plugin.spec.ts | 1 + packages/detox/jest.config.ts | 1 - packages/devkit/jest.config.ts | 1 - ...place-project-configuration-with-plugin.ts | 4 +- packages/esbuild/jest.config.ts | 1 - packages/eslint-plugin/jest.config.ts | 1 - packages/eslint/jest.config.ts | 1 - packages/expo/jest.config.ts | 1 - packages/express/jest.config.ts | 1 - packages/jest/jest.config.ts | 1 - packages/js/jest.config.ts | 1 - packages/nest/jest.config.ts | 1 - packages/next/jest.config.ts | 1 - packages/node/jest.config.ts | 1 - packages/nx/jest.config.ts | 1 - ...project-graph-incremental-recomputation.ts | 49 ++-- packages/nx/src/devkit-exports.ts | 1 - .../generators/utils/project-configuration.ts | 9 +- .../update-15-1-0/set-project-names.ts | 3 +- .../project-json/build-nodes/project-json.ts | 4 +- .../affected/locators/project-glob-changes.ts | 1 - .../src/project-graph/build-project-graph.ts | 28 +- packages/nx/src/project-graph/file-utils.ts | 60 +++- .../utils/project-configuration-utils.spec.ts | 108 +++++++- .../utils/project-configuration-utils.ts | 262 +++++++++++------- .../utils/retrieve-workspace-files.spec.ts | 13 +- .../utils/retrieve-workspace-files.ts | 54 ++-- packages/nx/src/utils/nx-plugin.deprecated.ts | 35 +-- packages/nx/src/utils/nx-plugin.ts | 67 ++--- packages/plugin/jest.config.ts | 1 - packages/react-native/jest.config.ts | 1 - packages/react/jest.config.ts | 1 - packages/rollup/jest.config.ts | 1 - packages/storybook/jest.config.ts | 1 - packages/tao/jest.config.ts | 1 - packages/web/jest.config.ts | 1 - packages/webpack/jest.config.ts | 1 - packages/workspace/jest.config.ts | 1 - .../create-embeddings/jest.config.ts | 1 - tools/eslint-rules/jest.config.ts | 1 - tsconfig.base.json | 2 +- 58 files changed, 451 insertions(+), 318 deletions(-) delete mode 100644 docs/generated/devkit/CreateNodesAsync.md diff --git a/docs/generated/devkit/CreateNodesAsync.md b/docs/generated/devkit/CreateNodesAsync.md deleted file mode 100644 index 196a714ff7e10..0000000000000 --- a/docs/generated/devkit/CreateNodesAsync.md +++ /dev/null @@ -1,9 +0,0 @@ -# Type alias: CreateNodesAsync - -Ƭ **CreateNodesAsync**<`T`\>: readonly [projectFilePattern: string, createNodesFunction: CreateNodesFunctionAsync] - -#### Type parameters - -| Name | Type | -| :--- | :-------- | -| `T` | `unknown` | diff --git a/docs/generated/devkit/CreateNodesFunction.md b/docs/generated/devkit/CreateNodesFunction.md index 3f3df71e37667..f26253839cf9a 100644 --- a/docs/generated/devkit/CreateNodesFunction.md +++ b/docs/generated/devkit/CreateNodesFunction.md @@ -1,6 +1,6 @@ # Type alias: CreateNodesFunction -Ƭ **CreateNodesFunction**<`T`\>: (`projectConfigurationFile`: `string`, `options`: `T` \| `undefined`, `context`: [`CreateNodesContext`](../../devkit/documents/CreateNodesContext)) => [`CreateNodesResult`](../../devkit/documents/CreateNodesResult) +Ƭ **CreateNodesFunction**<`T`\>: (`projectConfigurationFile`: `string`, `options`: `T` \| `undefined`, `context`: [`CreateNodesContext`](../../devkit/documents/CreateNodesContext)) => [`CreateNodesResult`](../../devkit/documents/CreateNodesResult) \| `Promise`<[`CreateNodesResult`](../../devkit/documents/CreateNodesResult)\> #### Type parameters @@ -10,7 +10,7 @@ #### Type declaration -▸ (`projectConfigurationFile`, `options`, `context`): [`CreateNodesResult`](../../devkit/documents/CreateNodesResult) +▸ (`projectConfigurationFile`, `options`, `context`): [`CreateNodesResult`](../../devkit/documents/CreateNodesResult) \| `Promise`<[`CreateNodesResult`](../../devkit/documents/CreateNodesResult)\> A function which parses a configuration file into a set of nodes. Used for creating nodes for the [ProjectGraph](../../devkit/documents/ProjectGraph) @@ -25,4 +25,4 @@ Used for creating nodes for the [ProjectGraph](../../devkit/documents/ProjectGra ##### Returns -[`CreateNodesResult`](../../devkit/documents/CreateNodesResult) +[`CreateNodesResult`](../../devkit/documents/CreateNodesResult) \| `Promise`<[`CreateNodesResult`](../../devkit/documents/CreateNodesResult)\> diff --git a/docs/generated/devkit/NxPluginV2.md b/docs/generated/devkit/NxPluginV2.md index 092f88533ea3b..4d6d8ec7bb0f4 100644 --- a/docs/generated/devkit/NxPluginV2.md +++ b/docs/generated/devkit/NxPluginV2.md @@ -1,20 +1,19 @@ -# Type alias: NxPluginV2 +# Type alias: NxPluginV2 -Ƭ **NxPluginV2**<`TOptions`, `TCreateNodes`\>: `Object` +Ƭ **NxPluginV2**<`TOptions`\>: `Object` A plugin for Nx which creates nodes and dependencies for the [ProjectGraph](../../devkit/documents/ProjectGraph) #### Type parameters -| Name | Type | -| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `TOptions` | `unknown` | -| `TCreateNodes` | extends [`CreateNodes`](../../devkit/documents/CreateNodes)<`TOptions`\> \| [`CreateNodesAsync`](../../devkit/documents/CreateNodesAsync)<`TOptions`\> = [`CreateNodes`](../../devkit/documents/CreateNodes)<`TOptions`\> \| [`CreateNodesAsync`](../../devkit/documents/CreateNodesAsync)<`TOptions`\> | +| Name | Type | +| :--------- | :-------- | +| `TOptions` | `unknown` | #### Type declaration | Name | Type | Description | | :-------------------- | :----------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------- | | `createDependencies?` | [`CreateDependencies`](../../devkit/documents/CreateDependencies)<`TOptions`\> | Provides a function to analyze files to create dependencies for the [ProjectGraph](../../devkit/documents/ProjectGraph) | -| `createNodes?` | `TCreateNodes` | Provides a file pattern and function that retrieves configuration info from those files. e.g. { '\*_/_.csproj': buildProjectsFromCsProjFile } | +| `createNodes?` | [`CreateNodes`](../../devkit/documents/CreateNodes) | Provides a file pattern and function that retrieves configuration info from those files. e.g. { '\*_/_.csproj': buildProjectsFromCsProjFile } | | `name` | `string` | - | diff --git a/docs/generated/devkit/README.md b/docs/generated/devkit/README.md index c0ea2140cd8ca..889a8fe0332c7 100644 --- a/docs/generated/devkit/README.md +++ b/docs/generated/devkit/README.md @@ -65,7 +65,6 @@ It only uses language primitives and immutable objects - [CreateDependencies](../../devkit/documents/CreateDependencies) - [CreateNodes](../../devkit/documents/CreateNodes) -- [CreateNodesAsync](../../devkit/documents/CreateNodesAsync) - [CreateNodesFunction](../../devkit/documents/CreateNodesFunction) - [CustomHasher](../../devkit/documents/CustomHasher) - [DynamicDependency](../../devkit/documents/DynamicDependency) diff --git a/docs/generated/packages/devkit/documents/nx_devkit.md b/docs/generated/packages/devkit/documents/nx_devkit.md index c0ea2140cd8ca..889a8fe0332c7 100644 --- a/docs/generated/packages/devkit/documents/nx_devkit.md +++ b/docs/generated/packages/devkit/documents/nx_devkit.md @@ -65,7 +65,6 @@ It only uses language primitives and immutable objects - [CreateDependencies](../../devkit/documents/CreateDependencies) - [CreateNodes](../../devkit/documents/CreateNodes) -- [CreateNodesAsync](../../devkit/documents/CreateNodesAsync) - [CreateNodesFunction](../../devkit/documents/CreateNodesFunction) - [CustomHasher](../../devkit/documents/CustomHasher) - [DynamicDependency](../../devkit/documents/DynamicDependency) diff --git a/docs/shared/recipes/plugins/project-graph-plugins.md b/docs/shared/recipes/plugins/project-graph-plugins.md index a0c8788f48965..214814c659026 100644 --- a/docs/shared/recipes/plugins/project-graph-plugins.md +++ b/docs/shared/recipes/plugins/project-graph-plugins.md @@ -59,7 +59,7 @@ A simplified version of Nx's built-in `project.json` plugin is shown below, whic export const createNodes: CreateNodes = [ '**/project.json', (projectConfigurationFile: string, opts, context: CreateNodesContext) => { - const projectConfiguration = readJson(projectConfigurationFile); + const projectConfiguration = readJsonFile(projectConfigurationFile); const root = dirname(projectConfigurationFile); return { diff --git a/graph/client/tsconfig.app.json b/graph/client/tsconfig.app.json index 104fc453e36ff..d44e043c2d8d6 100644 --- a/graph/client/tsconfig.app.json +++ b/graph/client/tsconfig.app.json @@ -3,7 +3,7 @@ "compilerOptions": { "outDir": "../../dist/out-tsc", "types": ["node"], - "lib": ["DOM", "es2019"] + "lib": ["DOM", "es2022"] }, "files": [ "../../node_modules/@nx/react/typings/cssmodule.d.ts", diff --git a/jest.preset.js b/jest.preset.js index 6c33c1524f672..9b1922eca1ce4 100644 --- a/jest.preset.js +++ b/jest.preset.js @@ -13,4 +13,5 @@ module.exports = { moduleFileExtensions: ['ts', 'js', 'html'], coverageReporters: ['html'], maxWorkers: 1, + testEnvironment: 'node', }; diff --git a/nx-dev/models-document/jest.config.ts b/nx-dev/models-document/jest.config.ts index 9881939d1929d..4966b91e7b2ec 100644 --- a/nx-dev/models-document/jest.config.ts +++ b/nx-dev/models-document/jest.config.ts @@ -2,7 +2,6 @@ export default { displayName: 'nx-dev-models-document', globals: {}, - testEnvironment: 'node', transform: { '^.+\\.[tj]sx?$': [ 'ts-jest', diff --git a/nx-dev/models-menu/jest.config.ts b/nx-dev/models-menu/jest.config.ts index d25cbcfe0cce7..83a02ecd113bf 100644 --- a/nx-dev/models-menu/jest.config.ts +++ b/nx-dev/models-menu/jest.config.ts @@ -2,7 +2,6 @@ export default { displayName: 'nx-dev-models-menu', globals: {}, - testEnvironment: 'node', transform: { '^.+\\.[tj]sx?$': [ 'ts-jest', diff --git a/nx-dev/models-package/jest.config.ts b/nx-dev/models-package/jest.config.ts index 7644c6180df4f..8acd93a9a4488 100644 --- a/nx-dev/models-package/jest.config.ts +++ b/nx-dev/models-package/jest.config.ts @@ -2,7 +2,6 @@ export default { displayName: 'nx-dev-models-package', globals: {}, - testEnvironment: 'node', transform: { '^.+\\.[tj]sx?$': [ 'ts-jest', diff --git a/nx-dev/ui-sponsor-card/jest.config.ts b/nx-dev/ui-sponsor-card/jest.config.ts index d94d74125c553..7cd7571ed7deb 100644 --- a/nx-dev/ui-sponsor-card/jest.config.ts +++ b/nx-dev/ui-sponsor-card/jest.config.ts @@ -8,4 +8,5 @@ export default { coverageDirectory: '../../coverage/nx-dev/ui-sponsor-card', setupFilesAfterEnv: ['/test-setup.ts'], preset: '../../jest.preset.js', + testEnvironment: 'jsdom', }; diff --git a/nx-dev/util-ai/jest.config.ts b/nx-dev/util-ai/jest.config.ts index 4bcab610fa70c..1f5b94ac3f24a 100644 --- a/nx-dev/util-ai/jest.config.ts +++ b/nx-dev/util-ai/jest.config.ts @@ -2,7 +2,6 @@ export default { displayName: 'nx-dev-util-ai', preset: '../../jest.preset.js', - testEnvironment: 'node', transform: { '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], }, diff --git a/packages/angular/jest.config.ts b/packages/angular/jest.config.ts index d4110472c490e..50f9550706d89 100644 --- a/packages/angular/jest.config.ts +++ b/packages/angular/jest.config.ts @@ -6,7 +6,6 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'angular', - testEnvironment: 'node', preset: '../../jest.preset.js', setupFilesAfterEnv: ['/test-setup.ts'], }; diff --git a/packages/create-nx-plugin/jest.config.ts b/packages/create-nx-plugin/jest.config.ts index 4bc7fc0d25bd3..97243a45c9d5b 100644 --- a/packages/create-nx-plugin/jest.config.ts +++ b/packages/create-nx-plugin/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'create-nx-plugin', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/create-nx-workspace/jest.config.ts b/packages/create-nx-workspace/jest.config.ts index 332d93823095d..14ddf1ab92c00 100644 --- a/packages/create-nx-workspace/jest.config.ts +++ b/packages/create-nx-workspace/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'create-nx-workspace', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/cypress/jest.config.ts b/packages/cypress/jest.config.ts index a0137171cc56e..2603835b01b71 100644 --- a/packages/cypress/jest.config.ts +++ b/packages/cypress/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'cypress', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/cypress/src/migrations/update-17-2-0/add-nx-cypress-plugin.spec.ts b/packages/cypress/src/migrations/update-17-2-0/add-nx-cypress-plugin.spec.ts index 7d8d15967103c..26979c983990e 100644 --- a/packages/cypress/src/migrations/update-17-2-0/add-nx-cypress-plugin.spec.ts +++ b/packages/cypress/src/migrations/update-17-2-0/add-nx-cypress-plugin.spec.ts @@ -58,6 +58,7 @@ describe('add-nx-cypress-plugin migration', () => { }) ); updateProjectConfiguration(tree, 'e2e', { + name: 'e2e', root: 'e2e', targets: { e2e: { diff --git a/packages/detox/jest.config.ts b/packages/detox/jest.config.ts index 86cba287ef141..7a0b097302f92 100644 --- a/packages/detox/jest.config.ts +++ b/packages/detox/jest.config.ts @@ -6,7 +6,6 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'], globals: {}, displayName: 'react-native', - testEnvironment: 'node', verbose: true, preset: '../../jest.preset.js', }; diff --git a/packages/devkit/jest.config.ts b/packages/devkit/jest.config.ts index f3ac86d00561e..17d32278b2c3d 100644 --- a/packages/devkit/jest.config.ts +++ b/packages/devkit/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'cli', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts b/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts index 4a248f9106b86..dd135758ae144 100644 --- a/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts +++ b/packages/devkit/src/utils/replace-project-configuration-with-plugin.ts @@ -3,7 +3,7 @@ import type { TargetConfiguration, } from 'nx/src/config/workspace-json-project-json'; import type { Tree } from 'nx/src/generators/tree'; -import type { CreateNodes, CreateNodesAsync } from 'nx/src/utils/nx-plugin'; +import type { CreateNodes } from 'nx/src/utils/nx-plugin'; import { requireNx } from '../../nx'; const { readNxJson, @@ -19,7 +19,7 @@ export async function replaceProjectConfigurationsWithPlugin( tree: Tree, rootMappings: Map, pluginPath: string, - createNodes: CreateNodes | CreateNodesAsync, + createNodes: CreateNodes, pluginOptions: T ): Promise { const nxJson = readNxJson(tree); diff --git a/packages/esbuild/jest.config.ts b/packages/esbuild/jest.config.ts index 2c92e705875b8..36bb0d4e88ae9 100644 --- a/packages/esbuild/jest.config.ts +++ b/packages/esbuild/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'esbuild', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/eslint-plugin/jest.config.ts b/packages/eslint-plugin/jest.config.ts index 6a55cb70577d3..e0bc383fe7a59 100644 --- a/packages/eslint-plugin/jest.config.ts +++ b/packages/eslint-plugin/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'packages-eslint-plugin', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/eslint/jest.config.ts b/packages/eslint/jest.config.ts index d666bd199e136..d8ac6509f8c90 100644 --- a/packages/eslint/jest.config.ts +++ b/packages/eslint/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'eslint', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/expo/jest.config.ts b/packages/expo/jest.config.ts index 0b33ab26d660b..e90cf348aa036 100644 --- a/packages/expo/jest.config.ts +++ b/packages/expo/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'], globals: {}, displayName: 'expo', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/express/jest.config.ts b/packages/express/jest.config.ts index de96a24753788..63fc63b7128f3 100644 --- a/packages/express/jest.config.ts +++ b/packages/express/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'express', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/jest/jest.config.ts b/packages/jest/jest.config.ts index 33fbde4d7c80c..4178b986015d9 100644 --- a/packages/jest/jest.config.ts +++ b/packages/jest/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'jest', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/js/jest.config.ts b/packages/js/jest.config.ts index 352fa338bd54b..dfca5389c876a 100644 --- a/packages/js/jest.config.ts +++ b/packages/js/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'js', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/nest/jest.config.ts b/packages/nest/jest.config.ts index 7318736cb6116..8075e6159956b 100644 --- a/packages/nest/jest.config.ts +++ b/packages/nest/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'nest', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/next/jest.config.ts b/packages/next/jest.config.ts index fb2f7550a3632..2912c22a2d8a0 100644 --- a/packages/next/jest.config.ts +++ b/packages/next/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'next', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/node/jest.config.ts b/packages/node/jest.config.ts index e251e33d662d1..2f4b00f2cc897 100644 --- a/packages/node/jest.config.ts +++ b/packages/node/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'node', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/nx/jest.config.ts b/packages/nx/jest.config.ts index 93f60c3fb9b1a..26cb205652efd 100644 --- a/packages/nx/jest.config.ts +++ b/packages/nx/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'nx', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts b/packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts index aff990b841a26..206e96c0ad2ef 100644 --- a/packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts +++ b/packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts @@ -1,5 +1,5 @@ import { performance } from 'perf_hooks'; -import { readNxJson } from '../../config/nx-json'; +import { readNxJson, NxJsonConfiguration } from '../../config/nx-json'; import { FileData, FileMap, @@ -136,7 +136,10 @@ function computeWorkspaceConfigHash( return hashArray(projectConfigurationStrings); } -async function processCollectedUpdatedAndDeletedFiles() { +async function processCollectedUpdatedAndDeletedFiles( + projects: Record, + nxJson: NxJsonConfiguration +) { try { performance.mark('hash-watched-changes-start'); const updatedFiles = [...collectedUpdatedFiles.values()]; @@ -149,14 +152,7 @@ async function processCollectedUpdatedAndDeletedFiles() { 'hash-watched-changes-end' ); - const nxJson = readNxJson(workspaceRoot); - - const { projectNodes } = await retrieveProjectConfigurations( - workspaceRoot, - nxJson - ); - - const workspaceConfigHash = computeWorkspaceConfigHash(projectNodes); + const workspaceConfigHash = computeWorkspaceConfigHash(projects); serverLogger.requestLog( `Updated file-hasher based on watched changes, recomputing project graph...` ); @@ -172,7 +168,7 @@ async function processCollectedUpdatedAndDeletedFiles() { } else { if (fileMapWithFiles) { fileMapWithFiles = updateFileMap( - projectNodes, + projects, fileMapWithFiles.fileMap, fileMapWithFiles.allWorkspaceFiles, new Map(Object.entries(updatedFileHashes)), @@ -197,13 +193,24 @@ async function processCollectedUpdatedAndDeletedFiles() { `Error detected when recomputing project file map: ${e.message}` ); resetInternalState(); - return e; + throw e; } } async function processFilesAndCreateAndSerializeProjectGraph() { - const err = await processCollectedUpdatedAndDeletedFiles(); - if (err) { + try { + const nxJson = readNxJson(workspaceRoot); + const configResult = await retrieveProjectConfigurations( + workspaceRoot, + nxJson + ); + await processCollectedUpdatedAndDeletedFiles( + configResult.projectNodes, + nxJson + ); + writeSourceMaps(configResult.sourceMaps); + return createAndSerializeProjectGraph(configResult.projectNodes); + } catch (err) { return Promise.resolve({ error: err, projectGraph: null, @@ -211,8 +218,6 @@ async function processFilesAndCreateAndSerializeProjectGraph() { allWorkspaceFiles: null, serializedProjectGraph: null, }); - } else { - return createAndSerializeProjectGraph(); } } @@ -231,7 +236,9 @@ function copyFileMap(m: FileMap) { return c; } -async function createAndSerializeProjectGraph(): Promise<{ +async function createAndSerializeProjectGraph( + projects: Record +): Promise<{ error: string | null; projectGraph: ProjectGraph | null; fileMap: FileMap | null; @@ -240,15 +247,11 @@ async function createAndSerializeProjectGraph(): Promise<{ }> { try { performance.mark('create-project-graph-start'); - const projectConfigurations = await retrieveProjectConfigurations( - workspaceRoot, - readNxJson(workspaceRoot) - ); const fileMap = copyFileMap(fileMapWithFiles.fileMap); const allWorkspaceFiles = copyFileData(fileMapWithFiles.allWorkspaceFiles); const { projectGraph, projectFileMapCache } = await buildProjectGraphUsingFileMap( - projectConfigurations.projectNodes, + projects, knownExternalNodes, fileMap, allWorkspaceFiles, @@ -274,8 +277,6 @@ async function createAndSerializeProjectGraph(): Promise<{ 'json-stringify-end' ); - writeSourceMaps(projectConfigurations.sourceMaps); - return { error: null, projectGraph, diff --git a/packages/nx/src/devkit-exports.ts b/packages/nx/src/devkit-exports.ts index f4865db6ce66f..b7da714177f11 100644 --- a/packages/nx/src/devkit-exports.ts +++ b/packages/nx/src/devkit-exports.ts @@ -51,7 +51,6 @@ export type { NxPluginV2, ProjectTargetConfigurator, CreateNodes, - CreateNodesAsync, CreateNodesFunction, CreateNodesResult, CreateNodesContext, diff --git a/packages/nx/src/generators/utils/project-configuration.ts b/packages/nx/src/generators/utils/project-configuration.ts index 1d4af440c83f1..4a1af8e19f15f 100644 --- a/packages/nx/src/generators/utils/project-configuration.ts +++ b/packages/nx/src/generators/utils/project-configuration.ts @@ -5,6 +5,7 @@ import { getGlobPatternsFromPackageManagerWorkspaces, } from '../../../plugins/package-json-workspaces'; import { buildProjectFromProjectJson } from '../../plugins/project-json/build-nodes/project-json'; +import { getDefaultPluginsSync } from '../../utils/nx-plugin.deprecated'; import { renamePropertyWithStableKeys } from '../../adapter/angular-json'; import { ProjectConfiguration, @@ -14,7 +15,7 @@ import { mergeProjectConfigurationIntoRootMap, readProjectConfigurationsFromRootMap, } from '../../project-graph/utils/project-configuration-utils'; -import { retrieveProjectConfigurationPathsWithoutPluginInference } from '../../project-graph/utils/retrieve-workspace-files'; +import { retrieveProjectConfigurationPaths } from '../../project-graph/utils/retrieve-workspace-files'; import { output } from '../../utils/output'; import { PackageJson } from '../../utils/package-json'; import { joinPathFragments, normalizePath } from '../../utils/path'; @@ -191,9 +192,9 @@ function readAndCombineAllProjectConfigurations(tree: Tree): { readJson(tree, p) ), ]; - - const globbedFiles = retrieveProjectConfigurationPathsWithoutPluginInference( - tree.root + const globbedFiles = retrieveProjectConfigurationPaths( + tree.root, + getDefaultPluginsSync(tree.root) ); const createdFiles = findCreatedProjectFiles(tree, patterns); const deletedFiles = findDeletedProjectFiles(tree, patterns); diff --git a/packages/nx/src/migrations/update-15-1-0/set-project-names.ts b/packages/nx/src/migrations/update-15-1-0/set-project-names.ts index ec6665a2b2895..24c9e426ac331 100644 --- a/packages/nx/src/migrations/update-15-1-0/set-project-names.ts +++ b/packages/nx/src/migrations/update-15-1-0/set-project-names.ts @@ -4,12 +4,13 @@ import { dirname } from 'path'; import { readJson, writeJson } from '../../generators/utils/json'; import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available'; import { retrieveProjectConfigurationPaths } from '../../project-graph/utils/retrieve-workspace-files'; +import { loadNxPlugins } from '../../utils/nx-plugin'; export default async function (tree: Tree) { const nxJson = readNxJson(tree); const projectFiles = await retrieveProjectConfigurationPaths( tree.root, - nxJson + await loadNxPlugins(nxJson?.plugins) ); const projectJsons = projectFiles.filter((f) => f.endsWith('project.json')); diff --git a/packages/nx/src/plugins/project-json/build-nodes/project-json.ts b/packages/nx/src/plugins/project-json/build-nodes/project-json.ts index 3536326e3a1d6..bfaa8d03fe056 100644 --- a/packages/nx/src/plugins/project-json/build-nodes/project-json.ts +++ b/packages/nx/src/plugins/project-json/build-nodes/project-json.ts @@ -3,9 +3,9 @@ import { dirname, join } from 'node:path'; import { ProjectConfiguration } from '../../../config/workspace-json-project-json'; import { toProjectName } from '../../../config/workspaces'; import { readJsonFile } from '../../../utils/fileutils'; -import { CreateNodes, NxPluginV2 } from '../../../utils/nx-plugin'; +import { NxPluginV2 } from '../../../utils/nx-plugin'; -export const CreateProjectJsonProjectsPlugin: NxPluginV2 = { +export const CreateProjectJsonProjectsPlugin: NxPluginV2 = { name: 'nx-core-build-project-json-nodes', createNodes: [ '{project.json,**/project.json}', diff --git a/packages/nx/src/project-graph/affected/locators/project-glob-changes.ts b/packages/nx/src/project-graph/affected/locators/project-glob-changes.ts index 81dc8e94f418e..4ec255b206d2b 100644 --- a/packages/nx/src/project-graph/affected/locators/project-glob-changes.ts +++ b/packages/nx/src/project-graph/affected/locators/project-glob-changes.ts @@ -12,7 +12,6 @@ export const getTouchedProjectsFromProjectGlobChanges: TouchedProjectLocator = async (touchedFiles, projectGraphNodes, nxJson): Promise => { const globPattern = combineGlobPatterns( configurationGlobs( - workspaceRoot, await loadNxPlugins( nxJson?.plugins, getNxRequirePaths(workspaceRoot), diff --git a/packages/nx/src/project-graph/build-project-graph.ts b/packages/nx/src/project-graph/build-project-graph.ts index eddb5ffe767aa..91f99faba9f4e 100644 --- a/packages/nx/src/project-graph/build-project-graph.ts +++ b/packages/nx/src/project-graph/build-project-graph.ts @@ -33,6 +33,7 @@ import { readNxJson } from '../config/configuration'; import { existsSync } from 'fs'; import { PackageJson } from '../utils/package-json'; import { getNxRequirePaths } from '../utils/installation-directory'; +import { output } from '../utils/output'; let storedFileMap: FileMap | null = null; let storedAllWorkspaceFiles: FileData[] | null = null; @@ -244,13 +245,13 @@ async function updateProjectGraphWithPlugins( plugin.processProjectGraph && !plugin.createDependencies ) { - // TODO(@AgentEnder): Enable after rewriting nx-js-graph-plugin to v2 - // output.warn({ - // title: `${plugin.name} is a v1 plugin.`, - // bodyLines: [ - // 'Nx has recently released a v2 model for project graph plugins. The `processProjectGraph` method is deprecated. Plugins should use some combination of `createNodes` and `createDependencies` instead.', - // ], - // }); + output.warn({ + title: `${plugin.name} is a v1 plugin.`, + bodyLines: [ + 'Nx has recently released a v2 model for project graph plugins. The `processProjectGraph` method is deprecated. Plugins should use some combination of `createNodes` and `createDependencies` instead.', + ], + }); + performance.mark(`${plugin.name}:processProjectGraph - start`); graph = await plugin.processProjectGraph(graph, { ...context, projectsConfigurations: { @@ -265,6 +266,12 @@ async function updateProjectGraphWithPlugins( ...context.nxJsonConfiguration, }, }); + performance.mark(`${plugin.name}:processProjectGraph - end`); + performance.measure( + `${plugin.name}:processProjectGraph`, + `${plugin.name}:processProjectGraph - start`, + `${plugin.name}:processProjectGraph - end` + ); } } catch (e) { let message = `Failed to process the project graph with "${plugin.name}".`; @@ -287,6 +294,7 @@ async function updateProjectGraphWithPlugins( ); await Promise.all( createDependencyPlugins.map(async ({ plugin, options }) => { + performance.mark(`${plugin.name}:createDependencies - start`); try { const dependencies = await plugin.createDependencies(options, { ...context, @@ -308,6 +316,12 @@ async function updateProjectGraphWithPlugins( } throw new Error(message); } + performance.mark(`${plugin.name}:createDependencies - end`); + performance.measure( + `${plugin.name}:createDependencies`, + `${plugin.name}:createDependencies - start`, + `${plugin.name}:createDependencies - end` + ); }) ); return builder.getUpdatedProjectGraph(); diff --git a/packages/nx/src/project-graph/file-utils.ts b/packages/nx/src/project-graph/file-utils.ts index fd8e3447a9218..d1a11da2e610e 100644 --- a/packages/nx/src/project-graph/file-utils.ts +++ b/packages/nx/src/project-graph/file-utils.ts @@ -3,7 +3,10 @@ import { existsSync, readFileSync } from 'fs'; import { extname, join, relative, sep } from 'path'; import { readNxJson } from '../config/configuration'; import { FileData } from '../config/project-graph'; -import { ProjectsConfigurations } from '../config/workspace-json-project-json'; +import { + ProjectConfiguration, + ProjectsConfigurations, +} from '../config/workspace-json-project-json'; import type { NxArgs } from '../utils/command-line-utils'; import { workspaceRoot } from '../utils/workspace-root'; import { readJsonFile } from '../utils/fileutils'; @@ -14,10 +17,17 @@ import { } from './project-graph'; import { toOldFormat } from '../adapter/angular-json'; import { getIgnoreObject } from '../utils/ignore'; -import { retrieveProjectConfigurationPathsWithoutPluginInference } from './utils/retrieve-workspace-files'; -import { buildProjectsConfigurationsFromProjectPathsAndPlugins } from './utils/project-configuration-utils'; +import { retrieveProjectConfigurationPaths } from './utils/retrieve-workspace-files'; +import { + mergeProjectConfigurationIntoRootMap, + readProjectConfigurationsFromRootMap, +} from './utils/project-configuration-utils'; import { NxJsonConfiguration } from '../config/nx-json'; import { getDefaultPluginsSync } from '../utils/nx-plugin.deprecated'; +import minimatch = require('minimatch'); +import { CreateNodesResult } from '../devkit-exports'; +import { CreatePackageJsonProjectsNextToProjectJson } from '../plugins/project-json/build-nodes/package-json-next-to-project-json'; +import { LoadedNxPlugin } from '../utils/nx-plugin'; export interface Change { type: string; @@ -168,13 +178,45 @@ export { FileData }; // TODO(17): Remove these exports export { readNxJson, workspaceLayout } from '../config/configuration'; +/** + * TODO(v18): Remove this function. + */ function getProjectsSyncNoInference(root: string, nxJson: NxJsonConfiguration) { - const paths = retrieveProjectConfigurationPathsWithoutPluginInference(root); - return buildProjectsConfigurationsFromProjectPathsAndPlugins( - nxJson, - paths, - getDefaultPluginsSync(root), + const projectFiles = retrieveProjectConfigurationPaths( root, - true + getDefaultPluginsSync(root) ); + const plugins: LoadedNxPlugin[] = [ + { plugin: CreatePackageJsonProjectsNextToProjectJson }, + ...getDefaultPluginsSync(root), + ]; + + const projectRootMap: Map = new Map(); + + // We iterate over plugins first - this ensures that plugins specified first take precedence. + for (const { plugin, options } of plugins) { + const [pattern, createNodes] = plugin.createNodes ?? []; + if (!pattern) { + continue; + } + for (const file of projectFiles) { + if (minimatch(file, pattern, { dot: true })) { + let r = createNodes(file, options, { + nxJsonConfiguration: nxJson, + workspaceRoot: root, + }) as CreateNodesResult; + for (const node in r.projects) { + const project = { + root: node, + ...r.projects[node], + }; + mergeProjectConfigurationIntoRootMap(projectRootMap, project); + } + } + } + } + + return { + projects: readProjectConfigurationsFromRootMap(projectRootMap), + }; } diff --git a/packages/nx/src/project-graph/utils/project-configuration-utils.spec.ts b/packages/nx/src/project-graph/utils/project-configuration-utils.spec.ts index 8f01ed46d217b..dc7fa996dab4d 100644 --- a/packages/nx/src/project-graph/utils/project-configuration-utils.spec.ts +++ b/packages/nx/src/project-graph/utils/project-configuration-utils.spec.ts @@ -4,7 +4,7 @@ import { } from '../../config/workspace-json-project-json'; import { ConfigurationSourceMaps, - SourceInformation, + isCompatibleTarget, mergeProjectConfigurationIntoRootMap, mergeTargetConfigurations, readProjectConfigurationsFromRootMap, @@ -996,6 +996,112 @@ describe('project-configuration-utils', () => { `); }); }); + + describe('isCompatibleTarget', () => { + it('should return true if only one target specifies an executor', () => { + expect( + isCompatibleTarget( + { + executor: 'nx:run-commands', + }, + {} + ) + ).toBe(true); + }); + + it('should return true if both targets specify the same executor', () => { + expect( + isCompatibleTarget( + { + executor: 'nx:run-commands', + }, + { + executor: 'nx:run-commands', + } + ) + ).toBe(true); + }); + + it('should return false if both targets specify different executors', () => { + expect( + isCompatibleTarget( + { + executor: 'nx:run-commands', + }, + { + executor: 'other-executor', + } + ) + ).toBe(false); + }); + + it('should return true if both targets specify the same command', () => { + expect( + isCompatibleTarget( + { + command: 'echo', + }, + { + command: 'echo', + } + ) + ).toBe(true); + + expect( + isCompatibleTarget( + { + command: 'echo', + }, + { + executor: 'nx:run-commands', + options: { + command: 'echo', + }, + } + ) + ).toBe(true); + }); + + it('should return false if both targets specify different commands', () => { + expect( + isCompatibleTarget( + { + command: 'echo', + }, + { + command: 'echo2', + } + ) + ).toBe(false); + + expect( + isCompatibleTarget( + { + command: 'echo', + }, + { + executor: 'nx:run-commands', + options: { + command: 'echo2', + }, + } + ) + ).toBe(false); + }); + + it('should return false if one target specifies an executor and the other a command', () => { + expect( + isCompatibleTarget( + { + executor: 'nx:noop', + }, + { + command: 'echo', + } + ) + ).toBe(false); + }); + }); }); class RootMapBuilder { diff --git a/packages/nx/src/project-graph/utils/project-configuration-utils.ts b/packages/nx/src/project-graph/utils/project-configuration-utils.ts index 461c247ba6fe2..e54f600279c79 100644 --- a/packages/nx/src/project-graph/utils/project-configuration-utils.ts +++ b/packages/nx/src/project-graph/utils/project-configuration-utils.ts @@ -8,7 +8,6 @@ import { import { NX_PREFIX } from '../../utils/logger'; import { CreateNodesResult, LoadedNxPlugin } from '../../utils/nx-plugin'; import { workspaceRoot } from '../../utils/workspace-root'; -import { output } from '../../utils/output'; import minimatch = require('minimatch'); @@ -147,32 +146,13 @@ export function mergeProjectConfigurationIntoRootMap( ); } -type CreateNodesResultWithMetadata = { - result: CreateNodesResult | Promise; - pluginName: string; - file: string; -}; - -type ConfigurationResult = { +export type ConfigurationResult = { projects: Record; externalNodes: Record; rootMap: Record; sourceMaps: ConfigurationSourceMaps; }; -/** - * ** DO NOT USE ** - Please use without the `skipAsync` parameter. - * @deprecated - * @todo(@agentender): Remove in Nx 18 alongside the removal of its usage. - */ -export function buildProjectsConfigurationsFromProjectPathsAndPlugins( - nxJson: NxJsonConfiguration, - projectFiles: string[], // making this parameter allows devkit to pick up newly created projects - plugins: LoadedNxPlugin[], - root: string, - skipAsync: true -): ConfigurationResult; - /** * Transforms a list of project paths into a map of project configurations. * @@ -185,108 +165,144 @@ export function buildProjectsConfigurationsFromProjectPathsAndPlugins( nxJson: NxJsonConfiguration, projectFiles: string[], // making this parameter allows devkit to pick up newly created projects plugins: LoadedNxPlugin[], - root: string, - skipAsync?: false -): Promise; -export function buildProjectsConfigurationsFromProjectPathsAndPlugins( - nxJson: NxJsonConfiguration, - projectFiles: string[], // making this parameter allows devkit to pick up newly created projects - plugins: LoadedNxPlugin[], - root: string = workspaceRoot, - skipAsync: boolean = false -): ConfigurationResult | Promise { - const results: Array = []; + root: string = workspaceRoot +): Promise { + type CreateNodesResultWithContext = CreateNodesResult & { + file: string; + pluginName: string; + }; + + const results: Array>> = []; // We iterate over plugins first - this ensures that plugins specified first take precedence. for (const { plugin, options } of plugins) { const [pattern, createNodes] = plugin.createNodes ?? []; + const pluginResults: Array< + CreateNodesResultWithContext | Promise + > = []; + + performance.mark(`${plugin.name}:createNodes - start`); if (!pattern) { continue; } for (const file of projectFiles) { + performance.mark(`${plugin.name}:createNodes:${file} - start`); if (minimatch(file, pattern, { dot: true })) { - results.push({ - result: createNodes(file, options, { + try { + let r = createNodes(file, options, { nxJsonConfiguration: nxJson, workspaceRoot: root, - }), - pluginName: plugin.name, - file, - }); + }); + + if (r instanceof Promise) { + pluginResults.push( + r + .catch((e) => { + performance.mark(`${plugin.name}:createNodes:${file} - end`); + throw new CreateNodesError( + `Unable to create nodes for ${file} using plugin ${plugin.name}.`, + e + ); + }) + .then((r) => { + performance.mark(`${plugin.name}:createNodes:${file} - end`); + performance.measure( + `${plugin.name}:createNodes:${file}`, + `${plugin.name}:createNodes:${file} - start`, + `${plugin.name}:createNodes:${file} - end` + ); + return { ...r, file, pluginName: plugin.name }; + }) + ); + } else { + performance.mark(`${plugin.name}:createNodes:${file} - end`); + performance.measure( + `${plugin.name}:createNodes:${file}`, + `${plugin.name}:createNodes:${file} - start`, + `${plugin.name}:createNodes:${file} - end` + ); + pluginResults.push({ + ...r, + file, + pluginName: plugin.name, + }); + } + } catch (e) { + throw new CreateNodesError( + `Unable to create nodes for ${file} using plugin ${plugin.name}.`, + e + ); + } } } + // If there are no promises (counter undefined) or all promises have resolved (counter === 0) + results.push( + Promise.all(pluginResults).then((results) => { + performance.mark(`${plugin.name}:createNodes - end`); + performance.measure( + `${plugin.name}:createNodes`, + `${plugin.name}:createNodes - start`, + `${plugin.name}:createNodes - end` + ); + return results; + }) + ); } - return skipAsync - ? combineSyncConfigurationResults(results) - : combineAsyncConfigurationResults(results); -} - -function combineSyncConfigurationResults( - resultsWithMetadata: CreateNodesResultWithMetadata[] -): ConfigurationResult { - const projectRootMap: Map = new Map(); - const externalNodes: Record = {}; - const configurationSourceMaps: Record< - string, - Record - > = {}; - - let warned = false; - for (const { result, pluginName, file } of resultsWithMetadata) { - if (typeof result === 'object' && 'then' in result) { - if (!warned) { - output.warn({ - title: 'One or more plugins in this workspace are async.', - bodyLines: [ - 'Configuration from these plugins will not be visible to readWorkspaceConfig or readWorkspaceConfiguration. If you are using these methods, consider reading project info from the graph with createProjectGraphAsync instead.', - 'If you are not using one of these methods, please open an issue at http://github.com/nrwl/nx', - ], - }); - warned = true; - } - continue; - } - const { projects: projectNodes, externalNodes: pluginExternalNodes } = - result; - for (const node in projectNodes) { - mergeProjectConfigurationIntoRootMap( - projectRootMap, - { + return Promise.all(results).then((results) => { + performance.mark('createNodes:merge - start'); + const projectRootMap: Map = new Map(); + const externalNodes: Record = {}; + const configurationSourceMaps: Record< + string, + Record + > = {}; + + for (const result of results.flat()) { + const { + projects: projectNodes, + externalNodes: pluginExternalNodes, + file, + pluginName, + } = result; + for (const node in projectNodes) { + const project = { root: node, ...projectNodes[node], - }, - configurationSourceMaps, - [pluginName, file] - ); + }; + try { + mergeProjectConfigurationIntoRootMap( + projectRootMap, + project, + configurationSourceMaps, + [file, pluginName] + ); + } catch (e) { + throw new CreateNodesError( + `Unable to merge project information for "${project.root}" from ${result.file} using plugin ${result.pluginName}.`, + e + ); + } + } + Object.assign(externalNodes, pluginExternalNodes); } - Object.assign(externalNodes, pluginExternalNodes); - } - const rootMap = createRootMap(projectRootMap); + const rootMap = createRootMap(projectRootMap); - return { - projects: readProjectConfigurationsFromRootMap(projectRootMap), - externalNodes, - rootMap, - sourceMaps: configurationSourceMaps, - }; -} + performance.mark('createNodes:merge - end'); + performance.measure( + 'createNodes:merge', + 'createNodes:merge - start', + 'createNodes:merge - end' + ); -function combineAsyncConfigurationResults( - results: Array -): Promise { - return Promise.all( - results.map((resultWithMetadata) => - typeof resultWithMetadata.result === 'object' && - 'then' in resultWithMetadata.result - ? resultWithMetadata.result.then((resolvedResult) => ({ - ...resultWithMetadata, - result: resolvedResult, - })) - : resultWithMetadata - ) - ).then((r) => combineSyncConfigurationResults(r)); + return { + projects: readProjectConfigurationsFromRootMap(projectRootMap), + externalNodes, + rootMap, + sourceMaps: configurationSourceMaps, + }; + }); } export function readProjectConfigurationsFromRootMap( @@ -327,6 +343,23 @@ export function readProjectConfigurationsFromRootMap( return projects; } +class CreateNodesError extends Error { + constructor(msg, cause: Error | unknown) { + const message = `${msg} ${ + !cause + ? '' + : cause instanceof Error + ? `\n\n\t Inner Error: ${cause.stack}` + : cause + }`; + // These errors are thrown during a JS callback which is invoked via rust. + // The errors messaging gets lost in the rust -> js -> rust transition, but + // logging the error here will ensure that it is visible in the console. + console.error(message); + super(message, { cause }); + } +} + /** * Merges two targets. * @@ -417,8 +450,29 @@ export function mergeTargetConfigurations( * If the executors are both specified and don't match, the options aren't considered * "compatible" and shouldn't be merged. */ -function isCompatibleTarget(a: TargetConfiguration, b: TargetConfiguration) { - return !a.executor || !b.executor || a.executor === b.executor; +export function isCompatibleTarget( + a: TargetConfiguration, + b: TargetConfiguration +) { + if (a.command || b.command) { + const aCommand = + a.command ?? + (a.executor === 'nx:run-commands' ? a.options?.command : null); + const bCommand = + b.command ?? + (b.executor === 'nx:run-commands' ? b.options?.command : null); + + const sameCommand = aCommand === bCommand; + const aHasNoExecutor = !a.command && !a.executor; + const bHasNoExecutor = !b.command && !b.executor; + + return sameCommand || aHasNoExecutor || bHasNoExecutor; + } + + const oneHasNoExecutor = !a.executor || !b.executor; + const bothHaveSameExecutor = a.executor === b.executor; + + return oneHasNoExecutor || bothHaveSameExecutor; } function mergeConfigurations( diff --git a/packages/nx/src/project-graph/utils/retrieve-workspace-files.spec.ts b/packages/nx/src/project-graph/utils/retrieve-workspace-files.spec.ts index dac5b73750ec8..54eaa75de789a 100644 --- a/packages/nx/src/project-graph/utils/retrieve-workspace-files.spec.ts +++ b/packages/nx/src/project-graph/utils/retrieve-workspace-files.spec.ts @@ -1,3 +1,4 @@ +import { getDefaultPlugins } from '../../utils/nx-plugin'; import { TempFs } from '../../internal-testing-utils/temp-fs'; import { retrieveProjectConfigurationPaths } from './retrieve-workspace-files'; @@ -24,11 +25,13 @@ describe('retrieveProjectConfigurationPaths', () => { name: 'project-1', }) ); - expect( - await retrieveProjectConfigurationPaths(fs.tempDir, {}) - ).not.toContain('not-projects/project.json'); - expect(await retrieveProjectConfigurationPaths(fs.tempDir, {})).toContain( - 'projects/project.json' + + const configPaths = await retrieveProjectConfigurationPaths( + fs.tempDir, + await getDefaultPlugins(fs.tempDir) ); + + expect(configPaths).not.toContain('not-projects/project.json'); + expect(configPaths).toContain('projects/project.json'); }); }); diff --git a/packages/nx/src/project-graph/utils/retrieve-workspace-files.ts b/packages/nx/src/project-graph/utils/retrieve-workspace-files.ts index 79022df4db6f8..c1a4ad3fc7c6b 100644 --- a/packages/nx/src/project-graph/utils/retrieve-workspace-files.ts +++ b/packages/nx/src/project-graph/utils/retrieve-workspace-files.ts @@ -16,16 +16,16 @@ import { ProjectGraphExternalNode, } from '../../config/project-graph'; import type { NxWorkspaceFiles } from '../../native'; -import { - getGlobPatternsFromPackageManagerWorkspaces, - getNxPackageJsonWorkspacesPlugin, -} from '../../../plugins/package-json-workspaces'; +import { getNxPackageJsonWorkspacesPlugin } from '../../../plugins/package-json-workspaces'; import { ConfigurationSourceMaps, - SourceInformation, buildProjectsConfigurationsFromProjectPathsAndPlugins, } from './project-configuration-utils'; -import { LoadedNxPlugin, loadNxPlugins } from '../../utils/nx-plugin'; +import { + getDefaultPlugins, + LoadedNxPlugin, + loadNxPlugins, +} from '../../utils/nx-plugin'; import { CreateProjectJsonProjectsPlugin } from '../../plugins/project-json/build-nodes/project-json'; import { globWithWorkspaceContext, @@ -49,7 +49,7 @@ export async function retrieveWorkspaceFiles( getNxRequirePaths(workspaceRoot), workspaceRoot ); - let globs = configurationGlobs(workspaceRoot, plugins); + let globs = configurationGlobs(plugins); performance.mark('native-file-deps:end'); performance.measure( 'native-file-deps', @@ -122,7 +122,7 @@ export async function retrieveProjectConfigurations( workspaceRoot ); - const globs = configurationGlobs(workspaceRoot, plugins); + const globs = configurationGlobs(plugins); return _retrieveProjectConfigurations(workspaceRoot, nxJson, plugins, globs); } @@ -147,7 +147,7 @@ export async function retrieveProjectConfigurationsWithAngularProjects( plugins.push({ plugin: NxAngularJsonPlugin }); } - const globs = configurationGlobs(workspaceRoot, plugins); + const globs = configurationGlobs(plugins); return _retrieveProjectConfigurations(workspaceRoot, nxJson, plugins, globs); } @@ -189,21 +189,12 @@ function _retrieveProjectConfigurations( ).then(() => result); } -export async function retrieveProjectConfigurationPaths( +export function retrieveProjectConfigurationPaths( root: string, - nxJson: NxJsonConfiguration -): Promise { - const projectGlobPatterns = configurationGlobs( - root, - await loadNxPlugins(nxJson?.plugins ?? [], getNxRequirePaths(root), root) - ); - return globWithWorkspaceContext(root, projectGlobPatterns); -} - -export function retrieveProjectConfigurationPathsWithoutPluginInference( - root: string + plugins: LoadedNxPlugin[] ): string[] { - return globWithWorkspaceContext(root, configurationGlobsWithoutPlugins(root)); + const projectGlobPatterns = configurationGlobs(plugins); + return globWithWorkspaceContext(root, projectGlobPatterns); } const projectsWithoutPluginCache = new Map< @@ -216,7 +207,8 @@ export async function retrieveProjectConfigurationsWithoutPluginInference( root: string ): Promise> { const nxJson = readNxJson(root); - const projectGlobPatterns = configurationGlobsWithoutPlugins(root); + const plugins = await getDefaultPlugins(root); + const projectGlobPatterns = retrieveProjectConfigurationPaths(root, plugins); const cacheKey = root + ',' + projectGlobPatterns.join(','); if (projectsWithoutPluginCache.has(cacheKey)) { @@ -302,12 +294,8 @@ export async function createProjectConfigurations( }; } -export function configurationGlobs( - workspaceRoot: string, - plugins: LoadedNxPlugin[] -): string[] { - const globPatterns: string[] = - configurationGlobsWithoutPlugins(workspaceRoot); +export function configurationGlobs(plugins: LoadedNxPlugin[]): string[] { + const globPatterns = []; for (const { plugin } of plugins) { if (plugin.createNodes) { globPatterns.push(plugin.createNodes[0]); @@ -315,11 +303,3 @@ export function configurationGlobs( } return globPatterns; } - -function configurationGlobsWithoutPlugins(workspaceRoot: string): string[] { - return [ - 'project.json', - '**/project.json', - ...getGlobPatternsFromPackageManagerWorkspaces(workspaceRoot), - ]; -} diff --git a/packages/nx/src/utils/nx-plugin.deprecated.ts b/packages/nx/src/utils/nx-plugin.deprecated.ts index 0ad20d8ddb75b..3153f7d393300 100644 --- a/packages/nx/src/utils/nx-plugin.deprecated.ts +++ b/packages/nx/src/utils/nx-plugin.deprecated.ts @@ -1,25 +1,10 @@ import { getNxPackageJsonWorkspacesPlugin } from '../../plugins/package-json-workspaces'; -import { - NxAngularJsonPlugin, - shouldMergeAngularProjects, -} from '../adapter/angular-json'; -import { NxJsonConfiguration, PluginConfiguration } from '../config/nx-json'; +import { shouldMergeAngularProjects } from '../adapter/angular-json'; import { ProjectGraphProcessor } from '../config/project-graph'; -import { - ProjectConfiguration, - TargetConfiguration, -} from '../config/workspace-json-project-json'; +import { TargetConfiguration } from '../config/workspace-json-project-json'; +import { CreatePackageJsonProjectsNextToProjectJson } from '../plugins/project-json/build-nodes/package-json-next-to-project-json'; import { CreateProjectJsonProjectsPlugin } from '../plugins/project-json/build-nodes/project-json'; -import { retrieveProjectConfigurationsWithoutPluginInference } from '../project-graph/utils/retrieve-workspace-files'; -import { getNxRequirePaths } from './installation-directory'; -import { - ensurePluginIsV2, - getPluginPathAndName, - LoadedNxPlugin, - nxPluginCache, - NxPluginV2, -} from './nx-plugin'; -import { workspaceRoot } from './workspace-root'; +import { LoadedNxPlugin, NxPluginV2 } from './nx-plugin'; /** * @deprecated Add targets to the projects in a {@link CreateNodes} function instead. This will be removed in Nx 18 @@ -55,11 +40,15 @@ export type NxPluginV1 = { * @todo(@agentender) v18: Remove this fn when we remove readWorkspaceConfig */ export function getDefaultPluginsSync(root: string): LoadedNxPlugin[] { - const plugins: NxPluginV2[] = [require('../plugins/js')]; + const plugins: NxPluginV2[] = [ + require('../plugins/js'), + ...(shouldMergeAngularProjects(root, false) + ? [require('../adapter/angular-json').NxAngularJsonPlugin] + : []), + getNxPackageJsonWorkspacesPlugin(root), + CreateProjectJsonProjectsPlugin, + ]; - if (shouldMergeAngularProjects(root, false)) { - plugins.push(require('../adapter/angular-json').NxAngularJsonPlugin); - } return plugins.map((p) => ({ plugin: p, })); diff --git a/packages/nx/src/utils/nx-plugin.ts b/packages/nx/src/utils/nx-plugin.ts index c84f470c52047..503943fdddaf2 100644 --- a/packages/nx/src/utils/nx-plugin.ts +++ b/packages/nx/src/utils/nx-plugin.ts @@ -41,11 +41,6 @@ import { shouldMergeAngularProjects } from '../adapter/angular-json'; import { getNxPackageJsonWorkspacesPlugin } from '../../plugins/package-json-workspaces'; import { CreateProjectJsonProjectsPlugin } from '../plugins/project-json/build-nodes/project-json'; import { CreatePackageJsonProjectsNextToProjectJson } from '../plugins/project-json/build-nodes/package-json-next-to-project-json'; -import { - mergeProjectConfigurationIntoRootMap, - readProjectConfigurationsFromRootMap, -} from '../project-graph/utils/project-configuration-utils'; -import { globWithWorkspaceContext } from './workspace-context'; import { retrieveProjectConfigurationsWithoutPluginInference } from '../project-graph/utils/retrieve-workspace-files'; /** @@ -64,17 +59,7 @@ export type CreateNodesFunction = ( projectConfigurationFile: string, options: T | undefined, context: CreateNodesContext -) => CreateNodesResult; - -/** - * A function which parses a configuration file into a set of nodes. - * Used for creating nodes for the {@link ProjectGraph} - */ -export type CreateNodesFunctionAsync = ( - projectConfigurationFile: string, - options: T | undefined, - context: CreateNodesContext -) => Promise; +) => CreateNodesResult | Promise; export interface CreateNodesResult { /** @@ -96,11 +81,6 @@ export type CreateNodes = readonly [ createNodesFunction: CreateNodesFunction ]; -export type CreateNodesAsync = readonly [ - projectFilePattern: string, - createNodesFunction: CreateNodesFunctionAsync -]; - /** * Context for {@link CreateDependencies} */ @@ -145,19 +125,14 @@ export type CreateDependencies = ( /** * A plugin for Nx which creates nodes and dependencies for the {@link ProjectGraph} */ -export type NxPluginV2< - TOptions = unknown, - TCreateNodes extends CreateNodes | CreateNodesAsync = - | CreateNodes - | CreateNodesAsync -> = { +export type NxPluginV2 = { name: string; /** * Provides a file pattern and function that retrieves configuration info from * those files. e.g. { '**\/*.csproj': buildProjectsFromCsProjFile } */ - createNodes?: TCreateNodes; + createNodes?: CreateNodes; // Todo(@AgentEnder): This shouldn't be a full processor, since its only responsible for defining edges between projects. What do we want the API to be? /** @@ -248,7 +223,7 @@ export async function loadNxPluginAsync( if (pluginModule) { return { plugin: pluginModule, options }; } - + performance.mark(`Load Nx Plugin: ${moduleName} - start`); let { pluginPath, name } = await getPluginPathAndName( moduleName, paths, @@ -260,6 +235,12 @@ export async function loadNxPluginAsync( ); plugin.name ??= name; nxPluginCache.set(moduleName, plugin); + performance.mark(`Load Nx Plugin: ${moduleName} - end`); + performance.measure( + `Load Nx Plugin: ${moduleName}`, + `Load Nx Plugin: ${moduleName} - start`, + `Load Nx Plugin: ${moduleName} - end` + ); return { plugin, options }; } @@ -269,7 +250,9 @@ export async function loadNxPlugins( root = workspaceRoot, projects?: Record ): Promise { - const result: LoadedNxPlugin[] = [...(await getDefaultPlugins(root))]; + const result: LoadedNxPlugin[] = [ + { plugin: CreatePackageJsonProjectsNextToProjectJson }, + ]; // When loading plugins for `createNodes`, we don't know what projects exist yet. projects ??= await retrieveProjectConfigurationsWithoutPluginInference(root); @@ -281,10 +264,7 @@ export async function loadNxPlugins( } // We push the nx core node plugins onto the end, s.t. it overwrites any other plugins - result.push( - { plugin: getNxPackageJsonWorkspacesPlugin(root) }, - { plugin: CreateProjectJsonProjectsPlugin } - ); + result.push(...(await getDefaultPlugins(root))); return result; } @@ -515,17 +495,22 @@ function readPluginMainFromProjectConfiguration( return main; } -async function getDefaultPlugins(root: string): Promise { +export async function getDefaultPlugins( + root: string +): Promise { const plugins: NxPluginV2[] = [ - CreatePackageJsonProjectsNextToProjectJson, await import('../plugins/js'), + ...(shouldMergeAngularProjects(root, false) + ? [ + await import('../adapter/angular-json').then( + (m) => m.NxAngularJsonPlugin + ), + ] + : []), + getNxPackageJsonWorkspacesPlugin(root), + CreateProjectJsonProjectsPlugin, ]; - if (shouldMergeAngularProjects(root, false)) { - plugins.push( - await import('../adapter/angular-json').then((m) => m.NxAngularJsonPlugin) - ); - } return plugins.map((p) => ({ plugin: p, })); diff --git a/packages/plugin/jest.config.ts b/packages/plugin/jest.config.ts index 31d676606ac2b..811a082b8ee25 100644 --- a/packages/plugin/jest.config.ts +++ b/packages/plugin/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'plugin', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/react-native/jest.config.ts b/packages/react-native/jest.config.ts index 3c81720917b10..edb2c29019244 100644 --- a/packages/react-native/jest.config.ts +++ b/packages/react-native/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'], globals: {}, displayName: 'react-native', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/react/jest.config.ts b/packages/react/jest.config.ts index 729033215dbb1..0557ac98c315d 100644 --- a/packages/react/jest.config.ts +++ b/packages/react/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'react', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/rollup/jest.config.ts b/packages/rollup/jest.config.ts index fb152698c8cc4..5054e520b6fef 100644 --- a/packages/rollup/jest.config.ts +++ b/packages/rollup/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'rollup', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/storybook/jest.config.ts b/packages/storybook/jest.config.ts index 20a4f3a4aa70b..76d6fe103992c 100644 --- a/packages/storybook/jest.config.ts +++ b/packages/storybook/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'], globals: {}, displayName: 'storybook', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/tao/jest.config.ts b/packages/tao/jest.config.ts index 3ed0a25121a5b..9456db3fac009 100644 --- a/packages/tao/jest.config.ts +++ b/packages/tao/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'tao', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/web/jest.config.ts b/packages/web/jest.config.ts index e9babbf26d221..b363dde094d94 100644 --- a/packages/web/jest.config.ts +++ b/packages/web/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'web', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/webpack/jest.config.ts b/packages/webpack/jest.config.ts index 06a7246af7e5e..89fe896aae2ae 100644 --- a/packages/webpack/jest.config.ts +++ b/packages/webpack/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'webpack', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/packages/workspace/jest.config.ts b/packages/workspace/jest.config.ts index 6efad8d267ea1..4662c7ce616d4 100644 --- a/packages/workspace/jest.config.ts +++ b/packages/workspace/jest.config.ts @@ -6,6 +6,5 @@ export default { moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], globals: {}, displayName: 'workspace', - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/tools/documentation/create-embeddings/jest.config.ts b/tools/documentation/create-embeddings/jest.config.ts index fa82ea4a6317a..fc9460298f03e 100644 --- a/tools/documentation/create-embeddings/jest.config.ts +++ b/tools/documentation/create-embeddings/jest.config.ts @@ -2,7 +2,6 @@ export default { displayName: 'tools-documentation-create-embeddings', preset: './jest.preset.js', - testEnvironment: 'node', transform: { '^.+\\.(ts|tsx|js|jsx|mts|mjs)$': [ 'ts-jest', diff --git a/tools/eslint-rules/jest.config.ts b/tools/eslint-rules/jest.config.ts index a99e5a1c6e393..8322b63a2367e 100644 --- a/tools/eslint-rules/jest.config.ts +++ b/tools/eslint-rules/jest.config.ts @@ -12,6 +12,5 @@ export default { ], }, moduleFileExtensions: ['ts', 'js', 'html'], - testEnvironment: 'node', preset: '../../jest.preset.js', }; diff --git a/tsconfig.base.json b/tsconfig.base.json index 7657f7403c5f9..80c010fd6369a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -9,7 +9,7 @@ "emitDecoratorMetadata": true, "skipLibCheck": true, "types": ["node", "jest"], - "lib": ["ES2021"], + "lib": ["ES2022"], "declaration": true, "resolveJsonModule": true, "baseUrl": ".",