nx 20.2.0-canary.20241203-6b87005 → 20.2.0-canary.20241205-15060e3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/bin/post-install.js +5 -3
  2. package/package.json +11 -11
  3. package/plugins/package-json.d.ts +5 -1
  4. package/plugins/package-json.js +26 -2
  5. package/src/command-line/affected/affected.js +3 -1
  6. package/src/command-line/format/format.js +4 -2
  7. package/src/command-line/release/utils/github.d.ts +1 -0
  8. package/src/command-line/release/utils/github.js +2 -0
  9. package/src/command-line/show/project.js +4 -0
  10. package/src/command-line/show/projects.js +4 -0
  11. package/src/command-line/sync/sync.js +3 -3
  12. package/src/core/graph/main.js +1 -1
  13. package/src/core/graph/styles.js +1 -1
  14. package/src/daemon/server/project-graph-incremental-recomputation.js +4 -4
  15. package/src/daemon/server/shutdown-utils.js +2 -2
  16. package/src/executors/utils/convert-nx-executor.js +2 -3
  17. package/src/native/nx.wasm32-wasi.wasm +0 -0
  18. package/src/plugins/package-json/create-nodes.d.ts +3 -4
  19. package/src/plugins/package-json/create-nodes.js +19 -2
  20. package/src/project-graph/affected/affected-project-graph.js +3 -0
  21. package/src/project-graph/affected/locators/project-glob-changes.js +16 -4
  22. package/src/project-graph/build-project-graph.d.ts +1 -0
  23. package/src/project-graph/build-project-graph.js +12 -3
  24. package/src/project-graph/error-types.d.ts +1 -1
  25. package/src/project-graph/plugins/get-plugins.d.ts +4 -0
  26. package/src/project-graph/plugins/get-plugins.js +56 -0
  27. package/src/project-graph/plugins/index.js +1 -0
  28. package/src/project-graph/plugins/internal-api.d.ts +4 -0
  29. package/src/project-graph/plugins/internal-api.js +14 -7
  30. package/src/project-graph/plugins/isolation/index.js +1 -7
  31. package/src/project-graph/plugins/isolation/messaging.d.ts +3 -0
  32. package/src/project-graph/plugins/isolation/plugin-pool.js +5 -1
  33. package/src/project-graph/plugins/isolation/plugin-worker.js +9 -4
  34. package/src/project-graph/plugins/load-resolved-plugin.d.ts +3 -0
  35. package/src/project-graph/plugins/load-resolved-plugin.js +19 -0
  36. package/src/project-graph/plugins/loader.d.ts +7 -1
  37. package/src/project-graph/plugins/loader.js +22 -34
  38. package/src/project-graph/project-graph.js +19 -11
  39. package/src/project-graph/utils/retrieve-workspace-files.d.ts +2 -6
  40. package/src/project-graph/utils/retrieve-workspace-files.js +3 -5
  41. package/src/tasks-runner/run-command.js +2 -2
  42. package/src/utils/sync-generators.js +9 -14
  43. package/src/daemon/server/plugins.d.ts +0 -3
  44. package/src/daemon/server/plugins.js +0 -32
@@ -7,6 +7,7 @@ exports.resolveLocalNxPlugin = resolveLocalNxPlugin;
7
7
  exports.registerPluginTSTranspiler = registerPluginTSTranspiler;
8
8
  exports.getPluginPathAndName = getPluginPathAndName;
9
9
  exports.loadNxPlugin = loadNxPlugin;
10
+ exports.resolveNxPlugin = resolveNxPlugin;
10
11
  exports.loadNxPluginAsync = loadNxPluginAsync;
11
12
  const posix_1 = require("node:path/posix");
12
13
  const installation_directory_1 = require("../../utils/installation-directory");
@@ -20,10 +21,10 @@ const path_1 = require("../../utils/path");
20
21
  const logger_1 = require("../../utils/logger");
21
22
  const node_path_1 = require("node:path");
22
23
  const retrieve_workspace_files_1 = require("../utils/retrieve-workspace-files");
23
- const internal_api_1 = require("./internal-api");
24
24
  const error_types_1 = require("../error-types");
25
25
  const path = require("node:path/posix");
26
26
  const typescript_1 = require("../../plugins/js/utils/typescript");
27
+ const load_resolved_plugin_1 = require("./load-resolved-plugin");
27
28
  function readPluginPackageJson(pluginName, projects, paths = (0, installation_directory_1.getNxRequirePaths)()) {
28
29
  try {
29
30
  const result = (0, package_json_1.readModulePackageJsonWithoutFallbacks)(pluginName, paths);
@@ -138,19 +139,19 @@ function readPluginMainFromProjectConfiguration(plugin) {
138
139
  }
139
140
  function getPluginPathAndName(moduleName, paths, projects, root) {
140
141
  let pluginPath;
141
- let registerTSTranspiler = false;
142
+ let shouldRegisterTSTranspiler = false;
142
143
  try {
143
144
  pluginPath = require.resolve(moduleName, {
144
145
  paths,
145
146
  });
146
147
  const extension = path.extname(pluginPath);
147
- registerTSTranspiler = extension === '.ts';
148
+ shouldRegisterTSTranspiler = extension === '.ts';
148
149
  }
149
150
  catch (e) {
150
151
  if (e.code === 'MODULE_NOT_FOUND') {
151
152
  const plugin = resolveLocalNxPlugin(moduleName, projects, root);
152
153
  if (plugin) {
153
- registerTSTranspiler = true;
154
+ shouldRegisterTSTranspiler = true;
154
155
  const main = readPluginMainFromProjectConfiguration(plugin.projectConfig);
155
156
  pluginPath = main ? path.join(root, main) : plugin.path;
156
157
  }
@@ -164,16 +165,11 @@ function getPluginPathAndName(moduleName, paths, projects, root) {
164
165
  }
165
166
  }
166
167
  const packageJsonPath = path.join(pluginPath, 'package.json');
167
- // Register the ts-transpiler if we are pointing to a
168
- // plain ts file that's not part of a plugin project
169
- if (registerTSTranspiler) {
170
- registerPluginTSTranspiler();
171
- }
172
168
  const { name } = !['.ts', '.js'].some((x) => (0, node_path_1.extname)(moduleName) === x) && // Not trying to point to a ts or js file
173
169
  (0, node_fs_1.existsSync)(packageJsonPath) // plugin has a package.json
174
170
  ? (0, fileutils_1.readJsonFile)(packageJsonPath) // read name from package.json
175
171
  : { name: moduleName };
176
- return { pluginPath, name };
172
+ return { pluginPath, name, shouldRegisterTSTranspiler };
177
173
  }
178
174
  let projectsWithoutInference;
179
175
  function loadNxPlugin(plugin, root) {
@@ -182,38 +178,30 @@ function loadNxPlugin(plugin, root) {
182
178
  () => { },
183
179
  ];
184
180
  }
181
+ async function resolveNxPlugin(moduleName, root, paths) {
182
+ try {
183
+ require.resolve(moduleName);
184
+ }
185
+ catch {
186
+ // If a plugin cannot be resolved, we will need projects to resolve it
187
+ projectsWithoutInference ??=
188
+ await (0, retrieve_workspace_files_1.retrieveProjectConfigurationsWithoutPluginInference)(root);
189
+ }
190
+ const { pluginPath, name, shouldRegisterTSTranspiler } = getPluginPathAndName(moduleName, paths, projectsWithoutInference, root);
191
+ return { pluginPath, name, shouldRegisterTSTranspiler };
192
+ }
185
193
  async function loadNxPluginAsync(pluginConfiguration, paths, root) {
186
194
  const moduleName = typeof pluginConfiguration === 'string'
187
195
  ? pluginConfiguration
188
196
  : pluginConfiguration.plugin;
189
197
  try {
190
- try {
191
- require.resolve(moduleName);
192
- }
193
- catch {
194
- // If a plugin cannot be resolved, we will need projects to resolve it
195
- projectsWithoutInference ??=
196
- await (0, retrieve_workspace_files_1.retrieveProjectConfigurationsWithoutPluginInference)(root);
198
+ const { pluginPath, name, shouldRegisterTSTranspiler } = await resolveNxPlugin(moduleName, root, paths);
199
+ if (shouldRegisterTSTranspiler) {
200
+ registerPluginTSTranspiler();
197
201
  }
198
- performance.mark(`Load Nx Plugin: ${moduleName} - start`);
199
- const { pluginPath, name } = getPluginPathAndName(moduleName, paths, projectsWithoutInference, root);
200
- const plugin = await importPluginModule(pluginPath);
201
- plugin.name ??= name;
202
- performance.mark(`Load Nx Plugin: ${moduleName} - end`);
203
- performance.measure(`Load Nx Plugin: ${moduleName}`, `Load Nx Plugin: ${moduleName} - start`, `Load Nx Plugin: ${moduleName} - end`);
204
- return new internal_api_1.LoadedNxPlugin(plugin, pluginConfiguration);
202
+ return (0, load_resolved_plugin_1.loadResolvedNxPluginAsync)(pluginConfiguration, pluginPath, name);
205
203
  }
206
204
  catch (e) {
207
205
  throw new error_types_1.LoadPluginError(moduleName, e);
208
206
  }
209
207
  }
210
- async function importPluginModule(pluginPath) {
211
- const m = await Promise.resolve(`${pluginPath}`).then(s => require(s));
212
- if (m.default &&
213
- ('createNodes' in m.default ||
214
- 'createNodesV2' in m.default ||
215
- 'createDependencies' in m.default)) {
216
- return m.default;
217
- }
218
- return m;
219
- }
@@ -18,8 +18,9 @@ const workspace_root_1 = require("../utils/workspace-root");
18
18
  const build_project_graph_1 = require("./build-project-graph");
19
19
  const error_types_1 = require("./error-types");
20
20
  const nx_deps_cache_1 = require("./nx-deps-cache");
21
- const internal_api_1 = require("./plugins/internal-api");
22
21
  const retrieve_workspace_files_1 = require("./utils/retrieve-workspace-files");
22
+ const get_plugins_1 = require("./plugins/get-plugins");
23
+ const logger_1 = require("../utils/logger");
23
24
  /**
24
25
  * Synchronously reads the latest cached copy of the workspace's ProjectGraph.
25
26
  * @throws {Error} if there is no cached ProjectGraph to read from
@@ -75,7 +76,7 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
75
76
  perf_hooks_1.performance.mark('retrieve-project-configurations:start');
76
77
  let configurationResult;
77
78
  let projectConfigurationsError;
78
- const [plugins, cleanup] = await (0, internal_api_1.loadNxPlugins)(nxJson.plugins);
79
+ const plugins = await (0, get_plugins_1.getPlugins)();
79
80
  try {
80
81
  configurationResult = await (0, retrieve_workspace_files_1.retrieveProjectConfigurations)(plugins, workspace_root_1.workspaceRoot, nxJson);
81
82
  }
@@ -112,15 +113,6 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
112
113
  throw e;
113
114
  }
114
115
  }
115
- finally {
116
- // When plugins are isolated we don't clean them up during
117
- // a single run of the CLI. They are cleaned up when the CLI
118
- // process exits. Cleaning them here could cause issues if pending
119
- // promises are not resolved.
120
- if (process.env.NX_ISOLATE_PLUGINS !== 'true') {
121
- cleanup();
122
- }
123
- }
124
116
  const { projectGraph, projectFileMapCache } = projectGraphResult;
125
117
  perf_hooks_1.performance.mark('build-project-graph-using-project-file-map:end');
126
118
  delete global.NX_GRAPH_CREATION;
@@ -195,6 +187,22 @@ async function createProjectGraphAsync(opts = {
195
187
  exitOnError: false,
196
188
  resetDaemonClient: false,
197
189
  }) {
190
+ if (process.env.NX_FORCE_REUSE_CACHED_GRAPH === 'true') {
191
+ try {
192
+ const graph = readCachedProjectGraph();
193
+ const projectRootMap = Object.fromEntries(Object.entries(graph.nodes).map(([project, { data }]) => [
194
+ data.root,
195
+ project,
196
+ ]));
197
+ const { allWorkspaceFiles, fileMap, rustReferences } = await (0, retrieve_workspace_files_1.retrieveWorkspaceFiles)(workspace_root_1.workspaceRoot, projectRootMap);
198
+ (0, build_project_graph_1.hydrateFileMap)(fileMap, allWorkspaceFiles, rustReferences);
199
+ return graph;
200
+ // If no cached graph is found, we will fall through to the normal flow
201
+ }
202
+ catch (e) {
203
+ logger_1.logger.verbose('Unable to use cached project graph', e);
204
+ }
205
+ }
198
206
  const projectGraphAndSourceMaps = await createProjectGraphAndSourceMapsAsync(opts);
199
207
  return projectGraphAndSourceMaps.projectGraph;
200
208
  }
@@ -21,10 +21,6 @@ export declare function retrieveWorkspaceFiles(workspaceRoot: string, projectRoo
21
21
  */
22
22
  export declare function retrieveProjectConfigurations(plugins: LoadedNxPlugin[], workspaceRoot: string, nxJson: NxJsonConfiguration): Promise<ConfigurationResult>;
23
23
  export declare function retrieveProjectConfigurationsWithAngularProjects(workspaceRoot: string, nxJson: NxJsonConfiguration): Promise<ConfigurationResult>;
24
- export declare function retrieveProjectConfigurationPaths(root: string, plugins: Array<{
25
- createNodes?: readonly [string, ...unknown[]];
26
- } & unknown>): Promise<string[]>;
24
+ export declare function retrieveProjectConfigurationPaths(root: string, plugins: Array<LoadedNxPlugin>): Promise<string[]>;
27
25
  export declare function retrieveProjectConfigurationsWithoutPluginInference(root: string): Promise<Record<string, ProjectConfiguration>>;
28
- export declare function configurationGlobs(plugins: Array<{
29
- createNodes?: readonly [string, ...unknown[]];
30
- }>): string[];
26
+ export declare function configurationGlobs(plugins: Array<LoadedNxPlugin>): string[];
@@ -10,10 +10,10 @@ const perf_hooks_1 = require("perf_hooks");
10
10
  const angular_json_1 = require("../../adapter/angular-json");
11
11
  const nx_json_1 = require("../../config/nx-json");
12
12
  const project_configuration_utils_1 = require("./project-configuration-utils");
13
- const internal_api_1 = require("../plugins/internal-api");
14
13
  const workspace_context_1 = require("../../utils/workspace-context");
15
14
  const build_all_workspace_files_1 = require("./build-all-workspace-files");
16
15
  const path_1 = require("path");
16
+ const get_plugins_1 = require("../plugins/get-plugins");
17
17
  /**
18
18
  * Walks the workspace directory to create the `projectFileMap`, `ProjectConfigurations` and `allWorkspaceFiles`
19
19
  * @throws
@@ -52,9 +52,8 @@ async function retrieveProjectConfigurationsWithAngularProjects(workspaceRoot, n
52
52
  (typeof p === 'object' && p.plugin === angular_json_1.NX_ANGULAR_JSON_PLUGIN_NAME))) {
53
53
  pluginsToLoad.push((0, path_1.join)(__dirname, '../../adapter/angular-json'));
54
54
  }
55
- const [plugins, cleanup] = await (0, internal_api_1.loadNxPlugins)(nxJson?.plugins ?? [], workspaceRoot);
55
+ const plugins = await (0, get_plugins_1.getPlugins)();
56
56
  const res = await retrieveProjectConfigurations(plugins, workspaceRoot, nxJson);
57
- cleanup();
58
57
  return res;
59
58
  }
60
59
  function retrieveProjectConfigurationPaths(root, plugins) {
@@ -65,7 +64,7 @@ const projectsWithoutPluginCache = new Map();
65
64
  // TODO: This function is called way too often, it should be optimized without this cache
66
65
  async function retrieveProjectConfigurationsWithoutPluginInference(root) {
67
66
  const nxJson = (0, nx_json_1.readNxJson)(root);
68
- const [plugins, cleanup] = await (0, internal_api_1.loadNxPlugins)([]); // only load default plugins
67
+ const plugins = await (0, get_plugins_1.getOnlyDefaultPlugins)(); // only load default plugins
69
68
  const projectGlobPatterns = await retrieveProjectConfigurationPaths(root, plugins);
70
69
  const cacheKey = root + ',' + projectGlobPatterns.join(',');
71
70
  if (projectsWithoutPluginCache.has(cacheKey)) {
@@ -74,7 +73,6 @@ async function retrieveProjectConfigurationsWithoutPluginInference(root) {
74
73
  const projectFiles = (await (0, workspace_context_1.globWithWorkspaceContext)(root, projectGlobPatterns)) ?? [];
75
74
  const { projects } = await (0, project_configuration_utils_1.createProjectConfigurations)(root, nxJson, projectFiles, plugins);
76
75
  projectsWithoutPluginCache.set(cacheKey, projects);
77
- cleanup();
78
76
  return projects;
79
77
  }
80
78
  function configurationGlobs(plugins) {
@@ -149,8 +149,8 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
149
149
  const failedSyncGeneratorsFixMessageLines = (0, sync_generators_1.getFailedSyncGeneratorsFixMessageLines)(results, nxArgs.verbose);
150
150
  const outOfSyncTitle = 'The workspace is out of sync';
151
151
  const resultBodyLines = (0, sync_generators_1.getSyncGeneratorSuccessResultsMessageLines)(results);
152
- const fixMessage = 'You can manually run `nx sync` to update your workspace with the identified changes or you can set `sync.applyChanges` to `true` in your `nx.json` to apply the changes automatically when running tasks in interactive environments.';
153
- const willErrorOnCiMessage = 'Please note that having the workspace out of sync will result in an error in CI.';
152
+ const fixMessage = 'Make sure to run `nx sync` to apply the identified changes or set `sync.applyChanges` to `true` in your `nx.json` to apply them automatically when running tasks in interactive environments.';
153
+ const willErrorOnCiMessage = 'This will result in an error in CI.';
154
154
  if ((0, is_ci_1.isCI)() || !process.stdout.isTTY) {
155
155
  // If the user is running in CI or is running in a non-TTY environment we
156
156
  // throw an error to stop the execution of the tasks.
@@ -145,10 +145,7 @@ function getSyncGeneratorSuccessResultsMessageLines(results) {
145
145
  if ('error' in result) {
146
146
  continue;
147
147
  }
148
- messageLines.push(`The ${chalk.bold(result.generatorName)} sync generator identified ${chalk.bold(result.changes.length)} file${result.changes.length === 1 ? '' : 's'} in the workspace that ${result.changes.length === 1 ? 'is' : 'are'} out of sync${result.outOfSyncMessage ? ':' : '.'}`);
149
- if (result.outOfSyncMessage) {
150
- messageLines.push(result.outOfSyncMessage);
151
- }
148
+ messageLines.push(`[${chalk.bold(result.generatorName)}]: ${result.outOfSyncMessage ?? `Some files are out of sync.`}`);
152
149
  }
153
150
  return messageLines;
154
151
  }
@@ -159,11 +156,11 @@ function getFailedSyncGeneratorsFixMessageLines(results, verbose, globalGenerato
159
156
  let isFirst = true;
160
157
  for (const result of results) {
161
158
  if ('error' in result) {
162
- if (!isFirst) {
159
+ if (!isFirst && verbose) {
163
160
  messageLines.push('');
164
161
  }
165
162
  isFirst = false;
166
- messageLines.push(`The ${chalk.bold(result.generatorName)} sync generator reported the following error:`, '', errorToString(result.error, verbose));
163
+ messageLines.push(`[${chalk.bold(result.generatorName)}]: ${errorToString(result.error, verbose)}`);
167
164
  if (globalGeneratorSet.has(result.generatorName)) {
168
165
  globalGenerators.push(result.generatorName);
169
166
  }
@@ -181,11 +178,11 @@ function getFlushFailureMessageLines(result, verbose, globalGeneratorSet = new S
181
178
  const taskGenerators = [];
182
179
  let isFirst = true;
183
180
  for (const failure of result.generatorFailures) {
184
- if (!isFirst) {
181
+ if (!isFirst && verbose) {
185
182
  messageLines.push('');
186
183
  }
187
184
  isFirst = false;
188
- messageLines.push(`The ${chalk.bold(failure.generator)} sync generator failed to apply its changes with the following error:`, '', errorToString(failure.error, verbose));
185
+ messageLines.push(`[${chalk.bold(failure.generator)}]: ${errorToString(failure.error, verbose)}`);
189
186
  if (globalGeneratorSet.has(failure.generator)) {
190
187
  globalGenerators.push(failure.generator);
191
188
  }
@@ -205,13 +202,11 @@ function getFlushFailureMessageLines(result, verbose, globalGeneratorSet = new S
205
202
  messageLines.push(...[
206
203
  '',
207
204
  result.generalFailure.message,
208
- ...(verbose && !!result.generalFailure.stack
205
+ ...(!!result.generalFailure.stack
209
206
  ? [`\n${result.generalFailure.stack}`]
210
207
  : []),
211
208
  '',
212
- verbose
213
- ? 'Please report the error at: https://github.com/nrwl/nx/issues/new/choose'
214
- : 'Please run with `--verbose` and report the error at: https://github.com/nrwl/nx/issues/new/choose',
209
+ 'Please report the error at: https://github.com/nrwl/nx/issues/new/choose',
215
210
  ]);
216
211
  }
217
212
  return messageLines;
@@ -329,7 +324,7 @@ function getFailedSyncGeneratorsMessageLines(taskGenerators, globalGenerators, v
329
324
  }
330
325
  function errorToString(error, verbose) {
331
326
  if (error.title) {
332
- let message = ` ${chalk.red(error.title)}`;
327
+ let message = `${chalk.red(error.title)}`;
333
328
  if (error.bodyLines?.length) {
334
329
  message += `
335
330
 
@@ -339,7 +334,7 @@ function errorToString(error, verbose) {
339
334
  return message;
340
335
  }
341
336
  }
342
- return ` ${chalk.red(error.message)}${verbose && error.stack ? '\n ' + error.stack : ''}`;
337
+ return `${chalk.red(error.message)}${verbose && error.stack ? '\n ' + error.stack : ''}`;
343
338
  }
344
339
  function toSerializableError(error) {
345
340
  return error instanceof SyncError
@@ -1,3 +0,0 @@
1
- import { LoadedNxPlugin } from '../../project-graph/plugins/internal-api';
2
- export declare function getPlugins(): Promise<LoadedNxPlugin[]>;
3
- export declare function cleanupPlugins(): void;
@@ -1,32 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPlugins = getPlugins;
4
- exports.cleanupPlugins = cleanupPlugins;
5
- const file_hasher_1 = require("../../hasher/file-hasher");
6
- const nx_json_1 = require("../../config/nx-json");
7
- const internal_api_1 = require("../../project-graph/plugins/internal-api");
8
- const workspace_root_1 = require("../../utils/workspace-root");
9
- let currentPluginsConfigurationHash;
10
- let loadedPlugins;
11
- let cleanup;
12
- async function getPlugins() {
13
- const pluginsConfiguration = (0, nx_json_1.readNxJson)().plugins ?? [];
14
- const pluginsConfigurationHash = (0, file_hasher_1.hashObject)(pluginsConfiguration);
15
- // If the plugins configuration has not changed, reuse the current plugins
16
- if (loadedPlugins &&
17
- pluginsConfigurationHash === currentPluginsConfigurationHash) {
18
- return loadedPlugins;
19
- }
20
- // Cleanup current plugins before loading new ones
21
- if (cleanup) {
22
- cleanup();
23
- }
24
- currentPluginsConfigurationHash = pluginsConfigurationHash;
25
- const [result, cleanupFn] = await (0, internal_api_1.loadNxPlugins)(pluginsConfiguration, workspace_root_1.workspaceRoot);
26
- cleanup = cleanupFn;
27
- loadedPlugins = result;
28
- return result;
29
- }
30
- function cleanupPlugins() {
31
- cleanup();
32
- }