@nx/js 16.8.0-beta.3 → 16.8.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.
Files changed (49) hide show
  1. package/babel.js +7 -8
  2. package/package.json +5 -5
  3. package/src/executors/node/lib/kill-tree.js +42 -45
  4. package/src/executors/node/node.impl.js +190 -189
  5. package/src/executors/node/schema.json +1 -1
  6. package/src/executors/swc/swc.impl.js +82 -70
  7. package/src/executors/tsc/lib/batch/build-task-info-per-tsconfig-map.js +7 -4
  8. package/src/executors/tsc/lib/batch/watch.js +42 -49
  9. package/src/executors/tsc/lib/get-task-options.js +8 -6
  10. package/src/executors/tsc/lib/get-tsconfig.js +16 -5
  11. package/src/executors/tsc/lib/normalize-options.js +9 -2
  12. package/src/executors/tsc/lib/typescript-compilation.js +21 -24
  13. package/src/executors/tsc/tsc.batch-impl.js +133 -132
  14. package/src/executors/tsc/tsc.impl.js +54 -50
  15. package/src/executors/verdaccio/verdaccio.impl.js +64 -55
  16. package/src/generators/convert-to-swc/convert-to-swc.js +6 -9
  17. package/src/generators/init/init.js +86 -92
  18. package/src/generators/library/library.d.ts +1 -1
  19. package/src/generators/library/library.js +290 -203
  20. package/src/generators/setup-build/generator.js +120 -113
  21. package/src/generators/setup-verdaccio/generator.js +45 -50
  22. package/src/migrations/update-13-8-5/update-node-executor.js +17 -21
  23. package/src/migrations/update-13-8-5/update-swcrc.js +23 -27
  24. package/src/migrations/update-14-1-5/update-swcrc-path.js +17 -20
  25. package/src/migrations/update-15-8-0/rename-swcrc-config.js +57 -60
  26. package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.js +3 -6
  27. package/src/migrations/update-16-6-0/explicitly-set-projects-to-update-buildable-deps.js +19 -24
  28. package/src/plugins/jest/start-local-registry.js +4 -6
  29. package/src/plugins/rollup/type-definitions.js +21 -24
  30. package/src/utils/add-babel-inputs.js +1 -2
  31. package/src/utils/assets/assets.js +1 -2
  32. package/src/utils/assets/copy-assets-handler.js +48 -59
  33. package/src/utils/assets/index.js +20 -23
  34. package/src/utils/buildable-libs-utils.js +9 -13
  35. package/src/utils/find-npm-dependencies.d.ts +1 -0
  36. package/src/utils/find-npm-dependencies.js +25 -15
  37. package/src/utils/generate-globs.js +3 -3
  38. package/src/utils/inline.js +5 -10
  39. package/src/utils/package-json/get-npm-scope.js +2 -2
  40. package/src/utils/package-json/index.js +22 -25
  41. package/src/utils/package-json/update-package-json.js +26 -23
  42. package/src/utils/prettier.js +21 -24
  43. package/src/utils/swc/compile-swc.js +101 -106
  44. package/src/utils/typescript/compile-typescript-files.js +7 -8
  45. package/src/utils/typescript/print-diagnostics.js +13 -16
  46. package/src/utils/typescript/run-type-check.js +62 -59
  47. package/src/utils/typescript/ts-config.js +3 -5
  48. package/src/utils/typescript/tsnode-register.js +1 -1
  49. package/src/utils/watch-for-single-file-changes.js +13 -17
package/babel.js CHANGED
@@ -2,17 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const path_1 = require("path");
4
4
  module.exports = function (api, options = {}) {
5
- var _a, _b, _c;
6
5
  api.assertVersion(7);
7
- const isModern = api.caller((caller) => caller === null || caller === void 0 ? void 0 : caller.isModern);
6
+ const isModern = api.caller((caller) => caller?.isModern);
8
7
  // use by @nx/cypress react component testing to prevent core js build issues
9
- const isTest = api.caller((caller) => caller === null || caller === void 0 ? void 0 : caller.isTest);
8
+ const isTest = api.caller((caller) => caller?.isTest);
10
9
  // This is set by `@nx/rollup:rollup` executor
11
- const isNxPackage = api.caller((caller) => caller === null || caller === void 0 ? void 0 : caller.isNxPackage);
12
- const emitDecoratorMetadata = api.caller((caller) => { var _a; return (_a = caller === null || caller === void 0 ? void 0 : caller.emitDecoratorMetadata) !== null && _a !== void 0 ? _a : true; });
10
+ const isNxPackage = api.caller((caller) => caller?.isNxPackage);
11
+ const emitDecoratorMetadata = api.caller((caller) => caller?.emitDecoratorMetadata ?? true);
13
12
  // Determine settings for `@babel/plugin-proposal-class-properties`,
14
13
  // so that we can sync the `loose` option with `@babel/preset-env`.
15
- const classProperties = (_a = options.classProperties) !== null && _a !== void 0 ? _a : { loose: true };
14
+ const classProperties = options.classProperties ?? { loose: true };
16
15
  return {
17
16
  presets: [
18
17
  // Support module/nomodule pattern.
@@ -25,7 +24,7 @@ module.exports = function (api, options = {}) {
25
24
  ? { targets: { node: 'current' }, loose: true }
26
25
  : {
27
26
  // Allow importing core-js in entrypoint and use browserslist to select polyfills.
28
- useBuiltIns: (_b = options.useBuiltIns) !== null && _b !== void 0 ? _b : 'entry',
27
+ useBuiltIns: options.useBuiltIns ?? 'entry',
29
28
  corejs: 3,
30
29
  // Do not transform modules to CJS
31
30
  modules: false,
@@ -64,7 +63,7 @@ module.exports = function (api, options = {}) {
64
63
  // Must use legacy decorators to remain compatible with TypeScript.
65
64
  [
66
65
  require.resolve('@babel/plugin-proposal-decorators'),
67
- (_c = options.decorators) !== null && _c !== void 0 ? _c : { legacy: true },
66
+ options.decorators ?? { legacy: true },
68
67
  ],
69
68
  [
70
69
  require.resolve('@babel/plugin-proposal-class-properties'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/js",
3
- "version": "16.8.0-beta.3",
3
+ "version": "16.8.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": {
@@ -39,9 +39,9 @@
39
39
  "@babel/preset-env": "^7.22.9",
40
40
  "@babel/preset-typescript": "^7.22.5",
41
41
  "@babel/runtime": "^7.22.6",
42
- "@nrwl/js": "16.8.0-beta.3",
43
- "@nx/devkit": "16.8.0-beta.3",
44
- "@nx/workspace": "16.8.0-beta.3",
42
+ "@nrwl/js": "16.8.0-beta.5",
43
+ "@nx/devkit": "16.8.0-beta.5",
44
+ "@nx/workspace": "16.8.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
  "type": "commonjs",
74
- "gitHead": "dcd48165a485bc8db57a1fb02b96a0772de3b7e9"
74
+ "gitHead": "ad2d1e8a55b2d1b358bb5e7483343d9757ff2c53"
75
75
  }
@@ -1,54 +1,51 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.killTree = void 0;
4
- const tslib_1 = require("tslib");
5
4
  // Adapted from https://raw.githubusercontent.com/pkrumins/node-tree-kill/deee138/index.js
6
5
  const child_process_1 = require("child_process");
7
- function killTree(pid, signal) {
8
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
9
- const tree = {};
10
- const pidsToProcess = {};
11
- tree[pid] = [];
12
- pidsToProcess[pid] = 1;
13
- return new Promise((resolve, reject) => {
14
- const callback = (error) => {
15
- if (error) {
16
- reject(error);
17
- }
18
- else {
19
- resolve();
20
- }
21
- };
22
- switch (process.platform) {
23
- case 'win32':
24
- (0, child_process_1.exec)('taskkill /pid ' + pid + ' /T /F', (error) => {
25
- // Ignore Fatal errors (128) because it might be due to the process already being killed.
26
- // On Linux/Mac we can check ESRCH (no such process), but on Windows we can't.
27
- callback((error === null || error === void 0 ? void 0 : error.code) !== 128 ? error : null);
28
- });
29
- break;
30
- case 'darwin':
31
- buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
32
- return (0, child_process_1.spawn)('pgrep', ['-P', parentPid]);
33
- }, function () {
34
- killAll(tree, signal, callback);
35
- });
36
- break;
37
- default: // Linux
38
- buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
39
- return (0, child_process_1.spawn)('ps', [
40
- '-o',
41
- 'pid',
42
- '--no-headers',
43
- '--ppid',
44
- parentPid,
45
- ]);
46
- }, function () {
47
- killAll(tree, signal, callback);
48
- });
49
- break;
6
+ async function killTree(pid, signal) {
7
+ const tree = {};
8
+ const pidsToProcess = {};
9
+ tree[pid] = [];
10
+ pidsToProcess[pid] = 1;
11
+ return new Promise((resolve, reject) => {
12
+ const callback = (error) => {
13
+ if (error) {
14
+ reject(error);
50
15
  }
51
- });
16
+ else {
17
+ resolve();
18
+ }
19
+ };
20
+ switch (process.platform) {
21
+ case 'win32':
22
+ (0, child_process_1.exec)('taskkill /pid ' + pid + ' /T /F', (error) => {
23
+ // Ignore Fatal errors (128) because it might be due to the process already being killed.
24
+ // On Linux/Mac we can check ESRCH (no such process), but on Windows we can't.
25
+ callback(error?.code !== 128 ? error : null);
26
+ });
27
+ break;
28
+ case 'darwin':
29
+ buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
30
+ return (0, child_process_1.spawn)('pgrep', ['-P', parentPid]);
31
+ }, function () {
32
+ killAll(tree, signal, callback);
33
+ });
34
+ break;
35
+ default: // Linux
36
+ buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
37
+ return (0, child_process_1.spawn)('ps', [
38
+ '-o',
39
+ 'pid',
40
+ '--no-headers',
41
+ '--ppid',
42
+ parentPid,
43
+ ]);
44
+ }, function () {
45
+ killAll(tree, signal, callback);
46
+ });
47
+ break;
48
+ }
52
49
  });
53
50
  }
54
51
  exports.killTree = killTree;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.nodeExecutor = void 0;
4
- const tslib_1 = require("tslib");
5
4
  const chalk = require("chalk");
6
5
  const child_process_1 = require("child_process");
7
6
  const devkit_1 = require("@nx/devkit");
@@ -21,203 +20,205 @@ function debounce(fn, wait) {
21
20
  timeoutId = setTimeout(fn, wait);
22
21
  };
23
22
  }
24
- function nodeExecutor(options, context) {
25
- var _a, _b, _c;
26
- var _d;
27
- return tslib_1.__asyncGenerator(this, arguments, function* nodeExecutor_1() {
28
- (_a = (_d = process.env).NODE_ENV) !== null && _a !== void 0 ? _a : (_d.NODE_ENV = (_b = context === null || context === void 0 ? void 0 : context.configurationName) !== null && _b !== void 0 ? _b : 'development');
29
- const project = context.projectGraph.nodes[context.projectName];
30
- const buildTarget = (0, devkit_1.parseTargetString)(options.buildTarget, context.projectGraph);
31
- if (!project.data.targets[buildTarget.target]) {
32
- throw new Error(`Cannot find build target ${chalk.bold(options.buildTarget)} for project ${chalk.bold(context.projectName)}`);
33
- }
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
- }
40
- const buildOptions = Object.assign(Object.assign({}, (0, devkit_1.readTargetOptions)(buildTarget, context)), options.buildTargetOptions);
41
- if (options.waitUntilTargets && options.waitUntilTargets.length > 0) {
42
- const results = yield tslib_1.__await(runWaitUntilTargets(options, context));
43
- for (const [i, result] of results.entries()) {
44
- if (!result.success) {
45
- throw new Error(`Wait until target failed: ${options.waitUntilTargets[i]}.`);
46
- }
23
+ async function* nodeExecutor(options, context) {
24
+ process.env.NODE_ENV ??= context?.configurationName ?? 'development';
25
+ const project = context.projectGraph.nodes[context.projectName];
26
+ const buildTarget = (0, devkit_1.parseTargetString)(options.buildTarget, context.projectGraph);
27
+ if (!project.data.targets[buildTarget.target]) {
28
+ throw new Error(`Cannot find build target ${chalk.bold(options.buildTarget)} for project ${chalk.bold(context.projectName)}`);
29
+ }
30
+ const buildTargetExecutor = project.data.targets[buildTarget.target]?.executor;
31
+ if (buildTargetExecutor === 'nx:run-commands' ||
32
+ buildTargetExecutor === '@nrwl/workspace:run-commands') {
33
+ // Run commands does not emit build event, so we have to switch to run entire build through Nx CLI.
34
+ options.runBuildTargetDependencies = true;
35
+ }
36
+ const buildOptions = {
37
+ ...(0, devkit_1.readTargetOptions)(buildTarget, context),
38
+ ...options.buildTargetOptions,
39
+ };
40
+ if (options.waitUntilTargets && options.waitUntilTargets.length > 0) {
41
+ const results = await runWaitUntilTargets(options, context);
42
+ for (const [i, result] of results.entries()) {
43
+ if (!result.success) {
44
+ throw new Error(`Wait until target failed: ${options.waitUntilTargets[i]}.`);
47
45
  }
48
46
  }
49
- // Re-map buildable workspace projects to their output directory.
50
- const mappings = calculateResolveMappings(context, options);
51
- const fileToRun = getFileToRun(context, project, buildOptions, buildTargetExecutor);
52
- let additionalExitHandler = null;
53
- let currentTask = null;
54
- const tasks = [];
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* () {
56
- var _e;
57
- const processQueue = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
58
- if (tasks.length === 0)
59
- return;
60
- const previousTask = currentTask;
61
- const task = tasks.shift();
62
- currentTask = task;
63
- yield (previousTask === null || previousTask === void 0 ? void 0 : previousTask.stop('SIGTERM'));
64
- yield task.start();
65
- });
66
- const debouncedProcessQueue = debounce(processQueue, (_e = options.debounce) !== null && _e !== void 0 ? _e : 1000);
67
- const addToQueue = (childProcess, buildResult) => tslib_1.__awaiter(this, void 0, void 0, function* () {
68
- const task = {
69
- id: (0, crypto_1.randomUUID)(),
70
- killed: false,
71
- childProcess,
72
- promise: null,
73
- start: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
74
- // Wait for build to finish.
75
- const result = yield buildResult;
76
- if (!result.success) {
77
- // If in watch-mode, don't throw or else the process exits.
78
- if (options.watch) {
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
- }
83
- return;
84
- }
85
- else {
86
- throw new Error(`Build failed. See above for errors.`);
47
+ }
48
+ // Re-map buildable workspace projects to their output directory.
49
+ const mappings = calculateResolveMappings(context, options);
50
+ const fileToRun = getFileToRun(context, project, buildOptions, buildTargetExecutor);
51
+ let additionalExitHandler = null;
52
+ let currentTask = null;
53
+ const tasks = [];
54
+ yield* (0, async_iterable_1.createAsyncIterable)(async ({ done, next, error }) => {
55
+ const processQueue = async () => {
56
+ if (tasks.length === 0)
57
+ return;
58
+ const previousTask = currentTask;
59
+ const task = tasks.shift();
60
+ currentTask = task;
61
+ await previousTask?.stop('SIGTERM');
62
+ await task.start();
63
+ };
64
+ const debouncedProcessQueue = debounce(processQueue, options.debounce ?? 1000);
65
+ const addToQueue = async (childProcess, buildResult) => {
66
+ const task = {
67
+ id: (0, crypto_1.randomUUID)(),
68
+ killed: false,
69
+ childProcess,
70
+ promise: null,
71
+ start: async () => {
72
+ // Wait for build to finish.
73
+ const result = await buildResult;
74
+ if (!result.success) {
75
+ // If in watch-mode, don't throw or else the process exits.
76
+ if (options.watch) {
77
+ if (!task.killed) {
78
+ // Only log build error if task was not killed by a new change.
79
+ devkit_1.logger.error(`Build failed, waiting for changes to restart...`);
87
80
  }
88
- }
89
- // Before running the program, check if the task has been killed (by a new change during watch).
90
- if (task.killed)
91
81
  return;
92
- // Run the program
93
- task.promise = new Promise((resolve, reject) => {
94
- var _a;
95
- task.childProcess = (0, child_process_1.fork)((0, devkit_1.joinPathFragments)(__dirname, 'node-with-require-overrides'), (_a = options.args) !== null && _a !== void 0 ? _a : [], {
96
- execArgv: getExecArgv(options),
97
- stdio: [0, 1, 'pipe', 'ipc'],
98
- env: Object.assign(Object.assign({}, process.env), { NX_FILE_TO_RUN: fileToRunCorrectPath(fileToRun), NX_MAPPINGS: JSON.stringify(mappings) }),
99
- });
100
- const handleStdErr = (data) => {
101
- // Don't log out error if task is killed and new one has started.
102
- // This could happen if a new build is triggered while new process is starting, since the operation is not atomic.
103
- // Log the error in normal mode
104
- if (!options.watch || !task.killed) {
105
- devkit_1.logger.error(data.toString());
106
- }
107
- };
108
- task.childProcess.stderr.on('data', handleStdErr);
109
- task.childProcess.once('exit', (code) => {
110
- task.childProcess.off('data', handleStdErr);
111
- if (options.watch && !task.killed) {
112
- devkit_1.logger.info(`NX Process exited with code ${code}, waiting for changes to restart...`);
113
- }
114
- if (!options.watch)
115
- done();
116
- resolve();
117
- });
118
- next({ success: true, options: buildOptions });
119
- });
120
- }),
121
- stop: (signal = 'SIGTERM') => tslib_1.__awaiter(this, void 0, void 0, function* () {
122
- task.killed = true;
123
- // Request termination and wait for process to finish gracefully.
124
- // NOTE: `childProcess` may not have been set yet if the task did not have a chance to start.
125
- // e.g. multiple file change events in a short time (like git checkout).
126
- if (task.childProcess) {
127
- yield (0, kill_tree_1.killTree)(task.childProcess.pid, signal);
128
- }
129
- try {
130
- yield task.promise;
131
82
  }
132
- catch (_f) {
133
- // Doesn't matter if task fails, we just need to wait until it finishes.
83
+ else {
84
+ throw new Error(`Build failed. See above for errors.`);
134
85
  }
135
- }),
136
- };
137
- tasks.push(task);
138
- });
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',
86
+ }
87
+ // Before running the program, check if the task has been killed (by a new change during watch).
88
+ if (task.killed)
89
+ return;
90
+ // Run the program
91
+ task.promise = new Promise((resolve, reject) => {
92
+ task.childProcess = (0, child_process_1.fork)((0, devkit_1.joinPathFragments)(__dirname, 'node-with-require-overrides'), options.args ?? [], {
93
+ execArgv: getExecArgv(options),
94
+ stdio: [0, 1, 'pipe', 'ipc'],
95
+ env: {
96
+ ...process.env,
97
+ NX_FILE_TO_RUN: fileToRunCorrectPath(fileToRun),
98
+ NX_MAPPINGS: JSON.stringify(mappings),
99
+ },
151
100
  });
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) });
101
+ const handleStdErr = (data) => {
102
+ // Don't log out error if task is killed and new one has started.
103
+ // This could happen if a new build is triggered while new process is starting, since the operation is not atomic.
104
+ // Log the error in normal mode
105
+ if (!options.watch || !task.killed) {
106
+ devkit_1.logger.error(data.toString());
107
+ }
108
+ };
109
+ task.childProcess.stderr.on('data', handleStdErr);
110
+ task.childProcess.once('exit', (code) => {
111
+ task.childProcess.off('data', handleStdErr);
112
+ if (options.watch && !task.killed) {
113
+ devkit_1.logger.info(`NX Process exited with code ${code}, waiting for changes to restart...`);
114
+ }
115
+ if (!options.watch)
116
+ done();
117
+ resolve();
158
118
  });
159
- }));
160
- yield addToQueue(childProcess, whenReady);
161
- yield debouncedProcessQueue();
162
- });
163
- additionalExitHandler = yield client_1.daemonClient.registerFileWatcher({
164
- watchProjects: [context.projectName],
165
- includeDependentProjects: true,
166
- }, (err, data) => tslib_1.__awaiter(this, void 0, void 0, function* () {
167
- var _g;
168
- if (err === 'closed') {
169
- devkit_1.logger.error(`Watch error: Daemon closed the connection`);
170
- process.exit(1);
171
- }
172
- else if (err) {
173
- devkit_1.logger.error(`Watch error: ${(_g = err === null || err === void 0 ? void 0 : err.message) !== null && _g !== void 0 ? _g : 'Unknown'}`);
119
+ next({ success: true, options: buildOptions });
120
+ });
121
+ },
122
+ stop: async (signal = 'SIGTERM') => {
123
+ task.killed = true;
124
+ // Request termination and wait for process to finish gracefully.
125
+ // NOTE: `childProcess` may not have been set yet if the task did not have a chance to start.
126
+ // e.g. multiple file change events in a short time (like git checkout).
127
+ if (task.childProcess) {
128
+ await (0, kill_tree_1.killTree)(task.childProcess.pid, signal);
174
129
  }
175
- else {
176
- devkit_1.logger.info(`NX File change detected. Restarting...`);
177
- yield runBuild();
130
+ try {
131
+ await task.promise;
178
132
  }
179
- }));
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;
133
+ catch {
134
+ // Doesn't matter if task fails, we just need to wait until it finishes.
193
135
  }
136
+ },
137
+ };
138
+ tasks.push(task);
139
+ };
140
+ if (options.runBuildTargetDependencies) {
141
+ // If a all dependencies need to be rebuild on changes, then register with watcher
142
+ // and run through CLI, otherwise only the current project will rebuild.
143
+ const runBuild = async () => {
144
+ let childProcess = null;
145
+ const whenReady = new Promise(async (resolve) => {
146
+ childProcess = (0, child_process_1.fork)(require.resolve('nx'), [
147
+ 'run',
148
+ `${context.projectName}:${buildTarget.target}${buildTarget.configuration ? `:${buildTarget.configuration}` : ''}`,
149
+ ], {
150
+ cwd: context.root,
151
+ stdio: 'inherit',
152
+ });
153
+ childProcess.once('exit', (code) => {
154
+ if (code === 0)
155
+ resolve({ success: true });
156
+ // If process is killed due to current task being killed, then resolve with success.
157
+ else
158
+ resolve({ success: !!currentTask?.killed });
159
+ });
160
+ });
161
+ await addToQueue(childProcess, whenReady);
162
+ await debouncedProcessQueue();
163
+ };
164
+ additionalExitHandler = await client_1.daemonClient.registerFileWatcher({
165
+ watchProjects: [context.projectName],
166
+ includeDependentProjects: true,
167
+ }, async (err, data) => {
168
+ if (err === 'closed') {
169
+ devkit_1.logger.error(`Watch error: Daemon closed the connection`);
170
+ process.exit(1);
194
171
  }
195
- }
196
- const stopAllTasks = (signal = 'SIGTERM') => {
197
- additionalExitHandler === null || additionalExitHandler === void 0 ? void 0 : additionalExitHandler();
198
- for (const task of tasks) {
199
- task.stop(signal);
172
+ else if (err) {
173
+ devkit_1.logger.error(`Watch error: ${err?.message ?? 'Unknown'}`);
200
174
  }
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
- }));
214
- })))));
175
+ else {
176
+ devkit_1.logger.info(`NX File change detected. Restarting...`);
177
+ await runBuild();
178
+ }
179
+ });
180
+ await 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 = await (0, devkit_1.runExecutor)(buildTarget, {
187
+ ...options.buildTargetOptions,
188
+ watch: options.watch,
189
+ }, context);
190
+ while (true) {
191
+ const event = await output.next();
192
+ await addToQueue(null, Promise.resolve(event.value));
193
+ await debouncedProcessQueue();
194
+ if (event.done || !options.watch) {
195
+ break;
196
+ }
197
+ }
198
+ }
199
+ const stopAllTasks = (signal = 'SIGTERM') => {
200
+ additionalExitHandler?.();
201
+ for (const task of tasks) {
202
+ task.stop(signal);
203
+ }
204
+ };
205
+ process.on('SIGTERM', async () => {
206
+ stopAllTasks('SIGTERM');
207
+ process.exit(128 + 15);
208
+ });
209
+ process.on('SIGINT', async () => {
210
+ stopAllTasks('SIGINT');
211
+ process.exit(128 + 2);
212
+ });
213
+ process.on('SIGHUP', async () => {
214
+ stopAllTasks('SIGHUP');
215
+ process.exit(128 + 1);
216
+ });
215
217
  });
216
218
  }
217
219
  exports.nodeExecutor = nodeExecutor;
218
220
  function getExecArgv(options) {
219
- var _a;
220
- const args = ((_a = options.runtimeArgs) !== null && _a !== void 0 ? _a : (options.runtimeArgs = []));
221
+ const args = (options.runtimeArgs ??= []);
221
222
  args.push('-r', require.resolve('source-map-support/register'));
222
223
  if (options.inspect === true) {
223
224
  options.inspect = "inspect" /* InspectType.Inspect */;
@@ -238,24 +239,24 @@ function calculateResolveMappings(context, options) {
238
239
  }, {});
239
240
  }
240
241
  function runWaitUntilTargets(options, context) {
241
- return Promise.all(options.waitUntilTargets.map((waitUntilTarget) => tslib_1.__awaiter(this, void 0, void 0, function* () {
242
+ return Promise.all(options.waitUntilTargets.map(async (waitUntilTarget) => {
242
243
  const target = (0, devkit_1.parseTargetString)(waitUntilTarget, context.projectGraph);
243
- const output = yield (0, devkit_1.runExecutor)(target, {}, context);
244
- return new Promise((resolve) => tslib_1.__awaiter(this, void 0, void 0, function* () {
245
- let event = yield output.next();
244
+ const output = await (0, devkit_1.runExecutor)(target, {}, context);
245
+ return new Promise(async (resolve) => {
246
+ let event = await output.next();
246
247
  // Resolve after first event
247
248
  resolve(event.value);
248
249
  // Continue iterating
249
250
  while (!event.done) {
250
- event = yield output.next();
251
+ event = await output.next();
251
252
  }
252
- }));
253
- })));
253
+ });
254
+ }));
254
255
  }
255
256
  function getFileToRun(context, project, buildOptions, buildTargetExecutor) {
256
257
  // If using run-commands or another custom executor, then user should set
257
258
  // 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
+ if (!buildOptions?.outputPath && !buildOptions?.outputFileName) {
259
260
  const fallbackFile = path.join('dist', project.data.root, 'main.js');
260
261
  devkit_1.logger.warn(`Build option ${chalk.bold('outputFileName')} not set for ${chalk.bold(project.name)}. Using fallback value of ${chalk.bold(fallbackFile)}.`);
261
262
  return (0, path_1.join)(context.root, fallbackFile);
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "waitUntilTargets": {
20
20
  "type": "array",
21
- "description": "The targets to run before starting the node app.",
21
+ "description": "The targets to run before starting the node app. Listed in the form <project>:<target>. The main target will run once all listed targets have output something to the console.",
22
22
  "default": [],
23
23
  "items": {
24
24
  "type": "string"