@nx/js 0.0.0-pr-3-5e7ccde → 0.0.0-pr-29464-c4b160c
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 +3 -3
- package/src/executors/node/node.impl.js +1 -1
- package/src/generators/library/library.js +7 -117
- package/src/generators/library/utils/add-release-config.d.ts +11 -0
- package/src/generators/library/utils/add-release-config.js +136 -0
- package/src/generators/release-version/release-version.js +1 -1
- package/src/plugins/typescript/plugin.js +308 -113
- package/src/utils/find-npm-dependencies.d.ts +1 -0
- package/src/utils/find-npm-dependencies.js +12 -2
- package/src/utils/npm-config.js +1 -4
- package/src/utils/swc/add-swc-config.d.ts +1 -1
- package/src/utils/swc/add-swc-config.js +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/js",
|
|
3
|
-
"version": "0.0.0-pr-
|
|
3
|
+
"version": "0.0.0-pr-29464-c4b160c",
|
|
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,8 +39,8 @@
|
|
|
39
39
|
"@babel/preset-env": "^7.23.2",
|
|
40
40
|
"@babel/preset-typescript": "^7.22.5",
|
|
41
41
|
"@babel/runtime": "^7.22.6",
|
|
42
|
-
"@nx/devkit": "0.0.0-pr-
|
|
43
|
-
"@nx/workspace": "0.0.0-pr-
|
|
42
|
+
"@nx/devkit": "0.0.0-pr-29464-c4b160c",
|
|
43
|
+
"@nx/workspace": "0.0.0-pr-29464-c4b160c",
|
|
44
44
|
"@zkochan/js-yaml": "0.0.7",
|
|
45
45
|
"babel-plugin-const-enum": "^1.0.1",
|
|
46
46
|
"babel-plugin-macros": "^3.1.0",
|
|
@@ -88,7 +88,7 @@ async function* nodeExecutor(options, context) {
|
|
|
88
88
|
start: async () => {
|
|
89
89
|
// Wait for build to finish.
|
|
90
90
|
const result = await buildResult;
|
|
91
|
-
if (!result.success) {
|
|
91
|
+
if (result && !result.success) {
|
|
92
92
|
// If in watch-mode, don't throw or else the process exits.
|
|
93
93
|
if (options.watch) {
|
|
94
94
|
if (!task.killed) {
|
|
@@ -8,7 +8,6 @@ const project_name_and_root_utils_1 = require("@nx/devkit/src/generators/project
|
|
|
8
8
|
const prompt_1 = require("@nx/devkit/src/generators/prompt");
|
|
9
9
|
const target_defaults_utils_1 = require("@nx/devkit/src/generators/target-defaults-utils");
|
|
10
10
|
const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-project-command");
|
|
11
|
-
const find_matching_projects_1 = require("nx/src/utils/find-matching-projects");
|
|
12
11
|
const path_1 = require("path");
|
|
13
12
|
const generator_prompts_1 = require("../../utils/generator-prompts");
|
|
14
13
|
const update_package_json_1 = require("../../utils/package-json/update-package-json");
|
|
@@ -22,9 +21,9 @@ const ts_config_1 = require("../../utils/typescript/ts-config");
|
|
|
22
21
|
const ts_solution_setup_1 = require("../../utils/typescript/ts-solution-setup");
|
|
23
22
|
const versions_1 = require("../../utils/versions");
|
|
24
23
|
const init_1 = require("../init/init");
|
|
25
|
-
const generator_1 = require("../setup-verdaccio/generator");
|
|
26
24
|
const sort_fields_1 = require("../../utils/package-json/sort-fields");
|
|
27
25
|
const get_import_path_1 = require("../../utils/get-import-path");
|
|
26
|
+
const add_release_config_1 = require("./utils/add-release-config");
|
|
28
27
|
const defaultOutputDirectory = 'dist';
|
|
29
28
|
async function libraryGenerator(tree, schema) {
|
|
30
29
|
return await libraryGeneratorInternal(tree, {
|
|
@@ -54,9 +53,6 @@ async function libraryGeneratorInternal(tree, schema) {
|
|
|
54
53
|
if (!options.skipPackageJson) {
|
|
55
54
|
tasks.push(addProjectDependencies(tree, options));
|
|
56
55
|
}
|
|
57
|
-
if (options.publishable) {
|
|
58
|
-
tasks.push(await (0, generator_1.default)(tree, { ...options, skipFormat: true }));
|
|
59
|
-
}
|
|
60
56
|
if (options.bundler === 'rollup') {
|
|
61
57
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/rollup', versions_1.nxVersion);
|
|
62
58
|
await configurationGenerator(tree, {
|
|
@@ -151,9 +147,7 @@ async function libraryGeneratorInternal(tree, schema) {
|
|
|
151
147
|
await (0, devkit_1.formatFiles)(tree);
|
|
152
148
|
}
|
|
153
149
|
if (options.publishable) {
|
|
154
|
-
tasks.push(()
|
|
155
|
-
logNxReleaseDocsInfo();
|
|
156
|
-
});
|
|
150
|
+
tasks.push(await (0, add_release_config_1.releaseTasks)(tree));
|
|
157
151
|
}
|
|
158
152
|
// Always run install to link packages.
|
|
159
153
|
if (options.isUsingTsSolutionConfig) {
|
|
@@ -220,26 +214,12 @@ async function configureProject(tree, options) {
|
|
|
220
214
|
}
|
|
221
215
|
}
|
|
222
216
|
if (options.publishable) {
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
packageRoot,
|
|
229
|
-
},
|
|
230
|
-
};
|
|
231
|
-
projectConfiguration.release = {
|
|
232
|
-
version: {
|
|
233
|
-
generatorOptions: {
|
|
234
|
-
packageRoot,
|
|
235
|
-
// using git tags to determine the current version is required here because
|
|
236
|
-
// the version in the package root is overridden with every build
|
|
237
|
-
currentVersionResolver: 'git-tag',
|
|
238
|
-
},
|
|
239
|
-
},
|
|
240
|
-
};
|
|
217
|
+
if (options.isUsingTsSolutionConfig) {
|
|
218
|
+
await (0, add_release_config_1.addReleaseConfigForTsSolution)(tree, options.name, projectConfiguration);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
await (0, add_release_config_1.addReleaseConfigForNonTsSolution)(tree, options.name, projectConfiguration, defaultOutputDirectory);
|
|
241
222
|
}
|
|
242
|
-
await addProjectToNxReleaseConfig(tree, options, projectConfiguration);
|
|
243
223
|
}
|
|
244
224
|
if (!options.useProjectJson) {
|
|
245
225
|
// we want the package.json as clean as possible, with the bare minimum
|
|
@@ -930,96 +910,6 @@ function determineEntryFields(options) {
|
|
|
930
910
|
}
|
|
931
911
|
}
|
|
932
912
|
}
|
|
933
|
-
function projectsConfigMatchesProject(projectsConfig, project) {
|
|
934
|
-
if (!projectsConfig) {
|
|
935
|
-
return false;
|
|
936
|
-
}
|
|
937
|
-
if (typeof projectsConfig === 'string') {
|
|
938
|
-
projectsConfig = [projectsConfig];
|
|
939
|
-
}
|
|
940
|
-
const graph = {
|
|
941
|
-
[project.name]: project,
|
|
942
|
-
};
|
|
943
|
-
const matchingProjects = (0, find_matching_projects_1.findMatchingProjects)(projectsConfig, graph);
|
|
944
|
-
return matchingProjects.includes(project.name);
|
|
945
|
-
}
|
|
946
|
-
async function addProjectToNxReleaseConfig(tree, options, projectConfiguration) {
|
|
947
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
948
|
-
const addPreVersionCommand = () => {
|
|
949
|
-
const pmc = (0, devkit_1.getPackageManagerCommand)();
|
|
950
|
-
nxJson.release = {
|
|
951
|
-
...nxJson.release,
|
|
952
|
-
version: {
|
|
953
|
-
preVersionCommand: `${pmc.dlx} nx run-many -t build`,
|
|
954
|
-
...nxJson.release?.version,
|
|
955
|
-
},
|
|
956
|
-
};
|
|
957
|
-
};
|
|
958
|
-
if (!nxJson.release || (!nxJson.release.projects && !nxJson.release.groups)) {
|
|
959
|
-
// skip adding any projects configuration since the new project should be
|
|
960
|
-
// automatically included by nx release's default project detection logic
|
|
961
|
-
addPreVersionCommand();
|
|
962
|
-
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
963
|
-
return;
|
|
964
|
-
}
|
|
965
|
-
const project = {
|
|
966
|
-
name: options.name,
|
|
967
|
-
type: 'lib',
|
|
968
|
-
data: {
|
|
969
|
-
root: projectConfiguration.root,
|
|
970
|
-
tags: projectConfiguration.tags,
|
|
971
|
-
},
|
|
972
|
-
};
|
|
973
|
-
if (projectsConfigMatchesProject(nxJson.release.projects, project)) {
|
|
974
|
-
devkit_1.output.log({
|
|
975
|
-
title: `Project already included in existing release configuration`,
|
|
976
|
-
});
|
|
977
|
-
addPreVersionCommand();
|
|
978
|
-
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
979
|
-
return;
|
|
980
|
-
}
|
|
981
|
-
if (Array.isArray(nxJson.release.projects)) {
|
|
982
|
-
nxJson.release.projects.push(options.name);
|
|
983
|
-
addPreVersionCommand();
|
|
984
|
-
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
985
|
-
devkit_1.output.log({
|
|
986
|
-
title: `Added project to existing release configuration`,
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
|
-
if (nxJson.release.groups) {
|
|
990
|
-
const allGroups = Object.entries(nxJson.release.groups);
|
|
991
|
-
for (const [name, group] of allGroups) {
|
|
992
|
-
if (projectsConfigMatchesProject(group.projects, project)) {
|
|
993
|
-
addPreVersionCommand();
|
|
994
|
-
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
995
|
-
return `Project already included in existing release configuration for group ${name}`;
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
devkit_1.output.warn({
|
|
999
|
-
title: `Could not find a release group that includes ${options.name}`,
|
|
1000
|
-
bodyLines: [
|
|
1001
|
-
`Ensure that ${options.name} is included in a release group's "projects" list in nx.json so it can be published with "nx release"`,
|
|
1002
|
-
],
|
|
1003
|
-
});
|
|
1004
|
-
addPreVersionCommand();
|
|
1005
|
-
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
1008
|
-
if (typeof nxJson.release.projects === 'string') {
|
|
1009
|
-
nxJson.release.projects = [nxJson.release.projects, options.name];
|
|
1010
|
-
addPreVersionCommand();
|
|
1011
|
-
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
1012
|
-
devkit_1.output.log({
|
|
1013
|
-
title: `Added project to existing release configuration`,
|
|
1014
|
-
});
|
|
1015
|
-
return;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
function logNxReleaseDocsInfo() {
|
|
1019
|
-
devkit_1.output.log({
|
|
1020
|
-
title: `📦 To learn how to publish this library, see https://nx.dev/core-features/manage-releases.`,
|
|
1021
|
-
});
|
|
1022
|
-
}
|
|
1023
913
|
function findRootJestPreset(tree) {
|
|
1024
914
|
const ext = ['js', 'cjs', 'mjs'].find((ext) => tree.exists(`jest.preset.${ext}`));
|
|
1025
915
|
return ext ? `jest.preset.${ext}` : null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GeneratorCallback, ProjectConfiguration, Tree } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* Adds release option in nx.json to build the project before versioning
|
|
4
|
+
*/
|
|
5
|
+
export declare function addReleaseConfigForTsSolution(tree: Tree, projectName: string, projectConfiguration: ProjectConfiguration): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Add release configuration for non-ts solution projects
|
|
8
|
+
* Add release option in project.json and add packageRoot to nx-release-publish target
|
|
9
|
+
*/
|
|
10
|
+
export declare function addReleaseConfigForNonTsSolution(tree: Tree, projectName: string, projectConfiguration: ProjectConfiguration, defaultOutputDirectory?: string): Promise<ProjectConfiguration>;
|
|
11
|
+
export declare function releaseTasks(tree: Tree): Promise<GeneratorCallback>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addReleaseConfigForTsSolution = addReleaseConfigForTsSolution;
|
|
4
|
+
exports.addReleaseConfigForNonTsSolution = addReleaseConfigForNonTsSolution;
|
|
5
|
+
exports.releaseTasks = releaseTasks;
|
|
6
|
+
const devkit_1 = require("@nx/devkit");
|
|
7
|
+
const find_matching_projects_1 = require("nx/src/utils/find-matching-projects");
|
|
8
|
+
const generator_1 = require("../../setup-verdaccio/generator");
|
|
9
|
+
/**
|
|
10
|
+
* Adds release option in nx.json to build the project before versioning
|
|
11
|
+
*/
|
|
12
|
+
async function addReleaseConfigForTsSolution(tree, projectName, projectConfiguration) {
|
|
13
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
14
|
+
const addPreVersionCommand = () => {
|
|
15
|
+
const pmc = (0, devkit_1.getPackageManagerCommand)();
|
|
16
|
+
nxJson.release = {
|
|
17
|
+
...nxJson.release,
|
|
18
|
+
version: {
|
|
19
|
+
preVersionCommand: `${pmc.dlx} nx run-many -t build`,
|
|
20
|
+
...nxJson.release?.version,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
// if the release configuration does not exist, it will be created
|
|
25
|
+
if (!nxJson.release || (!nxJson.release.projects && !nxJson.release.groups)) {
|
|
26
|
+
// skip adding any projects configuration since the new project should be
|
|
27
|
+
// automatically included by nx release's default project detection logic
|
|
28
|
+
addPreVersionCommand();
|
|
29
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const project = {
|
|
33
|
+
name: projectName,
|
|
34
|
+
type: 'lib',
|
|
35
|
+
data: {
|
|
36
|
+
root: projectConfiguration.root,
|
|
37
|
+
tags: projectConfiguration.tags,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
// if the project is already included in the release configuration, it will not be added again
|
|
41
|
+
if (projectsConfigMatchesProject(nxJson.release.projects, project)) {
|
|
42
|
+
devkit_1.output.log({
|
|
43
|
+
title: `Project already included in existing release configuration`,
|
|
44
|
+
});
|
|
45
|
+
addPreVersionCommand();
|
|
46
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// if the release configuration is a string, it will be converted to an array and added to it
|
|
50
|
+
if (Array.isArray(nxJson.release.projects)) {
|
|
51
|
+
nxJson.release.projects.push(projectName);
|
|
52
|
+
addPreVersionCommand();
|
|
53
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
54
|
+
devkit_1.output.log({
|
|
55
|
+
title: `Added project to existing release configuration`,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (nxJson.release.groups) {
|
|
59
|
+
const allGroups = Object.entries(nxJson.release.groups);
|
|
60
|
+
for (const [name, group] of allGroups) {
|
|
61
|
+
if (projectsConfigMatchesProject(group.projects, project)) {
|
|
62
|
+
addPreVersionCommand();
|
|
63
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
64
|
+
devkit_1.output.log({
|
|
65
|
+
title: `Project already included in existing release configuration for group ${name}`,
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
devkit_1.output.warn({
|
|
71
|
+
title: `Could not find a release group that includes ${projectName}`,
|
|
72
|
+
bodyLines: [
|
|
73
|
+
`Ensure that ${projectName} is included in a release group's "projects" list in nx.json so it can be published with "nx release"`,
|
|
74
|
+
],
|
|
75
|
+
});
|
|
76
|
+
addPreVersionCommand();
|
|
77
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (typeof nxJson.release.projects === 'string') {
|
|
81
|
+
nxJson.release.projects = [nxJson.release.projects, projectName];
|
|
82
|
+
addPreVersionCommand();
|
|
83
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
84
|
+
devkit_1.output.log({
|
|
85
|
+
title: `Added project to existing release configuration`,
|
|
86
|
+
});
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Add release configuration for non-ts solution projects
|
|
92
|
+
* Add release option in project.json and add packageRoot to nx-release-publish target
|
|
93
|
+
*/
|
|
94
|
+
async function addReleaseConfigForNonTsSolution(tree, projectName, projectConfiguration, defaultOutputDirectory = 'dist') {
|
|
95
|
+
const packageRoot = (0, devkit_1.joinPathFragments)(defaultOutputDirectory, '{projectRoot}');
|
|
96
|
+
projectConfiguration.targets ??= {};
|
|
97
|
+
projectConfiguration.targets['nx-release-publish'] = {
|
|
98
|
+
options: {
|
|
99
|
+
packageRoot,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
projectConfiguration.release = {
|
|
103
|
+
version: {
|
|
104
|
+
generatorOptions: {
|
|
105
|
+
packageRoot,
|
|
106
|
+
// using git tags to determine the current version is required here because
|
|
107
|
+
// the version in the package root is overridden with every build
|
|
108
|
+
currentVersionResolver: 'git-tag',
|
|
109
|
+
fallbackCurrentVersionResolver: 'disk',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
await addReleaseConfigForTsSolution(tree, projectName, projectConfiguration);
|
|
114
|
+
return projectConfiguration;
|
|
115
|
+
}
|
|
116
|
+
function projectsConfigMatchesProject(projectsConfig, project) {
|
|
117
|
+
if (!projectsConfig) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
if (typeof projectsConfig === 'string') {
|
|
121
|
+
projectsConfig = [projectsConfig];
|
|
122
|
+
}
|
|
123
|
+
const graph = {
|
|
124
|
+
[project.name]: project,
|
|
125
|
+
};
|
|
126
|
+
const matchingProjects = (0, find_matching_projects_1.findMatchingProjects)(projectsConfig, graph);
|
|
127
|
+
return matchingProjects.includes(project.name);
|
|
128
|
+
}
|
|
129
|
+
async function releaseTasks(tree) {
|
|
130
|
+
return (0, devkit_1.runTasksInSerial)(await (0, generator_1.default)(tree, { skipFormat: true }), () => logNxReleaseDocsInfo());
|
|
131
|
+
}
|
|
132
|
+
function logNxReleaseDocsInfo() {
|
|
133
|
+
devkit_1.output.log({
|
|
134
|
+
title: `📦 To learn how to publish this library, see https://nx.dev/core-features/manage-releases.`,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
@@ -191,7 +191,7 @@ To fix this you will either need to add a package.json file at that location, or
|
|
|
191
191
|
const releaseTagPattern = options.releaseGroup.releaseTagPattern;
|
|
192
192
|
latestMatchingGitTag = await (0, git_1.getLatestGitTagForPattern)(releaseTagPattern, {
|
|
193
193
|
projectName: project.name,
|
|
194
|
-
});
|
|
194
|
+
}, options.releaseGroup.releaseTagPatternCheckAllBranchesWhen);
|
|
195
195
|
if (!latestMatchingGitTag) {
|
|
196
196
|
if (options.fallbackCurrentVersionResolver === 'disk') {
|
|
197
197
|
if (!currentVersionFromDisk &&
|
|
@@ -6,20 +6,28 @@ const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
|
|
|
6
6
|
const minimatch_1 = require("minimatch");
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
8
8
|
const node_path_1 = require("node:path");
|
|
9
|
+
const posix = require("node:path/posix");
|
|
9
10
|
const file_hasher_1 = require("nx/src/hasher/file-hasher");
|
|
10
11
|
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
|
11
12
|
const lock_file_1 = require("nx/src/plugins/js/lock-file/lock-file");
|
|
12
13
|
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
13
|
-
const ts_config_1 = require("../../utils/typescript/ts-config");
|
|
14
14
|
const util_1 = require("./util");
|
|
15
15
|
const pmc = (0, devkit_1.getPackageManagerCommand)();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
let tsConfigCache;
|
|
17
|
+
const tsConfigCachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, 'tsconfig-files.hash');
|
|
18
|
+
let cache;
|
|
19
|
+
function readFromCache(cachePath) {
|
|
20
|
+
try {
|
|
21
|
+
return process.env.NX_CACHE_PROJECT_GRAPH !== 'false'
|
|
22
|
+
? (0, devkit_1.readJsonFile)(cachePath)
|
|
23
|
+
: {};
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
20
28
|
}
|
|
21
|
-
function
|
|
22
|
-
(0, devkit_1.writeJsonFile)(cachePath,
|
|
29
|
+
function writeToCache(cachePath, data) {
|
|
30
|
+
(0, devkit_1.writeJsonFile)(cachePath, data, { spaces: 0 });
|
|
23
31
|
}
|
|
24
32
|
/**
|
|
25
33
|
* @deprecated The 'createDependencies' function is now a no-op. This functionality is included in 'createNodesV2'.
|
|
@@ -34,15 +42,32 @@ exports.createNodesV2 = [
|
|
|
34
42
|
tsConfigGlob,
|
|
35
43
|
async (configFilePaths, options, context) => {
|
|
36
44
|
const optionsHash = (0, file_hasher_1.hashObject)(options);
|
|
37
|
-
const
|
|
38
|
-
const targetsCache =
|
|
45
|
+
const targetsCachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `tsc-${optionsHash}.hash`);
|
|
46
|
+
const targetsCache = readFromCache(targetsCachePath);
|
|
47
|
+
cache = { fileHashes: {}, rawFiles: {}, isExternalProjectReference: {} };
|
|
48
|
+
initializeTsConfigCache(configFilePaths, context.workspaceRoot);
|
|
39
49
|
const normalizedOptions = normalizePluginOptions(options);
|
|
40
|
-
const
|
|
50
|
+
const { configFilePaths: validConfigFilePaths, hashes, projectRoots, } = await resolveValidConfigFilesAndHashes(configFilePaths, optionsHash, context);
|
|
41
51
|
try {
|
|
42
|
-
return await (0, devkit_1.createNodesFromFiles)((
|
|
52
|
+
return await (0, devkit_1.createNodesFromFiles)((configFilePath, options, context, idx) => {
|
|
53
|
+
const projectRoot = projectRoots[idx];
|
|
54
|
+
const hash = hashes[idx];
|
|
55
|
+
const cacheKey = `${hash}_${configFilePath}`;
|
|
56
|
+
targetsCache[cacheKey] ??= buildTscTargets((0, node_path_1.join)(context.workspaceRoot, configFilePath), projectRoot, options, context);
|
|
57
|
+
const { targets } = targetsCache[cacheKey];
|
|
58
|
+
return {
|
|
59
|
+
projects: {
|
|
60
|
+
[projectRoot]: {
|
|
61
|
+
projectType: 'library',
|
|
62
|
+
targets,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}, validConfigFilePaths, normalizedOptions, context);
|
|
43
67
|
}
|
|
44
68
|
finally {
|
|
45
|
-
|
|
69
|
+
writeToCache(targetsCachePath, targetsCache);
|
|
70
|
+
writeToCache(tsConfigCachePath, toRelativePaths(tsConfigCache, context.workspaceRoot));
|
|
46
71
|
}
|
|
47
72
|
},
|
|
48
73
|
];
|
|
@@ -50,28 +75,92 @@ exports.createNodes = [
|
|
|
50
75
|
tsConfigGlob,
|
|
51
76
|
async (configFilePath, options, context) => {
|
|
52
77
|
devkit_1.logger.warn('`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.');
|
|
78
|
+
const projectRoot = (0, node_path_1.dirname)(configFilePath);
|
|
79
|
+
if (!checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context)) {
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
53
82
|
const normalizedOptions = normalizePluginOptions(options);
|
|
54
|
-
|
|
55
|
-
|
|
83
|
+
cache = { fileHashes: {}, rawFiles: {}, isExternalProjectReference: {} };
|
|
84
|
+
initializeTsConfigCache([configFilePath], context.workspaceRoot);
|
|
85
|
+
const { targets } = buildTscTargets((0, node_path_1.join)(context.workspaceRoot, configFilePath), projectRoot, normalizedOptions, context);
|
|
86
|
+
writeToCache(tsConfigCachePath, toRelativePaths(tsConfigCache, context.workspaceRoot));
|
|
87
|
+
return {
|
|
88
|
+
projects: {
|
|
89
|
+
[projectRoot]: {
|
|
90
|
+
projectType: 'library',
|
|
91
|
+
targets,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
};
|
|
56
95
|
},
|
|
57
96
|
];
|
|
58
|
-
async function
|
|
59
|
-
const
|
|
60
|
-
const
|
|
97
|
+
async function resolveValidConfigFilesAndHashes(configFilePaths, optionsHash, context) {
|
|
98
|
+
const lockFileHash = (0, file_hasher_1.hashFile)((0, node_path_1.join)(context.workspaceRoot, (0, lock_file_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot)))) ?? '';
|
|
99
|
+
const validConfigFilePaths = [];
|
|
100
|
+
const hashes = [];
|
|
101
|
+
const projectRoots = [];
|
|
102
|
+
for await (const configFilePath of configFilePaths) {
|
|
103
|
+
const projectRoot = (0, node_path_1.dirname)(configFilePath);
|
|
104
|
+
if (!checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context)) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
projectRoots.push(projectRoot);
|
|
108
|
+
validConfigFilePaths.push(configFilePath);
|
|
109
|
+
hashes.push(await getConfigFileHash(configFilePath, context.workspaceRoot, projectRoot, optionsHash, lockFileHash));
|
|
110
|
+
}
|
|
111
|
+
return { configFilePaths: validConfigFilePaths, hashes, projectRoots };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The cache key is composed by:
|
|
115
|
+
* - hashes of the content of the relevant files that can affect what's inferred by the plugin:
|
|
116
|
+
* - current config file
|
|
117
|
+
* - config files extended by the current config file (recursively up to the root config file)
|
|
118
|
+
* - referenced config files that are internal to the owning Nx project of the current config file,
|
|
119
|
+
* or is a shallow external reference of the owning Nx project
|
|
120
|
+
* - lock file
|
|
121
|
+
* - project's package.json
|
|
122
|
+
* - hash of the plugin options
|
|
123
|
+
* - current config file path
|
|
124
|
+
*/
|
|
125
|
+
async function getConfigFileHash(configFilePath, workspaceRoot, projectRoot, optionsHash, lockFileHash) {
|
|
126
|
+
const fullConfigPath = (0, node_path_1.join)(workspaceRoot, configFilePath);
|
|
127
|
+
const tsConfig = retrieveTsConfigFromCache(fullConfigPath, workspaceRoot);
|
|
128
|
+
const extendedConfigFiles = getExtendedConfigFiles(tsConfig, workspaceRoot);
|
|
129
|
+
const internalReferencedFiles = resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot);
|
|
130
|
+
const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot);
|
|
131
|
+
let packageJson = null;
|
|
132
|
+
try {
|
|
133
|
+
packageJson = (0, devkit_1.readJsonFile)((0, node_path_1.join)(workspaceRoot, projectRoot, 'package.json'));
|
|
134
|
+
}
|
|
135
|
+
catch { }
|
|
136
|
+
return (0, file_hasher_1.hashArray)([
|
|
137
|
+
...[
|
|
138
|
+
fullConfigPath,
|
|
139
|
+
...extendedConfigFiles.files.sort(),
|
|
140
|
+
...Object.keys(internalReferencedFiles).sort(),
|
|
141
|
+
...Object.keys(externalProjectReferences).sort(),
|
|
142
|
+
].map((file) => getFileHash(file, workspaceRoot)),
|
|
143
|
+
...extendedConfigFiles.packages.sort(),
|
|
144
|
+
lockFileHash,
|
|
145
|
+
optionsHash,
|
|
146
|
+
...(packageJson ? [(0, file_hasher_1.hashObject)(packageJson)] : []),
|
|
147
|
+
]);
|
|
148
|
+
}
|
|
149
|
+
function checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context) {
|
|
61
150
|
// Do not create a project for the workspace root tsconfig files.
|
|
62
151
|
if (projectRoot === '.') {
|
|
63
|
-
return
|
|
152
|
+
return false;
|
|
64
153
|
}
|
|
65
154
|
// Do not create a project if package.json and project.json isn't there.
|
|
66
155
|
const siblingFiles = (0, node_fs_1.readdirSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot));
|
|
67
156
|
if (!siblingFiles.includes('package.json') &&
|
|
68
157
|
!siblingFiles.includes('project.json')) {
|
|
69
|
-
return
|
|
158
|
+
return false;
|
|
70
159
|
}
|
|
71
160
|
// Do not create a project if it's not a tsconfig.json and there is no tsconfig.json in the same directory
|
|
72
161
|
if ((0, node_path_1.basename)(configFilePath) !== 'tsconfig.json' &&
|
|
73
162
|
!siblingFiles.includes('tsconfig.json')) {
|
|
74
|
-
return
|
|
163
|
+
return false;
|
|
75
164
|
}
|
|
76
165
|
// Do not create project for Next.js projects since they are not compatible with
|
|
77
166
|
// project references and typecheck will fail.
|
|
@@ -79,53 +168,14 @@ async function createNodesInternal(configFilePath, options, context, lockFileNam
|
|
|
79
168
|
siblingFiles.includes('next.config.cjs') ||
|
|
80
169
|
siblingFiles.includes('next.config.mjs') ||
|
|
81
170
|
siblingFiles.includes('next.config.ts')) {
|
|
82
|
-
return
|
|
171
|
+
return false;
|
|
83
172
|
}
|
|
84
|
-
|
|
85
|
-
* The cache key is composed by:
|
|
86
|
-
* - hashes of the content of the relevant files that can affect what's inferred by the plugin:
|
|
87
|
-
* - current config file
|
|
88
|
-
* - config files extended by the current config file (recursively up to the root config file)
|
|
89
|
-
* - referenced config files that are internal to the owning Nx project of the current config file, or is a shallow external reference of the owning Nx project
|
|
90
|
-
* - lock file
|
|
91
|
-
* - hash of the plugin options
|
|
92
|
-
* - current config file path
|
|
93
|
-
*/
|
|
94
|
-
const tsConfig = readCachedTsConfig(fullConfigPath);
|
|
95
|
-
const extendedConfigFiles = getExtendedConfigFiles(fullConfigPath, tsConfig);
|
|
96
|
-
const internalReferencedFiles = resolveInternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
|
|
97
|
-
const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
|
|
98
|
-
const packageJsonPath = (0, devkit_1.joinPathFragments)(projectRoot, 'package.json');
|
|
99
|
-
const packageJson = (0, node_fs_1.existsSync)(packageJsonPath)
|
|
100
|
-
? (0, devkit_1.readJsonFile)(packageJsonPath)
|
|
101
|
-
: null;
|
|
102
|
-
const nodeHash = (0, file_hasher_1.hashArray)([
|
|
103
|
-
...[
|
|
104
|
-
fullConfigPath,
|
|
105
|
-
...extendedConfigFiles.files,
|
|
106
|
-
...Object.keys(internalReferencedFiles),
|
|
107
|
-
...Object.keys(externalProjectReferences),
|
|
108
|
-
(0, node_path_1.join)(context.workspaceRoot, lockFileName),
|
|
109
|
-
].map(file_hasher_1.hashFile),
|
|
110
|
-
(0, file_hasher_1.hashObject)(options),
|
|
111
|
-
...(packageJson ? [(0, file_hasher_1.hashObject)(packageJson)] : []),
|
|
112
|
-
]);
|
|
113
|
-
const cacheKey = `${nodeHash}_${configFilePath}`;
|
|
114
|
-
targetsCache[cacheKey] ??= buildTscTargets(fullConfigPath, projectRoot, options, context);
|
|
115
|
-
const { targets } = targetsCache[cacheKey];
|
|
116
|
-
return {
|
|
117
|
-
projects: {
|
|
118
|
-
[projectRoot]: {
|
|
119
|
-
projectType: 'library',
|
|
120
|
-
targets,
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
};
|
|
173
|
+
return true;
|
|
124
174
|
}
|
|
125
175
|
function buildTscTargets(configFilePath, projectRoot, options, context) {
|
|
126
176
|
const targets = {};
|
|
127
177
|
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
128
|
-
const tsConfig =
|
|
178
|
+
const tsConfig = retrieveTsConfigFromCache(configFilePath, context.workspaceRoot);
|
|
129
179
|
let internalProjectReferences;
|
|
130
180
|
// Typecheck target
|
|
131
181
|
if ((0, node_path_1.basename)(configFilePath) === 'tsconfig.json' && options.typecheck) {
|
|
@@ -196,7 +246,7 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
|
|
|
196
246
|
function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot) {
|
|
197
247
|
const configFiles = new Set();
|
|
198
248
|
const externalDependencies = ['typescript'];
|
|
199
|
-
const extendedConfigFiles = getExtendedConfigFiles(
|
|
249
|
+
const extendedConfigFiles = getExtendedConfigFiles(tsConfig, workspaceRoot);
|
|
200
250
|
extendedConfigFiles.files.forEach((configPath) => {
|
|
201
251
|
configFiles.add(configPath);
|
|
202
252
|
});
|
|
@@ -294,7 +344,9 @@ function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspa
|
|
|
294
344
|
outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(config.options.outDir, relativeRootDir, `*.tsbuildinfo`), workspaceRoot, projectRoot));
|
|
295
345
|
}
|
|
296
346
|
}
|
|
297
|
-
else if (config.
|
|
347
|
+
else if (config.raw?.include?.length ||
|
|
348
|
+
config.raw?.files?.length ||
|
|
349
|
+
(!config.raw?.include && !config.raw?.files)) {
|
|
298
350
|
// tsc produce files in place when no outDir or outFile is set
|
|
299
351
|
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.js'));
|
|
300
352
|
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.cjs'));
|
|
@@ -407,23 +459,17 @@ function pathToInputOrOutput(path, workspaceRoot, projectRoot) {
|
|
|
407
459
|
}
|
|
408
460
|
return (0, devkit_1.joinPathFragments)('{projectRoot}', pathRelativeToProjectRoot);
|
|
409
461
|
}
|
|
410
|
-
function getExtendedConfigFiles(
|
|
462
|
+
function getExtendedConfigFiles(tsConfig, workspaceRoot) {
|
|
411
463
|
const extendedConfigFiles = new Set();
|
|
412
464
|
const extendedExternalPackages = new Set();
|
|
413
|
-
let
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if (!extendedConfigPath) {
|
|
418
|
-
break;
|
|
419
|
-
}
|
|
420
|
-
if (extendedConfigPath.externalPackage) {
|
|
421
|
-
extendedExternalPackages.add(extendedConfigPath.externalPackage);
|
|
465
|
+
let currentExtendedConfigFile = tsConfig.extendedConfigFile;
|
|
466
|
+
while (currentExtendedConfigFile) {
|
|
467
|
+
if (currentExtendedConfigFile.externalPackage) {
|
|
468
|
+
extendedExternalPackages.add(currentExtendedConfigFile.externalPackage);
|
|
422
469
|
break;
|
|
423
470
|
}
|
|
424
|
-
extendedConfigFiles.add(
|
|
425
|
-
|
|
426
|
-
currentConfigPath = extendedConfigPath.filePath;
|
|
471
|
+
extendedConfigFiles.add(currentExtendedConfigFile.filePath);
|
|
472
|
+
currentExtendedConfigFile = retrieveTsConfigFromCache(currentExtendedConfigFile.filePath, workspaceRoot).extendedConfigFile;
|
|
427
473
|
}
|
|
428
474
|
return {
|
|
429
475
|
files: Array.from(extendedConfigFiles),
|
|
@@ -431,27 +477,31 @@ function getExtendedConfigFiles(tsConfigPath, tsConfig) {
|
|
|
431
477
|
};
|
|
432
478
|
}
|
|
433
479
|
function resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
480
|
+
if (!tsConfig.projectReferences?.length) {
|
|
481
|
+
return {};
|
|
482
|
+
}
|
|
483
|
+
for (const ref of tsConfig.projectReferences) {
|
|
484
|
+
let refConfigPath = ref.path;
|
|
485
|
+
if (projectReferences[refConfigPath]) {
|
|
486
|
+
// Already resolved
|
|
487
|
+
continue;
|
|
437
488
|
}
|
|
438
|
-
|
|
439
|
-
|
|
489
|
+
if (!(0, node_fs_1.existsSync)(refConfigPath)) {
|
|
490
|
+
// the referenced tsconfig doesn't exist, ignore it
|
|
491
|
+
continue;
|
|
440
492
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
function resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
|
|
445
|
-
walkProjectReferences(tsConfig, workspaceRoot, projectRoot, (configPath, config) => {
|
|
446
|
-
if (isExternalProjectReference(configPath, workspaceRoot, projectRoot)) {
|
|
447
|
-
projectReferences[configPath] = config;
|
|
493
|
+
if (isExternalProjectReference(refConfigPath, workspaceRoot, projectRoot)) {
|
|
494
|
+
continue;
|
|
448
495
|
}
|
|
449
|
-
|
|
450
|
-
|
|
496
|
+
if (!refConfigPath.endsWith('.json')) {
|
|
497
|
+
refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
|
|
498
|
+
}
|
|
499
|
+
projectReferences[refConfigPath] = retrieveTsConfigFromCache(refConfigPath, workspaceRoot);
|
|
500
|
+
resolveInternalProjectReferences(projectReferences[refConfigPath], workspaceRoot, projectRoot, projectReferences);
|
|
501
|
+
}
|
|
451
502
|
return projectReferences;
|
|
452
503
|
}
|
|
453
|
-
function
|
|
454
|
-
projectReferences = {}) {
|
|
504
|
+
function resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
|
|
455
505
|
if (!tsConfig.projectReferences?.length) {
|
|
456
506
|
return projectReferences;
|
|
457
507
|
}
|
|
@@ -465,13 +515,11 @@ projectReferences = {}) {
|
|
|
465
515
|
// the referenced tsconfig doesn't exist, ignore it
|
|
466
516
|
continue;
|
|
467
517
|
}
|
|
468
|
-
if (
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (result !== false) {
|
|
474
|
-
walkProjectReferences(refTsConfig, workspaceRoot, projectRoot, visitor);
|
|
518
|
+
if (isExternalProjectReference(refConfigPath, workspaceRoot, projectRoot)) {
|
|
519
|
+
if (!refConfigPath.endsWith('.json')) {
|
|
520
|
+
refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
|
|
521
|
+
}
|
|
522
|
+
projectReferences[refConfigPath] = retrieveTsConfigFromCache(refConfigPath, workspaceRoot);
|
|
475
523
|
}
|
|
476
524
|
}
|
|
477
525
|
return projectReferences;
|
|
@@ -497,7 +545,7 @@ function hasExternalProjectReferences(tsConfigPath, tsConfig, workspaceRoot, pro
|
|
|
497
545
|
if (!refConfigPath.endsWith('.json')) {
|
|
498
546
|
refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
|
|
499
547
|
}
|
|
500
|
-
const refTsConfig =
|
|
548
|
+
const refTsConfig = retrieveTsConfigFromCache(refConfigPath, workspaceRoot);
|
|
501
549
|
const result = hasExternalProjectReferences(refConfigPath, refTsConfig, workspaceRoot, projectRoot, seen);
|
|
502
550
|
if (result) {
|
|
503
551
|
return true;
|
|
@@ -506,21 +554,28 @@ function hasExternalProjectReferences(tsConfigPath, tsConfig, workspaceRoot, pro
|
|
|
506
554
|
return false;
|
|
507
555
|
}
|
|
508
556
|
function isExternalProjectReference(refTsConfigPath, workspaceRoot, projectRoot) {
|
|
557
|
+
const relativePath = posix.relative(workspaceRoot, refTsConfigPath);
|
|
558
|
+
if (cache.isExternalProjectReference[relativePath] !== undefined) {
|
|
559
|
+
return cache.isExternalProjectReference[relativePath];
|
|
560
|
+
}
|
|
509
561
|
const absoluteProjectRoot = (0, node_path_1.join)(workspaceRoot, projectRoot);
|
|
510
562
|
let currentPath = getTsConfigDirName(refTsConfigPath);
|
|
511
563
|
if ((0, node_path_1.relative)(absoluteProjectRoot, currentPath).startsWith('..')) {
|
|
512
564
|
// it's outside of the project root, so it's an external project reference
|
|
565
|
+
cache.isExternalProjectReference[relativePath] = true;
|
|
513
566
|
return true;
|
|
514
567
|
}
|
|
515
568
|
while (currentPath !== absoluteProjectRoot) {
|
|
516
569
|
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(currentPath, 'package.json')) ||
|
|
517
570
|
(0, node_fs_1.existsSync)((0, node_path_1.join)(currentPath, 'project.json'))) {
|
|
518
571
|
// it's inside a nested project root, so it's and external project reference
|
|
572
|
+
cache.isExternalProjectReference[relativePath] = true;
|
|
519
573
|
return true;
|
|
520
574
|
}
|
|
521
575
|
currentPath = (0, node_path_1.dirname)(currentPath);
|
|
522
576
|
}
|
|
523
577
|
// it's inside the project root, so it's an internal project reference
|
|
578
|
+
cache.isExternalProjectReference[relativePath] = false;
|
|
524
579
|
return false;
|
|
525
580
|
}
|
|
526
581
|
function getTsConfigDirName(tsConfigPath) {
|
|
@@ -528,19 +583,79 @@ function getTsConfigDirName(tsConfigPath) {
|
|
|
528
583
|
? (0, node_path_1.dirname)(tsConfigPath)
|
|
529
584
|
: (0, node_path_1.normalize)(tsConfigPath);
|
|
530
585
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
586
|
+
function retrieveTsConfigFromCache(tsConfigPath, workspaceRoot) {
|
|
587
|
+
const relativePath = posix.relative(workspaceRoot, tsConfigPath);
|
|
588
|
+
// we don't need to check the hash if it's in the cache, because we've already
|
|
589
|
+
// checked it when we initially populated the cache
|
|
590
|
+
return tsConfigCache[relativePath]
|
|
591
|
+
? tsConfigCache[relativePath].data
|
|
592
|
+
: readTsConfigAndCache(tsConfigPath, workspaceRoot);
|
|
593
|
+
}
|
|
594
|
+
function initializeTsConfigCache(configFilePaths, workspaceRoot) {
|
|
595
|
+
tsConfigCache = toAbsolutePaths(readFromCache(tsConfigCachePath), workspaceRoot);
|
|
596
|
+
// ensure hashes are checked and the cache is invalidated and populated as needed
|
|
597
|
+
for (const configFilePath of configFilePaths) {
|
|
598
|
+
const fullConfigPath = (0, node_path_1.join)(workspaceRoot, configFilePath);
|
|
599
|
+
readTsConfigAndCache(fullConfigPath, workspaceRoot);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
function readTsConfigAndCache(tsConfigPath, workspaceRoot) {
|
|
603
|
+
const relativePath = posix.relative(workspaceRoot, tsConfigPath);
|
|
604
|
+
const hash = getFileHash(tsConfigPath, workspaceRoot);
|
|
605
|
+
let extendedFilesHash;
|
|
606
|
+
if (tsConfigCache[relativePath] &&
|
|
607
|
+
tsConfigCache[relativePath].hash === hash) {
|
|
608
|
+
extendedFilesHash = getExtendedFilesHash(tsConfigCache[relativePath].data.extendedConfigFile, workspaceRoot);
|
|
609
|
+
if (tsConfigCache[relativePath].extendedFilesHash === extendedFilesHash) {
|
|
610
|
+
return tsConfigCache[relativePath].data;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
const tsConfig = readTsConfig(tsConfigPath, workspaceRoot);
|
|
614
|
+
const extendedConfigFile = tsConfig.raw?.extends
|
|
615
|
+
? resolveExtendedTsConfigPath(tsConfig.raw.extends, (0, node_path_1.dirname)(tsConfigPath))
|
|
616
|
+
: null;
|
|
617
|
+
extendedFilesHash ??= getExtendedFilesHash(extendedConfigFile, workspaceRoot);
|
|
618
|
+
tsConfigCache[relativePath] = {
|
|
619
|
+
data: {
|
|
620
|
+
options: tsConfig.options,
|
|
621
|
+
projectReferences: tsConfig.projectReferences,
|
|
622
|
+
raw: tsConfig.raw,
|
|
623
|
+
extendedConfigFile: extendedConfigFile ?? null,
|
|
624
|
+
},
|
|
625
|
+
hash,
|
|
626
|
+
extendedFilesHash,
|
|
627
|
+
};
|
|
628
|
+
return tsConfigCache[relativePath].data;
|
|
629
|
+
}
|
|
630
|
+
function getExtendedFilesHash(extendedConfigFile, workspaceRoot) {
|
|
631
|
+
const hashes = [];
|
|
632
|
+
if (!extendedConfigFile) {
|
|
633
|
+
return '';
|
|
634
|
+
}
|
|
635
|
+
if (extendedConfigFile.externalPackage) {
|
|
636
|
+
hashes.push(extendedConfigFile.externalPackage);
|
|
637
|
+
}
|
|
638
|
+
else if (extendedConfigFile.filePath) {
|
|
639
|
+
hashes.push(getFileHash(extendedConfigFile.filePath, workspaceRoot));
|
|
640
|
+
hashes.push(getExtendedFilesHash(readTsConfigAndCache(extendedConfigFile.filePath, workspaceRoot)
|
|
641
|
+
.extendedConfigFile, workspaceRoot));
|
|
642
|
+
}
|
|
643
|
+
return hashes.join('|');
|
|
540
644
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
645
|
+
let ts;
|
|
646
|
+
function readTsConfig(tsConfigPath, workspaceRoot) {
|
|
647
|
+
if (!ts) {
|
|
648
|
+
ts = require('typescript');
|
|
649
|
+
}
|
|
650
|
+
const tsSys = {
|
|
651
|
+
...ts.sys,
|
|
652
|
+
readFile: (path) => readFile(path, workspaceRoot),
|
|
653
|
+
readDirectory: () => [],
|
|
654
|
+
};
|
|
655
|
+
const readResult = ts.readConfigFile(tsConfigPath, tsSys.readFile);
|
|
656
|
+
// read with a custom host that won't read directories which is only used
|
|
657
|
+
// to identify the filenames included in the program, which we won't use
|
|
658
|
+
return ts.parseJsonConfigFileContent(readResult.config, tsSys, (0, node_path_1.dirname)(tsConfigPath));
|
|
544
659
|
}
|
|
545
660
|
function normalizePluginOptions(pluginOptions = {}) {
|
|
546
661
|
const defaultTypecheckTargetName = 'typecheck';
|
|
@@ -600,3 +715,83 @@ function resolveExtendedTsConfigPath(tsConfigPath, directory) {
|
|
|
600
715
|
return null;
|
|
601
716
|
}
|
|
602
717
|
}
|
|
718
|
+
function getFileHash(filePath, workspaceRoot) {
|
|
719
|
+
const relativePath = posix.relative(workspaceRoot, filePath);
|
|
720
|
+
if (!cache.fileHashes[relativePath]) {
|
|
721
|
+
const content = readFile(filePath, workspaceRoot);
|
|
722
|
+
cache.fileHashes[relativePath] = (0, file_hasher_1.hashArray)([content]);
|
|
723
|
+
}
|
|
724
|
+
return cache.fileHashes[relativePath];
|
|
725
|
+
}
|
|
726
|
+
function readFile(filePath, workspaceRoot) {
|
|
727
|
+
const relativePath = posix.relative(workspaceRoot, filePath);
|
|
728
|
+
if (!cache.rawFiles[relativePath]) {
|
|
729
|
+
const content = (0, node_fs_1.readFileSync)(filePath, 'utf8');
|
|
730
|
+
cache.rawFiles[relativePath] = content;
|
|
731
|
+
}
|
|
732
|
+
return cache.rawFiles[relativePath];
|
|
733
|
+
}
|
|
734
|
+
function toAbsolutePaths(cache, workspaceRoot) {
|
|
735
|
+
const updatedCache = {};
|
|
736
|
+
for (const [key, { data, extendedFilesHash, hash }] of Object.entries(cache)) {
|
|
737
|
+
updatedCache[key] = {
|
|
738
|
+
data: {
|
|
739
|
+
options: { noEmit: data.options.noEmit },
|
|
740
|
+
extendedConfigFile: data.extendedConfigFile,
|
|
741
|
+
},
|
|
742
|
+
extendedFilesHash,
|
|
743
|
+
hash,
|
|
744
|
+
};
|
|
745
|
+
if (data.options.rootDir) {
|
|
746
|
+
updatedCache[key].data.options.rootDir = (0, node_path_1.join)(workspaceRoot, data.options.rootDir);
|
|
747
|
+
}
|
|
748
|
+
if (data.options.outDir) {
|
|
749
|
+
updatedCache[key].data.options.outDir = (0, node_path_1.join)(workspaceRoot, data.options.outDir);
|
|
750
|
+
}
|
|
751
|
+
if (data.options.outFile) {
|
|
752
|
+
updatedCache[key].data.options.outFile = (0, node_path_1.join)(workspaceRoot, data.options.outFile);
|
|
753
|
+
}
|
|
754
|
+
if (data.options.tsBuildInfoFile) {
|
|
755
|
+
updatedCache[key].data.options.tsBuildInfoFile = (0, node_path_1.join)(workspaceRoot, data.options.tsBuildInfoFile);
|
|
756
|
+
}
|
|
757
|
+
if (data.extendedConfigFile?.filePath) {
|
|
758
|
+
updatedCache[key].data.extendedConfigFile.filePath = (0, node_path_1.join)(workspaceRoot, data.extendedConfigFile.filePath);
|
|
759
|
+
}
|
|
760
|
+
if (data.projectReferences) {
|
|
761
|
+
updatedCache[key].data.projectReferences = data.projectReferences.map((ref) => ({ ...ref, path: (0, node_path_1.join)(workspaceRoot, ref.path) }));
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
return updatedCache;
|
|
765
|
+
}
|
|
766
|
+
function toRelativePaths(cache, workspaceRoot) {
|
|
767
|
+
const updatedCache = {};
|
|
768
|
+
for (const [key, { data, extendedFilesHash, hash }] of Object.entries(cache)) {
|
|
769
|
+
updatedCache[key] = {
|
|
770
|
+
data: {
|
|
771
|
+
options: { noEmit: data.options.noEmit },
|
|
772
|
+
extendedConfigFile: data.extendedConfigFile,
|
|
773
|
+
},
|
|
774
|
+
extendedFilesHash,
|
|
775
|
+
hash,
|
|
776
|
+
};
|
|
777
|
+
if (data.options.rootDir) {
|
|
778
|
+
updatedCache[key].data.options.rootDir = posix.relative(workspaceRoot, data.options.rootDir);
|
|
779
|
+
}
|
|
780
|
+
if (data.options.outDir) {
|
|
781
|
+
updatedCache[key].data.options.outDir = posix.relative(workspaceRoot, data.options.outDir);
|
|
782
|
+
}
|
|
783
|
+
if (data.options.outFile) {
|
|
784
|
+
updatedCache[key].data.options.outFile = posix.relative(workspaceRoot, data.options.outFile);
|
|
785
|
+
}
|
|
786
|
+
if (data.options.tsBuildInfoFile) {
|
|
787
|
+
updatedCache[key].data.options.tsBuildInfoFile = posix.relative(workspaceRoot, data.options.tsBuildInfoFile);
|
|
788
|
+
}
|
|
789
|
+
if (data.extendedConfigFile?.filePath) {
|
|
790
|
+
updatedCache[key].data.extendedConfigFile.filePath = posix.relative(workspaceRoot, data.extendedConfigFile.filePath);
|
|
791
|
+
}
|
|
792
|
+
if (data.projectReferences) {
|
|
793
|
+
updatedCache[key].data.projectReferences = data.projectReferences.map((ref) => ({ ...ref, path: posix.relative(workspaceRoot, ref.path) }));
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
return updatedCache;
|
|
797
|
+
}
|
|
@@ -22,7 +22,7 @@ function findNpmDependencies(workspaceRoot, sourceProject, projectGraph, project
|
|
|
22
22
|
return;
|
|
23
23
|
seen?.add(currentProject.name);
|
|
24
24
|
collectDependenciesFromFileMap(workspaceRoot, currentProject, projectGraph, projectFileMap, buildTarget, options.ignoredFiles, options.useLocalPathsForWorkspaceDependencies, collectedDeps);
|
|
25
|
-
collectHelperDependencies(workspaceRoot, currentProject, projectGraph, buildTarget, collectedDeps);
|
|
25
|
+
collectHelperDependencies(workspaceRoot, currentProject, projectGraph, buildTarget, options.runtimeHelpers, collectedDeps);
|
|
26
26
|
if (options.includeTransitiveDependencies) {
|
|
27
27
|
const projectDeps = projectGraph.dependencies[currentProject.name];
|
|
28
28
|
for (const dep of projectDeps) {
|
|
@@ -114,7 +114,17 @@ function readPackageJson(project, workspaceRoot) {
|
|
|
114
114
|
return (0, devkit_1.readJsonFile)(packageJsonPath);
|
|
115
115
|
return null;
|
|
116
116
|
}
|
|
117
|
-
function collectHelperDependencies(workspaceRoot, sourceProject, projectGraph, buildTarget, npmDeps) {
|
|
117
|
+
function collectHelperDependencies(workspaceRoot, sourceProject, projectGraph, buildTarget, runtimeHelpers, npmDeps) {
|
|
118
|
+
if (runtimeHelpers?.length > 0) {
|
|
119
|
+
for (const helper of runtimeHelpers) {
|
|
120
|
+
if (!npmDeps[helper] &&
|
|
121
|
+
projectGraph.externalNodes[`npm:${helper}`]?.type === 'npm') {
|
|
122
|
+
npmDeps[helper] =
|
|
123
|
+
projectGraph.externalNodes[`npm:${helper}`].data.version;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
118
128
|
const target = sourceProject.data.targets[buildTarget];
|
|
119
129
|
if (!target)
|
|
120
130
|
return;
|
package/src/utils/npm-config.js
CHANGED
|
@@ -78,10 +78,7 @@ async function execAsync(command, cwd) {
|
|
|
78
78
|
return new Promise((resolve, reject) => {
|
|
79
79
|
(0, child_process_1.exec)(command, { cwd, windowsHide: false }, (error, stdout, stderr) => {
|
|
80
80
|
if (error) {
|
|
81
|
-
return reject(error);
|
|
82
|
-
}
|
|
83
|
-
if (stderr) {
|
|
84
|
-
return reject(stderr);
|
|
81
|
+
return reject((stderr ? `${stderr}\n` : '') + error);
|
|
85
82
|
}
|
|
86
83
|
return resolve(stdout.trim());
|
|
87
84
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type Tree } from '@nx/devkit';
|
|
2
2
|
export declare const defaultExclude: string[];
|
|
3
|
-
export declare function addSwcConfig(tree: Tree, projectDir: string, type?: 'commonjs' | 'es6', supportTsx?: boolean): void;
|
|
3
|
+
export declare function addSwcConfig(tree: Tree, projectDir: string, type?: 'commonjs' | 'es6', supportTsx?: boolean, swcName?: string, additionalExcludes?: string[]): void;
|
|
4
4
|
export declare function addSwcTestConfig(tree: Tree, projectDir: string, type?: 'commonjs' | 'es6', supportTsx?: boolean): void;
|
|
@@ -43,11 +43,11 @@ const swcOptionsString = (type = 'commonjs', exclude, supportTsx) => `{
|
|
|
43
43
|
"exclude": ${JSON.stringify(exclude)}
|
|
44
44
|
}
|
|
45
45
|
`;
|
|
46
|
-
function addSwcConfig(tree, projectDir, type = 'commonjs', supportTsx = false) {
|
|
47
|
-
const swcrcPath = (0, path_1.join)(projectDir,
|
|
46
|
+
function addSwcConfig(tree, projectDir, type = 'commonjs', supportTsx = false, swcName = '.swcrc', additionalExcludes = []) {
|
|
47
|
+
const swcrcPath = (0, path_1.join)(projectDir, swcName);
|
|
48
48
|
if (tree.exists(swcrcPath))
|
|
49
49
|
return;
|
|
50
|
-
tree.write(swcrcPath, swcOptionsString(type, exports.defaultExclude, supportTsx));
|
|
50
|
+
tree.write(swcrcPath, swcOptionsString(type, [...exports.defaultExclude, ...additionalExcludes], supportTsx));
|
|
51
51
|
}
|
|
52
52
|
function addSwcTestConfig(tree, projectDir, type = 'commonjs', supportTsx = false) {
|
|
53
53
|
const swcrcPath = (0, path_1.join)(projectDir, '.spec.swcrc');
|