@nx/js 16.6.0-beta.3 → 16.6.0-beta.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/js",
3
- "version": "16.6.0-beta.3",
3
+ "version": "16.6.0-beta.5",
4
4
  "private": false,
5
5
  "description": "The JS plugin for Nx contains executors and generators that provide the best experience for developing JavaScript and TypeScript projects. ",
6
6
  "repository": {
@@ -32,16 +32,16 @@
32
32
  "executors": "./executors.json",
33
33
  "builders": "./executors.json",
34
34
  "dependencies": {
35
- "@babel/core": "^7.15.0",
36
- "@babel/plugin-proposal-class-properties": "^7.14.5",
37
- "@babel/plugin-proposal-decorators": "^7.14.5",
38
- "@babel/plugin-transform-runtime": "^7.15.0",
39
- "@babel/preset-env": "^7.15.0",
40
- "@babel/preset-typescript": "^7.15.0",
41
- "@babel/runtime": "^7.14.8",
42
- "@nrwl/js": "16.6.0-beta.3",
43
- "@nx/devkit": "16.6.0-beta.3",
44
- "@nx/workspace": "16.6.0-beta.3",
35
+ "@babel/core": "^7.22.9",
36
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
37
+ "@babel/plugin-proposal-decorators": "^7.22.7",
38
+ "@babel/plugin-transform-runtime": "^7.22.9",
39
+ "@babel/preset-env": "^7.22.9",
40
+ "@babel/preset-typescript": "^7.22.5",
41
+ "@babel/runtime": "^7.22.6",
42
+ "@nrwl/js": "16.6.0-beta.5",
43
+ "@nx/devkit": "16.6.0-beta.5",
44
+ "@nx/workspace": "16.6.0-beta.5",
45
45
  "@phenomnomnominal/tsquery": "~5.0.1",
46
46
  "babel-plugin-const-enum": "^1.0.1",
47
47
  "babel-plugin-macros": "^2.8.0",
@@ -71,5 +71,5 @@
71
71
  "access": "public"
72
72
  },
73
73
  "types": "./src/index.d.ts",
74
- "gitHead": "cd8c61d7a3b8ab9bc7bab068f5ca49bbf14abbf5"
74
+ "gitHead": "aab868aa0c30949832fe2c4b9cb109c204442e39"
75
75
  }
@@ -32,6 +32,11 @@ function nodeExecutor(options, context) {
32
32
  throw new Error(`Cannot find build target ${chalk.bold(options.buildTarget)} for project ${chalk.bold(context.projectName)}`);
33
33
  }
34
34
  const buildTargetExecutor = (_c = project.data.targets[buildTarget.target]) === null || _c === void 0 ? void 0 : _c.executor;
35
+ if (buildTargetExecutor === 'nx:run-commands' ||
36
+ buildTargetExecutor === '@nrwl/workspace:run-commands') {
37
+ // Run commands does not emit build event, so we have to switch to run entire build through Nx CLI.
38
+ options.runBuildTargetDependencies = true;
39
+ }
35
40
  const buildOptions = Object.assign(Object.assign({}, (0, devkit_1.readTargetOptions)(buildTarget, context)), options.buildTargetOptions);
36
41
  if (options.waitUntilTargets && options.waitUntilTargets.length > 0) {
37
42
  const results = yield tslib_1.__await(runWaitUntilTargets(options, context));
@@ -44,8 +49,9 @@ function nodeExecutor(options, context) {
44
49
  // Re-map buildable workspace projects to their output directory.
45
50
  const mappings = calculateResolveMappings(context, options);
46
51
  const fileToRun = getFileToRun(context, project, buildOptions, buildTargetExecutor);
47
- const tasks = [];
52
+ let additionalExitHandler = null;
48
53
  let currentTask = null;
54
+ const tasks = [];
49
55
  yield tslib_1.__await(yield* tslib_1.__asyncDelegator(tslib_1.__asyncValues((0, async_iterable_1.createAsyncIterable)(({ done, next, error }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
50
56
  var _e;
51
57
  const processQueue = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
@@ -58,59 +64,22 @@ function nodeExecutor(options, context) {
58
64
  yield task.start();
59
65
  });
60
66
  const debouncedProcessQueue = debounce(processQueue, (_e = options.debounce) !== null && _e !== void 0 ? _e : 1000);
61
- const addToQueue = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
67
+ const addToQueue = (childProcess, buildResult) => tslib_1.__awaiter(this, void 0, void 0, function* () {
62
68
  const task = {
63
69
  id: (0, crypto_1.randomUUID)(),
64
70
  killed: false,
65
- childProcess: null,
71
+ childProcess,
66
72
  promise: null,
67
73
  start: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
68
- if (options.runBuildTargetDependencies) {
69
- // If task dependencies are to be run, then we need to run through CLI since `runExecutor` doesn't support it.
70
- task.promise = new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
71
- task.childProcess = (0, child_process_1.fork)(require.resolve('nx'), [
72
- 'run',
73
- `${context.projectName}:${buildTarget.target}${buildTarget.configuration
74
- ? `:${buildTarget.configuration}`
75
- : ''}`,
76
- ], {
77
- cwd: context.root,
78
- stdio: 'inherit',
79
- });
80
- task.childProcess.once('exit', (code) => {
81
- if (code === 0)
82
- resolve();
83
- else
84
- reject();
85
- });
86
- }));
87
- }
88
- else {
89
- const output = yield (0, devkit_1.runExecutor)(buildTarget, Object.assign(Object.assign({}, options.buildTargetOptions), { watch: false }), context);
90
- task.promise = new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
91
- var _g;
92
- let error = false;
93
- let event;
94
- do {
95
- event = yield output.next();
96
- if (((_g = event.value) === null || _g === void 0 ? void 0 : _g.success) === false) {
97
- error = true;
98
- }
99
- } while (!event.done);
100
- if (error)
101
- reject();
102
- else
103
- resolve();
104
- }));
105
- }
106
74
  // Wait for build to finish.
107
- try {
108
- yield task.promise;
109
- }
110
- catch (_f) {
75
+ const result = yield buildResult;
76
+ if (!result.success) {
111
77
  // If in watch-mode, don't throw or else the process exits.
112
78
  if (options.watch) {
113
- devkit_1.logger.error(`Build failed, waiting for changes to restart...`);
79
+ if (!task.killed) {
80
+ // Only log build error if task was not killed by a new change.
81
+ devkit_1.logger.error(`Build failed, waiting for changes to restart...`);
82
+ }
114
83
  return;
115
84
  }
116
85
  else {
@@ -160,55 +129,88 @@ function nodeExecutor(options, context) {
160
129
  try {
161
130
  yield task.promise;
162
131
  }
163
- catch (_h) {
132
+ catch (_f) {
164
133
  // Doesn't matter if task fails, we just need to wait until it finishes.
165
134
  }
166
135
  }),
167
136
  };
168
137
  tasks.push(task);
169
138
  });
170
- if (options.watch) {
171
- const stopWatch = yield client_1.daemonClient.registerFileWatcher({
139
+ if (options.runBuildTargetDependencies) {
140
+ // If a all dependencies need to be rebuild on changes, then register with watcher
141
+ // and run through CLI, otherwise only the current project will rebuild.
142
+ const runBuild = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
143
+ let childProcess = null;
144
+ const whenReady = new Promise((resolve) => tslib_1.__awaiter(this, void 0, void 0, function* () {
145
+ childProcess = (0, child_process_1.fork)(require.resolve('nx'), [
146
+ 'run',
147
+ `${context.projectName}:${buildTarget.target}${buildTarget.configuration ? `:${buildTarget.configuration}` : ''}`,
148
+ ], {
149
+ cwd: context.root,
150
+ stdio: 'inherit',
151
+ });
152
+ childProcess.once('exit', (code) => {
153
+ if (code === 0)
154
+ resolve({ success: true });
155
+ // If process is killed due to current task being killed, then resolve with success.
156
+ else
157
+ resolve({ success: !!(currentTask === null || currentTask === void 0 ? void 0 : currentTask.killed) });
158
+ });
159
+ }));
160
+ yield addToQueue(childProcess, whenReady);
161
+ yield debouncedProcessQueue();
162
+ });
163
+ additionalExitHandler = yield client_1.daemonClient.registerFileWatcher({
172
164
  watchProjects: [context.projectName],
173
165
  includeDependentProjects: true,
174
166
  }, (err, data) => tslib_1.__awaiter(this, void 0, void 0, function* () {
175
- var _j;
167
+ var _g;
176
168
  if (err === 'closed') {
177
169
  devkit_1.logger.error(`Watch error: Daemon closed the connection`);
178
170
  process.exit(1);
179
171
  }
180
172
  else if (err) {
181
- devkit_1.logger.error(`Watch error: ${(_j = err === null || err === void 0 ? void 0 : err.message) !== null && _j !== void 0 ? _j : 'Unknown'}`);
173
+ devkit_1.logger.error(`Watch error: ${(_g = err === null || err === void 0 ? void 0 : err.message) !== null && _g !== void 0 ? _g : 'Unknown'}`);
182
174
  }
183
175
  else {
184
176
  devkit_1.logger.info(`NX File change detected. Restarting...`);
185
- yield addToQueue();
186
- yield debouncedProcessQueue();
177
+ yield runBuild();
187
178
  }
188
179
  }));
189
- const stopAllTasks = (signal = 'SIGTERM') => {
190
- for (const task of tasks) {
191
- task.stop(signal);
180
+ yield runBuild(); // run first build
181
+ }
182
+ else {
183
+ // Otherwise, run the build executor, which will not run task dependencies.
184
+ // This is mostly fine for bundlers like webpack that should already watch for dependency libs.
185
+ // For tsc/swc or custom build commands, consider using `runBuildTargetDependencies` instead.
186
+ const output = yield (0, devkit_1.runExecutor)(buildTarget, Object.assign(Object.assign({}, options.buildTargetOptions), { watch: options.watch }), context);
187
+ while (true) {
188
+ const event = yield output.next();
189
+ yield addToQueue(null, Promise.resolve(event.value));
190
+ yield debouncedProcessQueue();
191
+ if (event.done || !options.watch) {
192
+ break;
192
193
  }
193
- };
194
- process.on('SIGTERM', () => tslib_1.__awaiter(this, void 0, void 0, function* () {
195
- stopWatch();
196
- stopAllTasks('SIGTERM');
197
- process.exit(128 + 15);
198
- }));
199
- process.on('SIGINT', () => tslib_1.__awaiter(this, void 0, void 0, function* () {
200
- stopWatch();
201
- stopAllTasks('SIGINT');
202
- process.exit(128 + 2);
203
- }));
204
- process.on('SIGHUP', () => tslib_1.__awaiter(this, void 0, void 0, function* () {
205
- stopWatch();
206
- stopAllTasks('SIGHUP');
207
- process.exit(128 + 1);
208
- }));
194
+ }
209
195
  }
210
- yield addToQueue();
211
- yield processQueue();
196
+ const stopAllTasks = (signal = 'SIGTERM') => {
197
+ additionalExitHandler === null || additionalExitHandler === void 0 ? void 0 : additionalExitHandler();
198
+ for (const task of tasks) {
199
+ task.stop(signal);
200
+ }
201
+ };
202
+ process.on('SIGTERM', () => tslib_1.__awaiter(this, void 0, void 0, function* () {
203
+ stopAllTasks('SIGTERM');
204
+ process.exit(128 + 15);
205
+ }));
206
+ process.on('SIGINT', () => tslib_1.__awaiter(this, void 0, void 0, function* () {
207
+ stopAllTasks('SIGINT');
208
+ process.exit(128 + 2);
209
+ }));
210
+ process.on('SIGHUP', () => tslib_1.__awaiter(this, void 0, void 0, function* () {
211
+ stopAllTasks('SIGHUP');
212
+ process.exit(128 + 1);
213
+ }));
212
214
  })))));
213
215
  });
214
216
  }
@@ -227,7 +229,7 @@ function getExecArgv(options) {
227
229
  }
228
230
  function calculateResolveMappings(context, options) {
229
231
  const parsed = (0, devkit_1.parseTargetString)(options.buildTarget, context.projectGraph);
230
- const { dependencies } = (0, buildable_libs_utils_1.calculateProjectDependencies)(context.projectGraph, context.root, parsed.project, parsed.target, parsed.configuration);
232
+ const { dependencies } = (0, buildable_libs_utils_1.calculateProjectBuildableDependencies)(context.taskGraph, context.projectGraph, context.root, parsed.project, parsed.target, parsed.configuration);
231
233
  return dependencies.reduce((m, c) => {
232
234
  if (c.node.type !== 'npm' && c.outputs[0] != null) {
233
235
  m[c.name] = (0, devkit_1.joinPathFragments)(context.root, c.outputs[0]);
@@ -251,6 +253,13 @@ function runWaitUntilTargets(options, context) {
251
253
  })));
252
254
  }
253
255
  function getFileToRun(context, project, buildOptions, buildTargetExecutor) {
256
+ // If using run-commands or another custom executor, then user should set
257
+ // outputFileName, but we can try the default value that we use.
258
+ if (!(buildOptions === null || buildOptions === void 0 ? void 0 : buildOptions.outputPath) && !(buildOptions === null || buildOptions === void 0 ? void 0 : buildOptions.outputFileName)) {
259
+ const fallbackFile = path.join('dist', project.data.root, 'main.js');
260
+ devkit_1.logger.warn(`Build option ${chalk.bold('outputFileName')} not set for ${chalk.bold(project.name)}. Using fallback value of ${chalk.bold(fallbackFile)}.`);
261
+ return (0, path_1.join)(context.root, fallbackFile);
262
+ }
254
263
  let outputFileName = buildOptions.outputFileName;
255
264
  if (!outputFileName) {
256
265
  const fileName = `${path.parse(buildOptions.main).name}.js`;
@@ -45,7 +45,7 @@ function createTaskInfo(taskName, taskOptions, context, tsConfig) {
45
45
  outputDir: taskOptions.outputPath,
46
46
  assets: taskOptions.assets,
47
47
  });
48
- const { target: projectGraphNode, dependencies: buildableProjectNodeDependencies, } = (0, buildable_libs_utils_1.calculateProjectDependencies)(context.projectGraph, context.root, context.taskGraph.tasks[taskName].target.project, context.taskGraph.tasks[taskName].target.target, context.taskGraph.tasks[taskName].target.configuration);
48
+ const { target: projectGraphNode, dependencies: buildableProjectNodeDependencies, } = (0, buildable_libs_utils_1.calculateProjectBuildableDependencies)(context.taskGraph, context.projectGraph, context.root, context.taskGraph.tasks[taskName].target.project, context.taskGraph.tasks[taskName].target.target, context.taskGraph.tasks[taskName].target.configuration);
49
49
  return {
50
50
  task: taskName,
51
51
  options: taskOptions,
@@ -77,6 +77,9 @@ function projectGenerator(tree, schema, destinationDir, filesDir) {
77
77
  (0, devkit_1.joinPathFragments)(options.projectRoot, './src', 'index.' + (options.js ? 'js' : 'ts')),
78
78
  ]);
79
79
  }
80
+ if (options.bundler !== 'none') {
81
+ addBundlerDependencies(tree, options);
82
+ }
80
83
  if (!options.skipFormat) {
81
84
  yield (0, devkit_1.formatFiles)(tree);
82
85
  }
@@ -110,10 +113,12 @@ function addProject(tree, options, destinationDir) {
110
113
  };
111
114
  if (options.bundler === 'esbuild') {
112
115
  projectConfiguration.targets.build.options.generatePackageJson = true;
116
+ projectConfiguration.targets.build.options.format = ['cjs'];
113
117
  }
114
118
  if (options.bundler === 'rollup') {
115
119
  projectConfiguration.targets.build.options.project = `${options.projectRoot}/package.json`;
116
120
  projectConfiguration.targets.build.options.compiler = 'swc';
121
+ projectConfiguration.targets.build.options.format = ['cjs', 'esm'];
117
122
  }
118
123
  if (options.bundler === 'swc' && options.skipTypeCheck) {
119
124
  projectConfiguration.targets.build.options.skipTypeCheck = true;
@@ -163,6 +168,17 @@ function addLint(tree, options) {
163
168
  });
164
169
  }
165
170
  exports.addLint = addLint;
171
+ function addBundlerDependencies(tree, options) {
172
+ (0, devkit_1.updateJson)(tree, `${options.projectRoot}/package.json`, (json) => {
173
+ if (options.bundler === 'tsc') {
174
+ json.dependencies = Object.assign(Object.assign({}, json.dependencies), { tslib: versions_1.tsLibVersion });
175
+ }
176
+ else if (options.bundler === 'swc') {
177
+ json.dependencies = Object.assign(Object.assign({}, json.dependencies), { '@swc/helpers': versions_1.swcHelpersVersion });
178
+ }
179
+ return json;
180
+ });
181
+ }
166
182
  function updateTsConfig(tree, options) {
167
183
  (0, devkit_1.updateJson)(tree, (0, path_1.join)(options.projectRoot, 'tsconfig.json'), (json) => {
168
184
  if (options.strict) {
@@ -203,20 +219,15 @@ function createFiles(tree, options, filesDir) {
203
219
  (0, devkit_1.updateJson)(tree, packageJsonPath, (json) => {
204
220
  json.name = options.importPath;
205
221
  json.version = '0.0.1';
206
- json.type = 'commonjs';
207
222
  // If the package is publishable, we should remove the private field.
208
223
  if (json.private && options.publishable) {
209
224
  delete json.private;
210
225
  }
211
- return json;
226
+ return Object.assign(Object.assign(Object.assign({}, json), { dependencies: Object.assign(Object.assign({}, json.dependencies), determineDependencies(options)) }), determineEntryFields(options));
212
227
  });
213
228
  }
214
229
  else {
215
- (0, devkit_1.writeJson)(tree, packageJsonPath, {
216
- name: options.importPath,
217
- version: '0.0.1',
218
- type: 'commonjs',
219
- });
230
+ (0, devkit_1.writeJson)(tree, packageJsonPath, Object.assign({ name: options.importPath, version: '0.0.1', dependencies: determineDependencies(options) }, determineEntryFields(options)));
220
231
  }
221
232
  if (options.config === 'npm-scripts') {
222
233
  (0, devkit_1.updateJson)(tree, packageJsonPath, (json) => {
@@ -412,5 +423,68 @@ function createProjectTsConfigJson(tree, options) {
412
423
  };
413
424
  (0, devkit_1.writeJson)(tree, (0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.json'), tsconfig);
414
425
  }
426
+ function determineDependencies(options) {
427
+ switch (options.bundler) {
428
+ case 'tsc':
429
+ // importHelpers is true by default, so need to add tslib as a dependency.
430
+ return {
431
+ tslib: versions_1.tsLibVersion,
432
+ };
433
+ case 'swc':
434
+ // externalHelpers is true by default, so need to add swc helpers as a dependency.
435
+ return {
436
+ '@swc/helpers': versions_1.swcHelpersVersion,
437
+ };
438
+ default: {
439
+ // In other cases (vite, rollup, esbuild), helpers are bundled so no need to add them as a dependency.
440
+ return {};
441
+ }
442
+ }
443
+ }
444
+ function determineEntryFields(options) {
445
+ switch (options.bundler) {
446
+ case 'tsc':
447
+ return {
448
+ type: 'commonjs',
449
+ main: './src/index.js',
450
+ typings: './src/index.d.ts',
451
+ };
452
+ case 'swc':
453
+ return {
454
+ type: 'commonjs',
455
+ main: './src/index.js',
456
+ typings: './src/index.d.ts',
457
+ };
458
+ case 'rollup':
459
+ return {
460
+ type: 'commonjs',
461
+ main: './index.cjs',
462
+ module: './index.js',
463
+ // typings is missing for rollup currently
464
+ };
465
+ case 'vite':
466
+ return {
467
+ // Since we're publishing both formats, skip the type field.
468
+ // Bundlers or Node will determine the entry point to use.
469
+ main: './index.js',
470
+ module: './index.mjs',
471
+ typings: './index.d.ts',
472
+ };
473
+ case 'esbuild':
474
+ // For libraries intended for Node, use CJS.
475
+ return {
476
+ type: 'commonjs',
477
+ main: './index.cjs',
478
+ // typings is missing for esbuild currently
479
+ };
480
+ default: {
481
+ return {
482
+ // CJS is the safest optional for now due to lack of support from some packages
483
+ // also setting `type: module` results in different resolution behavior (e.g. import 'foo' no longer resolves to 'foo/index.js')
484
+ type: 'commonjs',
485
+ };
486
+ }
487
+ }
488
+ }
415
489
  exports.default = libraryGenerator;
416
490
  exports.librarySchematic = (0, devkit_1.convertNxGenerator)(libraryGenerator);
@@ -1,17 +1,28 @@
1
- import type { ProjectGraph, ProjectGraphProjectNode } from '@nx/devkit';
2
- import { ProjectGraphExternalNode } from '@nx/devkit';
1
+ import type { ProjectGraph, ProjectGraphExternalNode, ProjectGraphProjectNode, TaskGraph } from '@nx/devkit';
3
2
  import type * as ts from 'typescript';
4
3
  export type DependentBuildableProjectNode = {
5
4
  name: string;
6
5
  outputs: string[];
7
6
  node: ProjectGraphProjectNode | ProjectGraphExternalNode;
8
7
  };
8
+ export declare function calculateProjectBuildableDependencies(taskGraph: TaskGraph | undefined, projGraph: ProjectGraph, root: string, projectName: string, targetName: string, configurationName: string, shallow?: boolean): {
9
+ target: ProjectGraphProjectNode;
10
+ dependencies: DependentBuildableProjectNode[];
11
+ nonBuildableDependencies: string[];
12
+ topLevelDependencies: DependentBuildableProjectNode[];
13
+ };
9
14
  export declare function calculateProjectDependencies(projGraph: ProjectGraph, root: string, projectName: string, targetName: string, configurationName: string, shallow?: boolean): {
10
15
  target: ProjectGraphProjectNode;
11
16
  dependencies: DependentBuildableProjectNode[];
12
17
  nonBuildableDependencies: string[];
13
18
  topLevelDependencies: DependentBuildableProjectNode[];
14
19
  };
20
+ export declare function calculateDependenciesFromTaskGraph(taskGraph: TaskGraph, projectGraph: ProjectGraph, root: string, projectName: string, targetName: string, configurationName: string, shallow?: boolean): {
21
+ target: ProjectGraphProjectNode;
22
+ dependencies: DependentBuildableProjectNode[];
23
+ nonBuildableDependencies: string[];
24
+ topLevelDependencies: DependentBuildableProjectNode[];
25
+ };
15
26
  /**
16
27
  * Util function to create tsconfig compilerOptions object with support for workspace libs paths.
17
28
  *
@@ -1,19 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateBuildableProjectPackageJsonDependencies = exports.updatePaths = exports.findMissingBuildDependencies = exports.checkDependentProjectsHaveBeenBuilt = exports.createTmpTsConfig = exports.computeCompilerOptionsPaths = exports.calculateProjectDependencies = void 0;
4
- const path_1 = require("path");
5
- const fileutils_1 = require("nx/src/utils/fileutils");
3
+ exports.updateBuildableProjectPackageJsonDependencies = exports.updatePaths = exports.findMissingBuildDependencies = exports.checkDependentProjectsHaveBeenBuilt = exports.createTmpTsConfig = exports.computeCompilerOptionsPaths = exports.calculateDependenciesFromTaskGraph = exports.calculateProjectDependencies = exports.calculateProjectBuildableDependencies = void 0;
6
4
  const devkit_1 = require("@nx/devkit");
7
5
  const fs_1 = require("fs");
8
- const output_1 = require("nx/src/utils/output");
9
6
  const operators_1 = require("nx/src/project-graph/operators");
7
+ const fileutils_1 = require("nx/src/utils/fileutils");
8
+ const output_1 = require("nx/src/utils/output");
9
+ const path_1 = require("path");
10
10
  const ts_config_1 = require("./typescript/ts-config");
11
- let tsModule;
12
11
  function isBuildable(target, node) {
13
12
  return (node.data.targets &&
14
13
  node.data.targets[target] &&
15
14
  node.data.targets[target].executor !== '');
16
15
  }
16
+ function calculateProjectBuildableDependencies(taskGraph, projGraph, root, projectName, targetName, configurationName, shallow) {
17
+ if (process.env.NX_BUILDABLE_LIBRARIES_TASK_GRAPH === 'true' && taskGraph) {
18
+ return calculateDependenciesFromTaskGraph(taskGraph, projGraph, root, projectName, targetName, configurationName, shallow);
19
+ }
20
+ return calculateProjectDependencies(projGraph, root, projectName, targetName, configurationName, shallow);
21
+ }
22
+ exports.calculateProjectBuildableDependencies = calculateProjectBuildableDependencies;
17
23
  function calculateProjectDependencies(projGraph, root, projectName, targetName, configurationName, shallow) {
18
24
  const target = projGraph.nodes[projectName];
19
25
  // gather the library dependencies
@@ -108,6 +114,101 @@ function readTsConfigWithRemappedPaths(tsConfig, generatedTsConfigPath, dependen
108
114
  }
109
115
  return generatedTsConfig;
110
116
  }
117
+ function calculateDependenciesFromTaskGraph(taskGraph, projectGraph, root, projectName, targetName, configurationName, shallow) {
118
+ var _a;
119
+ const target = projectGraph.nodes[projectName];
120
+ const nonBuildableDependencies = [];
121
+ const topLevelDependencies = [];
122
+ const dependentTasks = collectDependentTasks(projectName, `${projectName}:${targetName}${configurationName ? `:${configurationName}` : ''}`, taskGraph, projectGraph, shallow);
123
+ const npmDependencies = collectNpmDependencies(projectName, projectGraph, !shallow ? dependentTasks : undefined);
124
+ const dependencies = [];
125
+ for (const [taskName, { isTopLevel }] of dependentTasks) {
126
+ let project = null;
127
+ const depTask = taskGraph.tasks[taskName];
128
+ const depProjectNode = (_a = projectGraph.nodes) === null || _a === void 0 ? void 0 : _a[depTask.target.project];
129
+ if ((depProjectNode === null || depProjectNode === void 0 ? void 0 : depProjectNode.type) !== 'lib') {
130
+ return null;
131
+ }
132
+ let outputs = (0, devkit_1.getOutputsForTargetAndConfiguration)(depTask, depProjectNode);
133
+ if (outputs.length === 0) {
134
+ nonBuildableDependencies.push(depTask.target.project);
135
+ continue;
136
+ }
137
+ const libPackageJsonPath = (0, path_1.join)(root, depProjectNode.data.root, 'package.json');
138
+ project = {
139
+ name: (0, fileutils_1.fileExists)(libPackageJsonPath)
140
+ ? (0, devkit_1.readJsonFile)(libPackageJsonPath).name // i.e. @workspace/mylib
141
+ : depTask.target.project,
142
+ outputs,
143
+ node: depProjectNode,
144
+ };
145
+ if (isTopLevel) {
146
+ topLevelDependencies.push(project);
147
+ }
148
+ dependencies.push(project);
149
+ }
150
+ for (const { project, isTopLevel } of npmDependencies) {
151
+ if (isTopLevel) {
152
+ topLevelDependencies.push(project);
153
+ }
154
+ dependencies.push(project);
155
+ }
156
+ dependencies.sort((a, b) => (a.name > b.name ? 1 : b.name > a.name ? -1 : 0));
157
+ return {
158
+ target,
159
+ dependencies,
160
+ nonBuildableDependencies,
161
+ topLevelDependencies,
162
+ };
163
+ }
164
+ exports.calculateDependenciesFromTaskGraph = calculateDependenciesFromTaskGraph;
165
+ function collectNpmDependencies(projectName, projectGraph, dependentTasks, collectedPackages = new Set(), isTopLevel = true) {
166
+ const dependencies = projectGraph.dependencies[projectName]
167
+ .map((dep) => {
168
+ var _a, _b, _c;
169
+ const projectNode = (_b = (_a = projectGraph.nodes) === null || _a === void 0 ? void 0 : _a[dep.target]) !== null && _b !== void 0 ? _b : (_c = projectGraph.externalNodes) === null || _c === void 0 ? void 0 : _c[dep.target];
170
+ if ((projectNode === null || projectNode === void 0 ? void 0 : projectNode.type) !== 'npm' ||
171
+ collectedPackages.has(projectNode.data.packageName)) {
172
+ return null;
173
+ }
174
+ const project = {
175
+ name: projectNode.data.packageName,
176
+ outputs: [],
177
+ node: projectNode,
178
+ };
179
+ collectedPackages.add(project.name);
180
+ return { project, isTopLevel };
181
+ })
182
+ .filter((x) => !!x);
183
+ if (dependentTasks === null || dependentTasks === void 0 ? void 0 : dependentTasks.size) {
184
+ for (const [, { project: projectName }] of dependentTasks) {
185
+ dependencies.push(...collectNpmDependencies(projectName, projectGraph, undefined, collectedPackages, false));
186
+ }
187
+ }
188
+ return dependencies;
189
+ }
190
+ function collectDependentTasks(project, task, taskGraph, projectGraph, shallow, areTopLevelDeps = true, dependentTasks = new Map()) {
191
+ var _a;
192
+ for (const depTask of (_a = taskGraph.dependencies[task]) !== null && _a !== void 0 ? _a : []) {
193
+ if (dependentTasks.has(depTask)) {
194
+ if (!dependentTasks.get(depTask).isTopLevel && areTopLevelDeps) {
195
+ dependentTasks.get(depTask).isTopLevel = true;
196
+ }
197
+ continue;
198
+ }
199
+ const { project: depTaskProject } = (0, devkit_1.parseTargetString)(depTask, projectGraph);
200
+ if (depTaskProject !== project) {
201
+ dependentTasks.set(depTask, {
202
+ project: depTaskProject,
203
+ isTopLevel: areTopLevelDeps,
204
+ });
205
+ }
206
+ if (!shallow) {
207
+ collectDependentTasks(depTaskProject, depTask, taskGraph, projectGraph, shallow, depTaskProject === project && areTopLevelDeps, dependentTasks);
208
+ }
209
+ }
210
+ return dependentTasks;
211
+ }
111
212
  /**
112
213
  * Util function to create tsconfig compilerOptions object with support for workspace libs paths.
113
214
  *
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkDependencies = void 0;
4
4
  const buildable_libs_utils_1 = require("./buildable-libs-utils");
5
5
  function checkDependencies(context, tsConfigPath) {
6
- const { target, dependencies } = (0, buildable_libs_utils_1.calculateProjectDependencies)(context.projectGraph, context.root, context.projectName, context.targetName, context.configurationName);
6
+ const { target, dependencies } = (0, buildable_libs_utils_1.calculateProjectBuildableDependencies)(context.taskGraph, context.projectGraph, context.root, context.projectName, context.targetName, context.configurationName);
7
7
  const projectRoot = target.data.root;
8
8
  if (dependencies.length > 0) {
9
9
  return {
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findNpmDependencies = void 0;
4
4
  const path_1 = require("path");
5
- const file_utils_1 = require("nx/src/project-graph/file-utils");
5
+ const configuration_1 = require("nx/src/config/configuration");
6
6
  const task_hasher_1 = require("nx/src/hasher/task-hasher");
7
7
  const devkit_1 = require("@nx/devkit");
8
8
  const fileutils_1 = require("nx/src/utils/fileutils");
@@ -44,7 +44,7 @@ function collectDependenciesFromFileMap(workspaceRoot, sourceProject, projectGra
44
44
  // Cannot read inputs if the target does not exist on the project.
45
45
  if (!sourceProject.data.targets[buildTarget])
46
46
  return;
47
- const inputs = (0, task_hasher_1.getTargetInputs)((0, file_utils_1.readNxJson)(), sourceProject, buildTarget).selfInputs;
47
+ const inputs = (0, task_hasher_1.getTargetInputs)((0, configuration_1.readNxJson)(), sourceProject, buildTarget).selfInputs;
48
48
  const files = (0, task_hasher_1.filterUsingGlobPatterns)(sourceProject.data.root, projectFileMap[sourceProject.name] || [], inputs);
49
49
  for (const fileData of files) {
50
50
  if (!fileData.deps ||