@nx/js 20.5.0-beta.3 → 20.5.0-canary.20250128-e0c49d3
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 +117 -8
- package/src/plugins/jest/start-local-registry.js +2 -2
- package/src/plugins/typescript/plugin.d.ts +0 -1
- package/src/plugins/typescript/plugin.js +108 -172
- package/src/utils/find-npm-dependencies.d.ts +0 -1
- package/src/utils/find-npm-dependencies.js +2 -12
- package/src/utils/npm-config.js +4 -1
- package/src/utils/swc/add-swc-config.d.ts +1 -1
- package/src/utils/swc/add-swc-config.js +3 -3
- package/src/generators/library/utils/add-release-config.d.ts +0 -11
- package/src/generators/library/utils/add-release-config.js +0 -136
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/js",
|
|
3
|
-
"version": "20.5.0-
|
|
3
|
+
"version": "20.5.0-canary.20250128-e0c49d3",
|
|
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": "20.5.0-
|
|
43
|
-
"@nx/workspace": "20.5.0-
|
|
42
|
+
"@nx/devkit": "20.5.0-canary.20250128-e0c49d3",
|
|
43
|
+
"@nx/workspace": "20.5.0-canary.20250128-e0c49d3",
|
|
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 (
|
|
91
|
+
if (!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,6 +8,7 @@ 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");
|
|
11
12
|
const path_1 = require("path");
|
|
12
13
|
const generator_prompts_1 = require("../../utils/generator-prompts");
|
|
13
14
|
const update_package_json_1 = require("../../utils/package-json/update-package-json");
|
|
@@ -21,9 +22,9 @@ const ts_config_1 = require("../../utils/typescript/ts-config");
|
|
|
21
22
|
const ts_solution_setup_1 = require("../../utils/typescript/ts-solution-setup");
|
|
22
23
|
const versions_1 = require("../../utils/versions");
|
|
23
24
|
const init_1 = require("../init/init");
|
|
25
|
+
const generator_1 = require("../setup-verdaccio/generator");
|
|
24
26
|
const sort_fields_1 = require("../../utils/package-json/sort-fields");
|
|
25
27
|
const get_import_path_1 = require("../../utils/get-import-path");
|
|
26
|
-
const add_release_config_1 = require("./utils/add-release-config");
|
|
27
28
|
const defaultOutputDirectory = 'dist';
|
|
28
29
|
async function libraryGenerator(tree, schema) {
|
|
29
30
|
return await libraryGeneratorInternal(tree, {
|
|
@@ -53,13 +54,15 @@ async function libraryGeneratorInternal(tree, schema) {
|
|
|
53
54
|
if (!options.skipPackageJson) {
|
|
54
55
|
tasks.push(addProjectDependencies(tree, options));
|
|
55
56
|
}
|
|
57
|
+
if (options.publishable) {
|
|
58
|
+
tasks.push(await (0, generator_1.default)(tree, { ...options, skipFormat: true }));
|
|
59
|
+
}
|
|
56
60
|
if (options.bundler === 'rollup') {
|
|
57
61
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/rollup', versions_1.nxVersion);
|
|
58
62
|
await configurationGenerator(tree, {
|
|
59
63
|
project: options.name,
|
|
60
64
|
compiler: 'swc',
|
|
61
65
|
format: options.isUsingTsSolutionConfig ? ['esm'] : ['cjs', 'esm'],
|
|
62
|
-
skipFormat: true,
|
|
63
66
|
});
|
|
64
67
|
}
|
|
65
68
|
if (options.bundler === 'vite') {
|
|
@@ -147,7 +150,9 @@ async function libraryGeneratorInternal(tree, schema) {
|
|
|
147
150
|
await (0, devkit_1.formatFiles)(tree);
|
|
148
151
|
}
|
|
149
152
|
if (options.publishable) {
|
|
150
|
-
tasks.push(
|
|
153
|
+
tasks.push(() => {
|
|
154
|
+
logNxReleaseDocsInfo();
|
|
155
|
+
});
|
|
151
156
|
}
|
|
152
157
|
// Always run install to link packages.
|
|
153
158
|
if (options.isUsingTsSolutionConfig) {
|
|
@@ -214,12 +219,26 @@ async function configureProject(tree, options) {
|
|
|
214
219
|
}
|
|
215
220
|
}
|
|
216
221
|
if (options.publishable) {
|
|
217
|
-
if (options.isUsingTsSolutionConfig) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
+
if (!options.isUsingTsSolutionConfig) {
|
|
223
|
+
const packageRoot = (0, devkit_1.joinPathFragments)(defaultOutputDirectory, '{projectRoot}');
|
|
224
|
+
projectConfiguration.targets ??= {};
|
|
225
|
+
projectConfiguration.targets['nx-release-publish'] = {
|
|
226
|
+
options: {
|
|
227
|
+
packageRoot,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
projectConfiguration.release = {
|
|
231
|
+
version: {
|
|
232
|
+
generatorOptions: {
|
|
233
|
+
packageRoot,
|
|
234
|
+
// using git tags to determine the current version is required here because
|
|
235
|
+
// the version in the package root is overridden with every build
|
|
236
|
+
currentVersionResolver: 'git-tag',
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
};
|
|
222
240
|
}
|
|
241
|
+
await addProjectToNxReleaseConfig(tree, options, projectConfiguration);
|
|
223
242
|
}
|
|
224
243
|
if (!options.useProjectJson) {
|
|
225
244
|
// we want the package.json as clean as possible, with the bare minimum
|
|
@@ -910,6 +929,96 @@ function determineEntryFields(options) {
|
|
|
910
929
|
}
|
|
911
930
|
}
|
|
912
931
|
}
|
|
932
|
+
function projectsConfigMatchesProject(projectsConfig, project) {
|
|
933
|
+
if (!projectsConfig) {
|
|
934
|
+
return false;
|
|
935
|
+
}
|
|
936
|
+
if (typeof projectsConfig === 'string') {
|
|
937
|
+
projectsConfig = [projectsConfig];
|
|
938
|
+
}
|
|
939
|
+
const graph = {
|
|
940
|
+
[project.name]: project,
|
|
941
|
+
};
|
|
942
|
+
const matchingProjects = (0, find_matching_projects_1.findMatchingProjects)(projectsConfig, graph);
|
|
943
|
+
return matchingProjects.includes(project.name);
|
|
944
|
+
}
|
|
945
|
+
async function addProjectToNxReleaseConfig(tree, options, projectConfiguration) {
|
|
946
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
947
|
+
const addPreVersionCommand = () => {
|
|
948
|
+
const pmc = (0, devkit_1.getPackageManagerCommand)();
|
|
949
|
+
nxJson.release = {
|
|
950
|
+
...nxJson.release,
|
|
951
|
+
version: {
|
|
952
|
+
preVersionCommand: `${pmc.dlx} nx run-many -t build`,
|
|
953
|
+
...nxJson.release?.version,
|
|
954
|
+
},
|
|
955
|
+
};
|
|
956
|
+
};
|
|
957
|
+
if (!nxJson.release || (!nxJson.release.projects && !nxJson.release.groups)) {
|
|
958
|
+
// skip adding any projects configuration since the new project should be
|
|
959
|
+
// automatically included by nx release's default project detection logic
|
|
960
|
+
addPreVersionCommand();
|
|
961
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
const project = {
|
|
965
|
+
name: options.name,
|
|
966
|
+
type: 'lib',
|
|
967
|
+
data: {
|
|
968
|
+
root: projectConfiguration.root,
|
|
969
|
+
tags: projectConfiguration.tags,
|
|
970
|
+
},
|
|
971
|
+
};
|
|
972
|
+
if (projectsConfigMatchesProject(nxJson.release.projects, project)) {
|
|
973
|
+
devkit_1.output.log({
|
|
974
|
+
title: `Project already included in existing release configuration`,
|
|
975
|
+
});
|
|
976
|
+
addPreVersionCommand();
|
|
977
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
if (Array.isArray(nxJson.release.projects)) {
|
|
981
|
+
nxJson.release.projects.push(options.name);
|
|
982
|
+
addPreVersionCommand();
|
|
983
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
984
|
+
devkit_1.output.log({
|
|
985
|
+
title: `Added project to existing release configuration`,
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
if (nxJson.release.groups) {
|
|
989
|
+
const allGroups = Object.entries(nxJson.release.groups);
|
|
990
|
+
for (const [name, group] of allGroups) {
|
|
991
|
+
if (projectsConfigMatchesProject(group.projects, project)) {
|
|
992
|
+
addPreVersionCommand();
|
|
993
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
994
|
+
return `Project already included in existing release configuration for group ${name}`;
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
devkit_1.output.warn({
|
|
998
|
+
title: `Could not find a release group that includes ${options.name}`,
|
|
999
|
+
bodyLines: [
|
|
1000
|
+
`Ensure that ${options.name} is included in a release group's "projects" list in nx.json so it can be published with "nx release"`,
|
|
1001
|
+
],
|
|
1002
|
+
});
|
|
1003
|
+
addPreVersionCommand();
|
|
1004
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
if (typeof nxJson.release.projects === 'string') {
|
|
1008
|
+
nxJson.release.projects = [nxJson.release.projects, options.name];
|
|
1009
|
+
addPreVersionCommand();
|
|
1010
|
+
(0, devkit_1.writeJson)(tree, 'nx.json', nxJson);
|
|
1011
|
+
devkit_1.output.log({
|
|
1012
|
+
title: `Added project to existing release configuration`,
|
|
1013
|
+
});
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
function logNxReleaseDocsInfo() {
|
|
1018
|
+
devkit_1.output.log({
|
|
1019
|
+
title: `📦 To learn how to publish this library, see https://nx.dev/core-features/manage-releases.`,
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
913
1022
|
function findRootJestPreset(tree) {
|
|
914
1023
|
const ext = ['js', 'cjs', 'mjs'].find((ext) => tree.exists(`jest.preset.${ext}`));
|
|
915
1024
|
return ext ? `jest.preset.${ext}` : null;
|
|
@@ -31,7 +31,7 @@ function startLocalRegistry({ localRegistryTarget, storage, verbose, clearStorag
|
|
|
31
31
|
const registry = `http://${listenAddress}:${port}`;
|
|
32
32
|
console.log(`Local registry started on ${registry}`);
|
|
33
33
|
process.env.npm_config_registry = registry;
|
|
34
|
-
(0, child_process_1.execSync)(`npm config set //${listenAddress}:${port}/:_authToken "secretVerdaccioToken"
|
|
34
|
+
(0, child_process_1.execSync)(`npm config set //${listenAddress}:${port}/:_authToken "secretVerdaccioToken"`, {
|
|
35
35
|
windowsHide: false,
|
|
36
36
|
});
|
|
37
37
|
// yarnv1
|
|
@@ -42,7 +42,7 @@ function startLocalRegistry({ localRegistryTarget, storage, verbose, clearStorag
|
|
|
42
42
|
console.log('Set npm and yarn config registry to ' + registry);
|
|
43
43
|
resolve(() => {
|
|
44
44
|
childProcess.kill();
|
|
45
|
-
(0, child_process_1.execSync)(`npm config delete //${listenAddress}:${port}/:_authToken
|
|
45
|
+
(0, child_process_1.execSync)(`npm config delete //${listenAddress}:${port}/:_authToken`, {
|
|
46
46
|
windowsHide: false,
|
|
47
47
|
});
|
|
48
48
|
});
|
|
@@ -6,27 +6,20 @@ 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");
|
|
10
9
|
const file_hasher_1 = require("nx/src/hasher/file-hasher");
|
|
11
10
|
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
|
12
11
|
const lock_file_1 = require("nx/src/plugins/js/lock-file/lock-file");
|
|
13
12
|
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
|
-
|
|
20
|
-
return process.env.NX_CACHE_PROJECT_GRAPH !== 'false'
|
|
21
|
-
? (0, devkit_1.readJsonFile)(cachePath)
|
|
22
|
-
: {};
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return {};
|
|
26
|
-
}
|
|
16
|
+
function readTargetsCache(cachePath) {
|
|
17
|
+
return process.env.NX_CACHE_PROJECT_GRAPH !== 'false' && (0, node_fs_1.existsSync)(cachePath)
|
|
18
|
+
? (0, devkit_1.readJsonFile)(cachePath)
|
|
19
|
+
: {};
|
|
27
20
|
}
|
|
28
|
-
function
|
|
29
|
-
(0, devkit_1.writeJsonFile)(cachePath,
|
|
21
|
+
function writeTargetsToCache(cachePath, results) {
|
|
22
|
+
(0, devkit_1.writeJsonFile)(cachePath, results);
|
|
30
23
|
}
|
|
31
24
|
/**
|
|
32
25
|
* @deprecated The 'createDependencies' function is now a no-op. This functionality is included in 'createNodesV2'.
|
|
@@ -41,33 +34,15 @@ exports.createNodesV2 = [
|
|
|
41
34
|
tsConfigGlob,
|
|
42
35
|
async (configFilePaths, options, context) => {
|
|
43
36
|
const optionsHash = (0, file_hasher_1.hashObject)(options);
|
|
44
|
-
const
|
|
45
|
-
const targetsCache =
|
|
46
|
-
tsConfigCache =
|
|
47
|
-
readFromCache(tsConfigCachePath);
|
|
37
|
+
const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `tsc-${optionsHash}.hash`);
|
|
38
|
+
const targetsCache = readTargetsCache(cachePath);
|
|
48
39
|
const normalizedOptions = normalizePluginOptions(options);
|
|
49
|
-
const
|
|
50
|
-
const { configFilePaths: validConfigFilePaths, hashes, projectRoots, } = await resolveValidConfigFilesAndHashes(configFilePaths, optionsHash, lockFileHash, context);
|
|
40
|
+
const lockFileName = (0, lock_file_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot));
|
|
51
41
|
try {
|
|
52
|
-
return await (0, devkit_1.createNodesFromFiles)((
|
|
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);
|
|
42
|
+
return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, lockFileName, targetsCache), configFilePaths, normalizedOptions, context);
|
|
67
43
|
}
|
|
68
44
|
finally {
|
|
69
|
-
|
|
70
|
-
writeToCache(tsConfigCachePath, tsConfigCache);
|
|
45
|
+
writeTargetsToCache(cachePath, targetsCache);
|
|
71
46
|
}
|
|
72
47
|
},
|
|
73
48
|
];
|
|
@@ -75,93 +50,28 @@ exports.createNodes = [
|
|
|
75
50
|
tsConfigGlob,
|
|
76
51
|
async (configFilePath, options, context) => {
|
|
77
52
|
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
|
-
}
|
|
82
53
|
const normalizedOptions = normalizePluginOptions(options);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const { targets } = buildTscTargets((0, node_path_1.join)(context.workspaceRoot, configFilePath), projectRoot, normalizedOptions, context);
|
|
86
|
-
return {
|
|
87
|
-
projects: {
|
|
88
|
-
[projectRoot]: {
|
|
89
|
-
projectType: 'library',
|
|
90
|
-
targets,
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
};
|
|
54
|
+
const lockFileName = (0, lock_file_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot));
|
|
55
|
+
return createNodesInternal(configFilePath, normalizedOptions, context, lockFileName, {});
|
|
94
56
|
},
|
|
95
57
|
];
|
|
96
|
-
async function
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const projectRoots = [];
|
|
100
|
-
const fileHashesCache = {};
|
|
101
|
-
for await (const configFilePath of configFilePaths) {
|
|
102
|
-
const projectRoot = (0, node_path_1.dirname)(configFilePath);
|
|
103
|
-
if (!checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context)) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
projectRoots.push(projectRoot);
|
|
107
|
-
validConfigFilePaths.push(configFilePath);
|
|
108
|
-
hashes.push(await getConfigFileHash(configFilePath, context.workspaceRoot, projectRoot, optionsHash, lockFileHash, fileHashesCache));
|
|
109
|
-
}
|
|
110
|
-
return { configFilePaths: validConfigFilePaths, hashes, projectRoots };
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* The cache key is composed by:
|
|
114
|
-
* - hashes of the content of the relevant files that can affect what's inferred by the plugin:
|
|
115
|
-
* - current config file
|
|
116
|
-
* - config files extended by the current config file (recursively up to the root config file)
|
|
117
|
-
* - referenced config files that are internal to the owning Nx project of the current config file,
|
|
118
|
-
* or is a shallow external reference of the owning Nx project
|
|
119
|
-
* - lock file
|
|
120
|
-
* - project's package.json
|
|
121
|
-
* - hash of the plugin options
|
|
122
|
-
* - current config file path
|
|
123
|
-
*/
|
|
124
|
-
async function getConfigFileHash(configFilePath, workspaceRoot, projectRoot, optionsHash, lockFileHash, fileHashesCache) {
|
|
125
|
-
const fullConfigPath = (0, node_path_1.join)(workspaceRoot, configFilePath);
|
|
126
|
-
const tsConfig = readCachedTsConfig(fullConfigPath, workspaceRoot);
|
|
127
|
-
const extendedConfigFiles = getExtendedConfigFiles(fullConfigPath, tsConfig, workspaceRoot);
|
|
128
|
-
const internalReferencedFiles = resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot);
|
|
129
|
-
const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot);
|
|
130
|
-
let packageJson = null;
|
|
131
|
-
try {
|
|
132
|
-
packageJson = (0, devkit_1.readJsonFile)((0, node_path_1.join)(workspaceRoot, projectRoot, 'package.json'));
|
|
133
|
-
}
|
|
134
|
-
catch { }
|
|
135
|
-
return (0, file_hasher_1.hashArray)([
|
|
136
|
-
...[
|
|
137
|
-
fullConfigPath,
|
|
138
|
-
...extendedConfigFiles.files,
|
|
139
|
-
...Object.keys(internalReferencedFiles),
|
|
140
|
-
...Object.keys(externalProjectReferences),
|
|
141
|
-
].map((file) => {
|
|
142
|
-
fileHashesCache[file] ??= (0, file_hasher_1.hashFile)(file);
|
|
143
|
-
return fileHashesCache[file];
|
|
144
|
-
}),
|
|
145
|
-
lockFileHash,
|
|
146
|
-
optionsHash,
|
|
147
|
-
...(packageJson ? [(0, file_hasher_1.hashObject)(packageJson)] : []),
|
|
148
|
-
]);
|
|
149
|
-
}
|
|
150
|
-
function checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context) {
|
|
58
|
+
async function createNodesInternal(configFilePath, options, context, lockFileName, targetsCache) {
|
|
59
|
+
const projectRoot = (0, node_path_1.dirname)(configFilePath);
|
|
60
|
+
const fullConfigPath = (0, devkit_1.joinPathFragments)(context.workspaceRoot, configFilePath);
|
|
151
61
|
// Do not create a project for the workspace root tsconfig files.
|
|
152
62
|
if (projectRoot === '.') {
|
|
153
|
-
return
|
|
63
|
+
return {};
|
|
154
64
|
}
|
|
155
65
|
// Do not create a project if package.json and project.json isn't there.
|
|
156
66
|
const siblingFiles = (0, node_fs_1.readdirSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot));
|
|
157
67
|
if (!siblingFiles.includes('package.json') &&
|
|
158
68
|
!siblingFiles.includes('project.json')) {
|
|
159
|
-
return
|
|
69
|
+
return {};
|
|
160
70
|
}
|
|
161
71
|
// Do not create a project if it's not a tsconfig.json and there is no tsconfig.json in the same directory
|
|
162
72
|
if ((0, node_path_1.basename)(configFilePath) !== 'tsconfig.json' &&
|
|
163
73
|
!siblingFiles.includes('tsconfig.json')) {
|
|
164
|
-
return
|
|
74
|
+
return {};
|
|
165
75
|
}
|
|
166
76
|
// Do not create project for Next.js projects since they are not compatible with
|
|
167
77
|
// project references and typecheck will fail.
|
|
@@ -169,14 +79,58 @@ function checkIfConfigFileShouldBeProject(configFilePath, projectRoot, context)
|
|
|
169
79
|
siblingFiles.includes('next.config.cjs') ||
|
|
170
80
|
siblingFiles.includes('next.config.mjs') ||
|
|
171
81
|
siblingFiles.includes('next.config.ts')) {
|
|
172
|
-
return
|
|
82
|
+
return {};
|
|
173
83
|
}
|
|
174
|
-
|
|
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
|
+
};
|
|
175
124
|
}
|
|
176
125
|
function buildTscTargets(configFilePath, projectRoot, options, context) {
|
|
177
126
|
const targets = {};
|
|
178
127
|
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
179
|
-
const tsConfig = readCachedTsConfig(configFilePath
|
|
128
|
+
const tsConfig = readCachedTsConfig(configFilePath);
|
|
129
|
+
// TODO: check whether we want to always run with --pretty --verbose, it makes replacing scripts harder
|
|
130
|
+
// `--verbose` conflicts with `tsc -b --clean`, might be another reason for not using it, it would
|
|
131
|
+
// prevent users from running the task with `--clean` flag.
|
|
132
|
+
// Should we consider creating a different optional target for `--clean`?
|
|
133
|
+
// Should we consider having a plugin option to disable `--pretty` and `--verbose`?
|
|
180
134
|
let internalProjectReferences;
|
|
181
135
|
// Typecheck target
|
|
182
136
|
if ((0, node_path_1.basename)(configFilePath) === 'tsconfig.json' && options.typecheck) {
|
|
@@ -184,7 +138,7 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
|
|
|
184
138
|
const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
|
|
185
139
|
const targetName = options.typecheck.targetName;
|
|
186
140
|
if (!targets[targetName]) {
|
|
187
|
-
let command = `tsc --build --emitDeclarationOnly
|
|
141
|
+
let command = `tsc --build --emitDeclarationOnly --pretty --verbose`;
|
|
188
142
|
if (tsConfig.options.noEmit ||
|
|
189
143
|
Object.values(internalProjectReferences).some((ref) => ref.options.noEmit) ||
|
|
190
144
|
Object.values(externalProjectReferences).some((ref) => ref.options.noEmit)) {
|
|
@@ -220,7 +174,7 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
|
|
|
220
174
|
const targetName = options.build.targetName;
|
|
221
175
|
targets[targetName] = {
|
|
222
176
|
dependsOn: [`^${targetName}`],
|
|
223
|
-
command: `tsc --build ${options.build.configName}
|
|
177
|
+
command: `tsc --build ${options.build.configName} --pretty --verbose`,
|
|
224
178
|
options: { cwd: projectRoot },
|
|
225
179
|
cache: true,
|
|
226
180
|
inputs: getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, context.workspaceRoot, projectRoot),
|
|
@@ -247,7 +201,7 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
|
|
|
247
201
|
function getInputs(namedInputs, configFilePath, tsConfig, internalProjectReferences, workspaceRoot, projectRoot) {
|
|
248
202
|
const configFiles = new Set();
|
|
249
203
|
const externalDependencies = ['typescript'];
|
|
250
|
-
const extendedConfigFiles = getExtendedConfigFiles(configFilePath, tsConfig
|
|
204
|
+
const extendedConfigFiles = getExtendedConfigFiles(configFilePath, tsConfig);
|
|
251
205
|
extendedConfigFiles.files.forEach((configPath) => {
|
|
252
206
|
configFiles.add(configPath);
|
|
253
207
|
});
|
|
@@ -345,9 +299,7 @@ function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspa
|
|
|
345
299
|
outputs.add(pathToInputOrOutput((0, devkit_1.joinPathFragments)(config.options.outDir, relativeRootDir, `*.tsbuildinfo`), workspaceRoot, projectRoot));
|
|
346
300
|
}
|
|
347
301
|
}
|
|
348
|
-
else if (config.
|
|
349
|
-
config.raw?.files?.length ||
|
|
350
|
-
(!config.raw?.include && !config.raw?.files)) {
|
|
302
|
+
else if (config.fileNames.length) {
|
|
351
303
|
// tsc produce files in place when no outDir or outFile is set
|
|
352
304
|
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.js'));
|
|
353
305
|
outputs.add((0, devkit_1.joinPathFragments)('{projectRoot}', '**/*.cjs'));
|
|
@@ -460,7 +412,7 @@ function pathToInputOrOutput(path, workspaceRoot, projectRoot) {
|
|
|
460
412
|
}
|
|
461
413
|
return (0, devkit_1.joinPathFragments)('{projectRoot}', pathRelativeToProjectRoot);
|
|
462
414
|
}
|
|
463
|
-
function getExtendedConfigFiles(tsConfigPath, tsConfig
|
|
415
|
+
function getExtendedConfigFiles(tsConfigPath, tsConfig) {
|
|
464
416
|
const extendedConfigFiles = new Set();
|
|
465
417
|
const extendedExternalPackages = new Set();
|
|
466
418
|
let currentConfigPath = tsConfigPath;
|
|
@@ -475,7 +427,7 @@ function getExtendedConfigFiles(tsConfigPath, tsConfig, workspaceRoot) {
|
|
|
475
427
|
break;
|
|
476
428
|
}
|
|
477
429
|
extendedConfigFiles.add(extendedConfigPath.filePath);
|
|
478
|
-
currentConfig = readCachedTsConfig(extendedConfigPath.filePath
|
|
430
|
+
currentConfig = readCachedTsConfig(extendedConfigPath.filePath);
|
|
479
431
|
currentConfigPath = extendedConfigPath.filePath;
|
|
480
432
|
}
|
|
481
433
|
return {
|
|
@@ -484,31 +436,27 @@ function getExtendedConfigFiles(tsConfigPath, tsConfig, workspaceRoot) {
|
|
|
484
436
|
};
|
|
485
437
|
}
|
|
486
438
|
function resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
for (const ref of tsConfig.projectReferences) {
|
|
491
|
-
let refConfigPath = ref.path;
|
|
492
|
-
if (projectReferences[refConfigPath]) {
|
|
493
|
-
// Already resolved
|
|
494
|
-
continue;
|
|
495
|
-
}
|
|
496
|
-
if (!(0, node_fs_1.existsSync)(refConfigPath)) {
|
|
497
|
-
// the referenced tsconfig doesn't exist, ignore it
|
|
498
|
-
continue;
|
|
439
|
+
walkProjectReferences(tsConfig, workspaceRoot, projectRoot, (configPath, config) => {
|
|
440
|
+
if (isExternalProjectReference(configPath, workspaceRoot, projectRoot)) {
|
|
441
|
+
return false;
|
|
499
442
|
}
|
|
500
|
-
|
|
501
|
-
|
|
443
|
+
else {
|
|
444
|
+
projectReferences[configPath] = config;
|
|
502
445
|
}
|
|
503
|
-
|
|
504
|
-
refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
|
|
505
|
-
}
|
|
506
|
-
projectReferences[refConfigPath] = readCachedTsConfig(refConfigPath, workspaceRoot);
|
|
507
|
-
resolveInternalProjectReferences(projectReferences[refConfigPath], workspaceRoot, projectRoot, projectReferences);
|
|
508
|
-
}
|
|
446
|
+
});
|
|
509
447
|
return projectReferences;
|
|
510
448
|
}
|
|
511
449
|
function resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
|
|
450
|
+
walkProjectReferences(tsConfig, workspaceRoot, projectRoot, (configPath, config) => {
|
|
451
|
+
if (isExternalProjectReference(configPath, workspaceRoot, projectRoot)) {
|
|
452
|
+
projectReferences[configPath] = config;
|
|
453
|
+
}
|
|
454
|
+
return false;
|
|
455
|
+
});
|
|
456
|
+
return projectReferences;
|
|
457
|
+
}
|
|
458
|
+
function walkProjectReferences(tsConfig, workspaceRoot, projectRoot, visitor, // false stops recursion
|
|
459
|
+
projectReferences = {}) {
|
|
512
460
|
if (!tsConfig.projectReferences?.length) {
|
|
513
461
|
return projectReferences;
|
|
514
462
|
}
|
|
@@ -522,11 +470,13 @@ function resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projec
|
|
|
522
470
|
// the referenced tsconfig doesn't exist, ignore it
|
|
523
471
|
continue;
|
|
524
472
|
}
|
|
525
|
-
if (
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
473
|
+
if (!refConfigPath.endsWith('.json')) {
|
|
474
|
+
refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
|
|
475
|
+
}
|
|
476
|
+
const refTsConfig = readCachedTsConfig(refConfigPath);
|
|
477
|
+
const result = visitor(refConfigPath, refTsConfig);
|
|
478
|
+
if (result !== false) {
|
|
479
|
+
walkProjectReferences(refTsConfig, workspaceRoot, projectRoot, visitor);
|
|
530
480
|
}
|
|
531
481
|
}
|
|
532
482
|
return projectReferences;
|
|
@@ -552,7 +502,7 @@ function hasExternalProjectReferences(tsConfigPath, tsConfig, workspaceRoot, pro
|
|
|
552
502
|
if (!refConfigPath.endsWith('.json')) {
|
|
553
503
|
refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
|
|
554
504
|
}
|
|
555
|
-
const refTsConfig = readCachedTsConfig(refConfigPath
|
|
505
|
+
const refTsConfig = readCachedTsConfig(refConfigPath);
|
|
556
506
|
const result = hasExternalProjectReferences(refConfigPath, refTsConfig, workspaceRoot, projectRoot, seen);
|
|
557
507
|
if (result) {
|
|
558
508
|
return true;
|
|
@@ -583,32 +533,19 @@ function getTsConfigDirName(tsConfigPath) {
|
|
|
583
533
|
? (0, node_path_1.dirname)(tsConfigPath)
|
|
584
534
|
: (0, node_path_1.normalize)(tsConfigPath);
|
|
585
535
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
const
|
|
589
|
-
if (tsConfigCache
|
|
590
|
-
return tsConfigCache
|
|
591
|
-
}
|
|
592
|
-
const tsConfig = readTsConfig(tsConfigPath);
|
|
593
|
-
tsConfigCache
|
|
594
|
-
data: {
|
|
595
|
-
options: tsConfig.options,
|
|
596
|
-
projectReferences: tsConfig.projectReferences,
|
|
597
|
-
raw: tsConfig.raw,
|
|
598
|
-
},
|
|
599
|
-
timestamp,
|
|
600
|
-
};
|
|
536
|
+
const tsConfigCache = new Map();
|
|
537
|
+
function readCachedTsConfig(tsConfigPath) {
|
|
538
|
+
const cacheKey = getTsConfigCacheKey(tsConfigPath);
|
|
539
|
+
if (tsConfigCache.has(cacheKey)) {
|
|
540
|
+
return tsConfigCache.get(cacheKey);
|
|
541
|
+
}
|
|
542
|
+
const tsConfig = (0, ts_config_1.readTsConfig)(tsConfigPath);
|
|
543
|
+
tsConfigCache.set(cacheKey, tsConfig);
|
|
601
544
|
return tsConfig;
|
|
602
545
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
ts = require('typescript');
|
|
607
|
-
}
|
|
608
|
-
const readResult = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
|
|
609
|
-
// read with a custom host that won't read directories which is only used
|
|
610
|
-
// to identify the filenames included in the program, which we won't use
|
|
611
|
-
return ts.parseJsonConfigFileContent(readResult.config, { ...ts.sys, readDirectory: () => [] }, (0, node_path_1.dirname)(tsConfigPath));
|
|
546
|
+
function getTsConfigCacheKey(tsConfigPath) {
|
|
547
|
+
const timestamp = (0, node_fs_1.statSync)(tsConfigPath).mtimeMs;
|
|
548
|
+
return `${tsConfigPath}-${timestamp}`;
|
|
612
549
|
}
|
|
613
550
|
function normalizePluginOptions(pluginOptions = {}) {
|
|
614
551
|
const defaultTypecheckTargetName = 'typecheck';
|
|
@@ -647,7 +584,6 @@ function normalizePluginOptions(pluginOptions = {}) {
|
|
|
647
584
|
return {
|
|
648
585
|
typecheck,
|
|
649
586
|
build,
|
|
650
|
-
verboseOutput: pluginOptions.verboseOutput ?? false,
|
|
651
587
|
};
|
|
652
588
|
}
|
|
653
589
|
function resolveExtendedTsConfigPath(tsConfigPath, directory) {
|
|
@@ -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,
|
|
25
|
+
collectHelperDependencies(workspaceRoot, currentProject, projectGraph, buildTarget, collectedDeps);
|
|
26
26
|
if (options.includeTransitiveDependencies) {
|
|
27
27
|
const projectDeps = projectGraph.dependencies[currentProject.name];
|
|
28
28
|
for (const dep of projectDeps) {
|
|
@@ -114,17 +114,7 @@ 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,
|
|
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
|
-
}
|
|
117
|
+
function collectHelperDependencies(workspaceRoot, sourceProject, projectGraph, buildTarget, npmDeps) {
|
|
128
118
|
const target = sourceProject.data.targets[buildTarget];
|
|
129
119
|
if (!target)
|
|
130
120
|
return;
|
package/src/utils/npm-config.js
CHANGED
|
@@ -78,7 +78,10 @@ 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(
|
|
81
|
+
return reject(error);
|
|
82
|
+
}
|
|
83
|
+
if (stderr) {
|
|
84
|
+
return reject(stderr);
|
|
82
85
|
}
|
|
83
86
|
return resolve(stdout.trim());
|
|
84
87
|
});
|
|
@@ -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
|
|
3
|
+
export declare function addSwcConfig(tree: Tree, projectDir: string, type?: 'commonjs' | 'es6', supportTsx?: boolean): 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) {
|
|
47
|
+
const swcrcPath = (0, path_1.join)(projectDir, '.swcrc');
|
|
48
48
|
if (tree.exists(swcrcPath))
|
|
49
49
|
return;
|
|
50
|
-
tree.write(swcrcPath, swcOptionsString(type,
|
|
50
|
+
tree.write(swcrcPath, swcOptionsString(type, exports.defaultExclude, supportTsx));
|
|
51
51
|
}
|
|
52
52
|
function addSwcTestConfig(tree, projectDir, type = 'commonjs', supportTsx = false) {
|
|
53
53
|
const swcrcPath = (0, path_1.join)(projectDir, '.spec.swcrc');
|
|
@@ -1,11 +0,0 @@
|
|
|
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>;
|
|
@@ -1,136 +0,0 @@
|
|
|
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
|
-
}
|