@nx/js 20.5.0-rc.1 → 20.5.0-rc.3
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/plugins/typescript/plugin.js +1 -82
- package/src/plugins/typescript/util.d.ts +8 -0
- package/src/plugins/typescript/util.js +73 -0
- package/src/utils/buildable-libs-utils.js +8 -7
- package/src/utils/typescript/ts-solution-setup.d.ts +1 -1
- package/src/utils/typescript/ts-solution-setup.js +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/js",
|
|
3
|
-
"version": "20.5.0-rc.
|
|
3
|
+
"version": "20.5.0-rc.3",
|
|
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-rc.
|
|
43
|
-
"@nx/workspace": "20.5.0-rc.
|
|
42
|
+
"@nx/devkit": "20.5.0-rc.3",
|
|
43
|
+
"@nx/workspace": "20.5.0-rc.3",
|
|
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",
|
|
@@ -216,7 +216,7 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
|
|
|
216
216
|
// Build target
|
|
217
217
|
if (options.build &&
|
|
218
218
|
(0, node_path_1.basename)(configFilePath) === options.build.configName &&
|
|
219
|
-
isValidPackageJsonBuildConfig(tsConfig, context.workspaceRoot, projectRoot)) {
|
|
219
|
+
(0, util_1.isValidPackageJsonBuildConfig)(tsConfig, context.workspaceRoot, projectRoot)) {
|
|
220
220
|
internalProjectReferences ??= resolveInternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
|
|
221
221
|
const targetName = options.build.targetName;
|
|
222
222
|
targets[targetName] = {
|
|
@@ -371,87 +371,6 @@ function getOutputs(configFilePath, tsConfig, internalProjectReferences, workspa
|
|
|
371
371
|
});
|
|
372
372
|
return Array.from(outputs);
|
|
373
373
|
}
|
|
374
|
-
/**
|
|
375
|
-
* Validates the build configuration of a `package.json` file by ensuring that paths in the `exports`, `module`,
|
|
376
|
-
* and `main` fields reference valid output paths within the `outDir` defined in the TypeScript configuration.
|
|
377
|
-
* Priority is given to the `exports` field, specifically the `.` export if defined. If `exports` is not defined,
|
|
378
|
-
* the function falls back to validating `main` and `module` fields. If `outFile` is specified, it validates that the file
|
|
379
|
-
* is located within the output directory.
|
|
380
|
-
* If no `package.json` file exists, it assumes the configuration is valid.
|
|
381
|
-
*
|
|
382
|
-
* @param tsConfig The TypeScript configuration object.
|
|
383
|
-
* @param workspaceRoot The workspace root path.
|
|
384
|
-
* @param projectRoot The project root path.
|
|
385
|
-
* @returns `true` if the package has a valid build configuration; otherwise, `false`.
|
|
386
|
-
*/
|
|
387
|
-
function isValidPackageJsonBuildConfig(tsConfig, workspaceRoot, projectRoot) {
|
|
388
|
-
const packageJsonPath = (0, node_path_1.join)(workspaceRoot, projectRoot, 'package.json');
|
|
389
|
-
if (!(0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
390
|
-
// If the package.json file does not exist.
|
|
391
|
-
// Assume it's valid because it would be using `project.json` instead.
|
|
392
|
-
return true;
|
|
393
|
-
}
|
|
394
|
-
const packageJson = (0, devkit_1.readJsonFile)(packageJsonPath);
|
|
395
|
-
const outDir = tsConfig.options.outFile
|
|
396
|
-
? (0, node_path_1.dirname)(tsConfig.options.outFile)
|
|
397
|
-
: tsConfig.options.outDir;
|
|
398
|
-
const resolvedOutDir = outDir
|
|
399
|
-
? (0, node_path_1.resolve)(workspaceRoot, projectRoot, outDir)
|
|
400
|
-
: undefined;
|
|
401
|
-
const isPathSourceFile = (path) => {
|
|
402
|
-
if (resolvedOutDir) {
|
|
403
|
-
const pathToCheck = (0, node_path_1.resolve)(workspaceRoot, projectRoot, path);
|
|
404
|
-
return !pathToCheck.startsWith(resolvedOutDir);
|
|
405
|
-
}
|
|
406
|
-
const ext = (0, node_path_1.extname)(path);
|
|
407
|
-
// Check that the file extension is a TS file extension. As the source files are in the same directory as the output files.
|
|
408
|
-
return ['.ts', '.tsx', '.cts', '.mts'].includes(ext);
|
|
409
|
-
};
|
|
410
|
-
// Checks if the value is a path within the `src` directory.
|
|
411
|
-
const containsInvalidPath = (value) => {
|
|
412
|
-
if (typeof value === 'string') {
|
|
413
|
-
return isPathSourceFile(value);
|
|
414
|
-
}
|
|
415
|
-
else if (typeof value === 'object') {
|
|
416
|
-
return Object.entries(value).some(([currentKey, subValue]) => {
|
|
417
|
-
// Skip types field
|
|
418
|
-
if (currentKey === 'types') {
|
|
419
|
-
return false;
|
|
420
|
-
}
|
|
421
|
-
if (typeof subValue === 'string') {
|
|
422
|
-
return isPathSourceFile(subValue);
|
|
423
|
-
}
|
|
424
|
-
return false;
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
return false;
|
|
428
|
-
};
|
|
429
|
-
const exports = packageJson?.exports;
|
|
430
|
-
// Check the `.` export if `exports` is defined.
|
|
431
|
-
if (exports) {
|
|
432
|
-
if (typeof exports === 'string') {
|
|
433
|
-
return !isPathSourceFile(exports);
|
|
434
|
-
}
|
|
435
|
-
if (typeof exports === 'object' && '.' in exports) {
|
|
436
|
-
return !containsInvalidPath(exports['.']);
|
|
437
|
-
}
|
|
438
|
-
// Check other exports if `.` is not defined or valid.
|
|
439
|
-
for (const key in exports) {
|
|
440
|
-
if (key !== '.' && containsInvalidPath(exports[key])) {
|
|
441
|
-
return false;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
return true;
|
|
445
|
-
}
|
|
446
|
-
// If `exports` is not defined, fallback to `main` and `module` fields.
|
|
447
|
-
const buildPaths = ['main', 'module'];
|
|
448
|
-
for (const field of buildPaths) {
|
|
449
|
-
if (packageJson[field] && isPathSourceFile(packageJson[field])) {
|
|
450
|
-
return false;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
return true;
|
|
454
|
-
}
|
|
455
374
|
function pathToInputOrOutput(path, workspaceRoot, projectRoot) {
|
|
456
375
|
const fullProjectRoot = (0, node_path_1.resolve)(workspaceRoot, projectRoot);
|
|
457
376
|
const fullPath = (0, node_path_1.resolve)(workspaceRoot, path);
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { type TargetConfiguration } from '@nx/devkit';
|
|
2
2
|
import { type PackageManagerCommands } from 'nx/src/utils/package-manager';
|
|
3
|
+
import { type ParsedCommandLine } from 'typescript';
|
|
4
|
+
export type ParsedTsconfigData = Pick<ParsedCommandLine, 'options' | 'projectReferences' | 'raw'> & {
|
|
5
|
+
extendedConfigFile: {
|
|
6
|
+
filePath: string;
|
|
7
|
+
externalPackage?: string;
|
|
8
|
+
} | null;
|
|
9
|
+
};
|
|
3
10
|
/**
|
|
4
11
|
* Allow uses that use incremental builds to run `nx watch-deps` to continuously build all dependencies.
|
|
5
12
|
*/
|
|
@@ -7,3 +14,4 @@ export declare function addBuildAndWatchDepsTargets(workspaceRoot: string, proje
|
|
|
7
14
|
buildDepsTargetName?: string;
|
|
8
15
|
watchDepsTargetName?: string;
|
|
9
16
|
}, pmc: PackageManagerCommands): void;
|
|
17
|
+
export declare function isValidPackageJsonBuildConfig(tsConfig: ParsedTsconfigData, workspaceRoot: string, projectRoot: string): boolean;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.addBuildAndWatchDepsTargets = addBuildAndWatchDepsTargets;
|
|
4
|
+
exports.isValidPackageJsonBuildConfig = isValidPackageJsonBuildConfig;
|
|
4
5
|
const devkit_1 = require("@nx/devkit");
|
|
5
6
|
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
6
8
|
const path_1 = require("path");
|
|
7
9
|
/**
|
|
8
10
|
* Allow uses that use incremental builds to run `nx watch-deps` to continuously build all dependencies.
|
|
@@ -32,3 +34,74 @@ function addBuildAndWatchDepsTargets(workspaceRoot, projectRoot, targets, option
|
|
|
32
34
|
};
|
|
33
35
|
}
|
|
34
36
|
}
|
|
37
|
+
function isValidPackageJsonBuildConfig(tsConfig, workspaceRoot, projectRoot) {
|
|
38
|
+
const resolvedProjectPath = (0, node_path_1.isAbsolute)(projectRoot)
|
|
39
|
+
? (0, node_path_1.relative)(workspaceRoot, projectRoot)
|
|
40
|
+
: projectRoot;
|
|
41
|
+
const packageJsonPath = (0, path_1.join)(workspaceRoot, resolvedProjectPath, 'package.json');
|
|
42
|
+
if (!(0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
43
|
+
// If the package.json file does not exist.
|
|
44
|
+
// Assume it's valid because it would be using `project.json` instead.
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
const packageJson = (0, devkit_1.readJsonFile)(packageJsonPath);
|
|
48
|
+
const outDir = tsConfig.options.outFile
|
|
49
|
+
? (0, node_path_1.dirname)(tsConfig.options.outFile)
|
|
50
|
+
: tsConfig.options.outDir;
|
|
51
|
+
const resolvedOutDir = outDir
|
|
52
|
+
? (0, node_path_1.resolve)(workspaceRoot, resolvedProjectPath, outDir)
|
|
53
|
+
: undefined;
|
|
54
|
+
const isPathSourceFile = (path) => {
|
|
55
|
+
if (resolvedOutDir) {
|
|
56
|
+
const pathToCheck = (0, node_path_1.resolve)(workspaceRoot, resolvedProjectPath, path);
|
|
57
|
+
return !pathToCheck.startsWith(resolvedOutDir);
|
|
58
|
+
}
|
|
59
|
+
const ext = (0, node_path_1.extname)(path);
|
|
60
|
+
// Check that the file extension is a TS file extension. As the source files are in the same directory as the output files.
|
|
61
|
+
return ['.ts', '.tsx', '.cts', '.mts'].includes(ext);
|
|
62
|
+
};
|
|
63
|
+
// Checks if the value is a path within the `src` directory.
|
|
64
|
+
const containsInvalidPath = (value) => {
|
|
65
|
+
if (typeof value === 'string') {
|
|
66
|
+
return isPathSourceFile(value);
|
|
67
|
+
}
|
|
68
|
+
else if (typeof value === 'object') {
|
|
69
|
+
return Object.entries(value).some(([currentKey, subValue]) => {
|
|
70
|
+
// Skip types field
|
|
71
|
+
if (currentKey === 'types') {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (typeof subValue === 'string') {
|
|
75
|
+
return isPathSourceFile(subValue);
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
};
|
|
82
|
+
const exports = packageJson?.exports;
|
|
83
|
+
// Check the `.` export if `exports` is defined.
|
|
84
|
+
if (exports) {
|
|
85
|
+
if (typeof exports === 'string') {
|
|
86
|
+
return !isPathSourceFile(exports);
|
|
87
|
+
}
|
|
88
|
+
if (typeof exports === 'object' && '.' in exports) {
|
|
89
|
+
return !containsInvalidPath(exports['.']);
|
|
90
|
+
}
|
|
91
|
+
// Check other exports if `.` is not defined or valid.
|
|
92
|
+
for (const key in exports) {
|
|
93
|
+
if (key !== '.' && containsInvalidPath(exports[key])) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
// If `exports` is not defined, fallback to `main` and `module` fields.
|
|
100
|
+
const buildPaths = ['main', 'module'];
|
|
101
|
+
for (const field of buildPaths) {
|
|
102
|
+
if (packageJson[field] && isPathSourceFile(packageJson[field])) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
@@ -17,6 +17,7 @@ const output_1 = require("nx/src/utils/output");
|
|
|
17
17
|
const path_1 = require("path");
|
|
18
18
|
const ts_config_1 = require("./typescript/ts-config");
|
|
19
19
|
const crypto_1 = require("crypto");
|
|
20
|
+
const project_graph_1 = require("nx/src/config/project-graph");
|
|
20
21
|
function isBuildable(target, node) {
|
|
21
22
|
return (node.data.targets &&
|
|
22
23
|
node.data.targets[target] &&
|
|
@@ -49,7 +50,7 @@ function calculateProjectDependencies(projGraph, root, projectName, targetName,
|
|
|
49
50
|
.map(({ name: dep, isTopLevel }) => {
|
|
50
51
|
let project = null;
|
|
51
52
|
const depNode = projGraph.nodes[dep] || projGraph.externalNodes[dep];
|
|
52
|
-
if (depNode.type === 'lib') {
|
|
53
|
+
if ((0, project_graph_1.isProjectGraphProjectNode)(depNode) && depNode.type === 'lib') {
|
|
53
54
|
if (isBuildable(targetName, depNode)) {
|
|
54
55
|
const libPackageJsonPath = (0, path_1.join)(root, depNode.data.root, 'package.json');
|
|
55
56
|
project = {
|
|
@@ -68,7 +69,7 @@ function calculateProjectDependencies(projGraph, root, projectName, targetName,
|
|
|
68
69
|
nonBuildableDependencies.push(dep);
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
|
-
else if (
|
|
72
|
+
else if ((0, project_graph_1.isProjectGraphExternalNode)(depNode)) {
|
|
72
73
|
project = {
|
|
73
74
|
name: depNode.data.packageName,
|
|
74
75
|
outputs: [],
|
|
@@ -284,10 +285,9 @@ function findMissingBuildDependencies(root, projectName, targetName, projectDepe
|
|
|
284
285
|
function updatePaths(dependencies, paths) {
|
|
285
286
|
const pathsKeys = Object.keys(paths);
|
|
286
287
|
// For each registered dependency
|
|
287
|
-
dependencies
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
288
|
+
dependencies
|
|
289
|
+
.filter((dep) => (0, project_graph_1.isProjectGraphProjectNode)(dep.node))
|
|
290
|
+
.forEach((dep) => {
|
|
291
291
|
// If there are outputs
|
|
292
292
|
if (dep.outputs && dep.outputs.length > 0) {
|
|
293
293
|
// Directly map the dependency name to the output paths (dist/packages/..., etc.)
|
|
@@ -351,7 +351,8 @@ function updateBuildableProjectPackageJsonDependencies(root, projectName, target
|
|
|
351
351
|
!hasDependency(packageJson, 'peerDependencies', packageName)) {
|
|
352
352
|
try {
|
|
353
353
|
let depVersion;
|
|
354
|
-
if (entry.node
|
|
354
|
+
if ((0, project_graph_1.isProjectGraphProjectNode)(entry.node) &&
|
|
355
|
+
entry.node.type === 'lib') {
|
|
355
356
|
const outputs = (0, devkit_1.getOutputsForTargetAndConfiguration)({
|
|
356
357
|
project: projectName,
|
|
357
358
|
target: targetName,
|
|
@@ -2,7 +2,7 @@ import { type Tree } from '@nx/devkit';
|
|
|
2
2
|
export declare function isUsingTypeScriptPlugin(tree: Tree): boolean;
|
|
3
3
|
export declare function isUsingTsSolutionSetup(tree?: Tree): boolean;
|
|
4
4
|
export declare function assertNotUsingTsSolutionSetup(tree: Tree, pluginName: string, generatorName: string): void;
|
|
5
|
-
export declare function findRuntimeTsConfigName(
|
|
5
|
+
export declare function findRuntimeTsConfigName(projectRoot: string, tree?: Tree): string | null;
|
|
6
6
|
export declare function updateTsconfigFiles(tree: Tree, projectRoot: string, runtimeTsconfigFileName: string, compilerOptions: Record<string, string | boolean | string[]>, exclude?: string[], rootDir?: string): void;
|
|
7
7
|
export declare function addProjectToTsSolutionWorkspace(tree: Tree, projectDir: string): void;
|
|
8
8
|
export declare function getProjectType(tree: Tree, projectRoot: string, projectType?: 'library' | 'application'): 'library' | 'application';
|
|
@@ -71,7 +71,8 @@ function assertNotUsingTsSolutionSetup(tree, pluginName, generatorName) {
|
|
|
71
71
|
});
|
|
72
72
|
throw new Error(`The ${artifactString} doesn't yet support the existing TypeScript setup. See the error above.`);
|
|
73
73
|
}
|
|
74
|
-
function findRuntimeTsConfigName(
|
|
74
|
+
function findRuntimeTsConfigName(projectRoot, tree) {
|
|
75
|
+
tree ??= new tree_1.FsTree(devkit_1.workspaceRoot, false);
|
|
75
76
|
if (tree.exists((0, devkit_1.joinPathFragments)(projectRoot, 'tsconfig.app.json')))
|
|
76
77
|
return 'tsconfig.app.json';
|
|
77
78
|
if (tree.exists((0, devkit_1.joinPathFragments)(projectRoot, 'tsconfig.lib.json')))
|