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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/migrations.json CHANGED
@@ -111,6 +111,19 @@
111
111
  "alwaysAddToPackageJson": false
112
112
  }
113
113
  }
114
+ },
115
+ "20.2.0": {
116
+ "version": "20.2.0-beta.5",
117
+ "x-prompt": "Do you want to update to TypeScript v5.6?",
118
+ "requires": {
119
+ "typescript": ">=5.5.0 <5.6.0"
120
+ },
121
+ "packages": {
122
+ "typescript": {
123
+ "version": "~5.6.2",
124
+ "alwaysAddToPackageJson": false
125
+ }
126
+ }
114
127
  }
115
128
  }
116
129
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/js",
3
- "version": "20.2.0-beta.3",
3
+ "version": "20.2.0-beta.5",
4
4
  "private": false,
5
5
  "description": "The JS plugin for Nx contains executors and generators that provide the best experience for developing JavaScript and TypeScript projects. ",
6
6
  "repository": {
@@ -39,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.2.0-beta.3",
43
- "@nx/workspace": "20.2.0-beta.3",
42
+ "@nx/devkit": "20.2.0-beta.5",
43
+ "@nx/workspace": "20.2.0-beta.5",
44
44
  "@zkochan/js-yaml": "0.0.7",
45
45
  "babel-plugin-const-enum": "^1.0.1",
46
46
  "babel-plugin-macros": "^2.8.0",
@@ -3,5 +3,5 @@ import { NodeExecutorOptions } from './schema';
3
3
  export declare function nodeExecutor(options: NodeExecutorOptions, context: ExecutorContext): AsyncGenerator<{
4
4
  success: boolean;
5
5
  options?: Record<string, any>;
6
- }, void, undefined>;
6
+ }, void, any>;
7
7
  export default nodeExecutor;
@@ -6,5 +6,5 @@ export declare function swcExecutor(_options: SwcExecutorOptions, context: Execu
6
6
  } | {
7
7
  success: boolean;
8
8
  outfile: string;
9
- }, any, undefined>;
9
+ }, any, any>;
10
10
  export default swcExecutor;
@@ -3,5 +3,5 @@ import type { TypeScriptCompilationOptions } from '@nx/workspace/src/utilities/t
3
3
  import { ExecutorOptions, NormalizedExecutorOptions } from '../../utils/schema';
4
4
  export declare function determineModuleFormatFromTsConfig(absolutePathToTsConfig: string): 'cjs' | 'esm';
5
5
  export declare function createTypeScriptCompilationOptions(normalizedOptions: NormalizedExecutorOptions, context: ExecutorContext): TypeScriptCompilationOptions;
6
- export declare function tscExecutor(_options: ExecutorOptions, context: ExecutorContext): AsyncGenerator<import("../../utils/typescript/compile-typescript-files").TypescriptCompilationResult, any, undefined>;
6
+ export declare function tscExecutor(_options: ExecutorOptions, context: ExecutorContext): AsyncGenerator<import("../../utils/typescript/compile-typescript-files").TypescriptCompilationResult, any, any>;
7
7
  export default tscExecutor;
@@ -135,6 +135,10 @@ async function libraryGeneratorInternal(tree, schema) {
135
135
  logNxReleaseDocsInfo();
136
136
  });
137
137
  }
138
+ // Always run install to link packages.
139
+ if (options.isUsingTsSolutionConfig) {
140
+ tasks.push(() => (0, devkit_1.installPackagesTask)(tree));
141
+ }
138
142
  tasks.push(() => {
139
143
  (0, log_show_project_command_1.logShowProjectCommand)(options.name);
140
144
  });
@@ -816,6 +820,17 @@ function determineEntryFields(options) {
816
820
  // Safest option is to not set a type field.
817
821
  // Allow the user to decide which module format their library is using
818
822
  type: undefined,
823
+ // For non-buildable libraries, point to source so we can still use them in apps via bundlers like Vite.
824
+ main: options.isUsingTsSolutionConfig
825
+ ? options.js
826
+ ? './src/index.js'
827
+ : './src/index.ts'
828
+ : undefined,
829
+ types: options.isUsingTsSolutionConfig
830
+ ? options.js
831
+ ? './src/index.js'
832
+ : './src/index.ts'
833
+ : undefined,
819
834
  };
820
835
  }
821
836
  }
@@ -1,7 +1,4 @@
1
- import type {
2
- ProjectNameAndRootFormat,
3
- ProjectNameAndRootOptions,
4
- } from '@nx/devkit/src/generators/project-name-and-root-utils';
1
+ import type { ProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
5
2
  // nx-ignore-next-line
6
3
  const { Linter, LinterType } = require('@nx/eslint'); // use require to import to avoid circular dependency
7
4
  import type { ProjectPackageManagerWorkspaceState } from '../../utils/package-manager-workspaces';
@@ -12,7 +9,6 @@ export type Bundler = 'swc' | 'tsc' | 'rollup' | 'vite' | 'esbuild' | 'none';
12
9
  export interface LibraryGeneratorSchema {
13
10
  directory: string;
14
11
  name?: string;
15
- projectNameAndRootFormat?: ProjectNameAndRootFormat;
16
12
  skipFormat?: boolean;
17
13
  tags?: string;
18
14
  skipTsConfig?: boolean;
@@ -72,12 +72,20 @@ async function createNodesInternal(configFilePath, options, context, lockFileNam
72
72
  !siblingFiles.includes('tsconfig.json')) {
73
73
  return {};
74
74
  }
75
+ // Do not create project for Next.js projects since they are not compatible with
76
+ // project references and typecheck will fail.
77
+ if (siblingFiles.includes('next.config.js') ||
78
+ siblingFiles.includes('next.config.cjs') ||
79
+ siblingFiles.includes('next.config.mjs') ||
80
+ siblingFiles.includes('next.config.ts')) {
81
+ return {};
82
+ }
75
83
  /**
76
84
  * The cache key is composed by:
77
85
  * - hashes of the content of the relevant files that can affect what's inferred by the plugin:
78
86
  * - current config file
79
87
  * - config files extended by the current config file (recursively up to the root config file)
80
- * - referenced config files that are internal to the owning Nx project of the current config file
88
+ * - 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
81
89
  * - lock file
82
90
  * - hash of the plugin options
83
91
  * - current config file path
@@ -85,11 +93,13 @@ async function createNodesInternal(configFilePath, options, context, lockFileNam
85
93
  const tsConfig = readCachedTsConfig(fullConfigPath);
86
94
  const extendedConfigFiles = getExtendedConfigFiles(fullConfigPath, tsConfig);
87
95
  const internalReferencedFiles = resolveInternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
96
+ const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
88
97
  const nodeHash = (0, file_hasher_1.hashArray)([
89
98
  ...[
90
99
  fullConfigPath,
91
100
  ...extendedConfigFiles.files,
92
101
  ...Object.keys(internalReferencedFiles),
102
+ ...Object.keys(externalProjectReferences),
93
103
  (0, node_path_1.join)(context.workspaceRoot, lockFileName),
94
104
  ].map(file_hasher_1.hashFile),
95
105
  (0, file_hasher_1.hashObject)(options),
@@ -119,14 +129,15 @@ function buildTscTargets(configFilePath, projectRoot, options, context) {
119
129
  // Typecheck target
120
130
  if ((0, node_path_1.basename)(configFilePath) === 'tsconfig.json' && options.typecheck) {
121
131
  internalProjectReferences = resolveInternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
132
+ const externalProjectReferences = resolveShallowExternalProjectReferences(tsConfig, context.workspaceRoot, projectRoot);
122
133
  const targetName = options.typecheck.targetName;
123
134
  if (!targets[targetName]) {
124
135
  let command = `tsc --build --emitDeclarationOnly --pretty --verbose`;
125
136
  if (tsConfig.options.noEmit ||
126
- Object.values(internalProjectReferences).some((ref) => ref.options.noEmit)) {
127
- // `--emitDeclarationOnly` and `--noEmit` are mutually exclusive, so
128
- // we remove `--emitDeclarationOnly` if `--noEmit` is set.
129
- command = `tsc --build --pretty --verbose`;
137
+ Object.values(internalProjectReferences).some((ref) => ref.options.noEmit) ||
138
+ Object.values(externalProjectReferences).some((ref) => ref.options.noEmit)) {
139
+ // `tsc --build` does not work with `noEmit: true`
140
+ command = `echo "The 'typecheck' target is disabled because one or more project references set 'noEmit: true' in their tsconfig. Remove this property to resolve this issue."`;
130
141
  }
131
142
  targets[targetName] = {
132
143
  dependsOn: [`^${targetName}`],
@@ -321,6 +332,27 @@ function getExtendedConfigFiles(tsConfigPath, tsConfig) {
321
332
  };
322
333
  }
323
334
  function resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
335
+ walkProjectReferences(tsConfig, workspaceRoot, projectRoot, (configPath, config) => {
336
+ if (isExternalProjectReference(configPath, workspaceRoot, projectRoot)) {
337
+ return false;
338
+ }
339
+ else {
340
+ projectReferences[configPath] = config;
341
+ }
342
+ });
343
+ return projectReferences;
344
+ }
345
+ function resolveShallowExternalProjectReferences(tsConfig, workspaceRoot, projectRoot, projectReferences = {}) {
346
+ walkProjectReferences(tsConfig, workspaceRoot, projectRoot, (configPath, config) => {
347
+ if (isExternalProjectReference(configPath, workspaceRoot, projectRoot)) {
348
+ projectReferences[configPath] = config;
349
+ }
350
+ return false;
351
+ });
352
+ return projectReferences;
353
+ }
354
+ function walkProjectReferences(tsConfig, workspaceRoot, projectRoot, visitor, // false stops recursion
355
+ projectReferences = {}) {
324
356
  if (!tsConfig.projectReferences?.length) {
325
357
  return projectReferences;
326
358
  }
@@ -334,15 +366,14 @@ function resolveInternalProjectReferences(tsConfig, workspaceRoot, projectRoot,
334
366
  // the referenced tsconfig doesn't exist, ignore it
335
367
  continue;
336
368
  }
337
- if (isExternalProjectReference(refConfigPath, workspaceRoot, projectRoot)) {
338
- continue;
339
- }
340
369
  if (!refConfigPath.endsWith('.json')) {
341
370
  refConfigPath = (0, node_path_1.join)(refConfigPath, 'tsconfig.json');
342
371
  }
343
372
  const refTsConfig = readCachedTsConfig(refConfigPath);
344
- projectReferences[refConfigPath] = refTsConfig;
345
- resolveInternalProjectReferences(refTsConfig, workspaceRoot, projectRoot, projectReferences);
373
+ const result = visitor(refConfigPath, refTsConfig);
374
+ if (result !== false) {
375
+ walkProjectReferences(refTsConfig, workspaceRoot, projectRoot, visitor);
376
+ }
346
377
  }
347
378
  return projectReferences;
348
379
  }
@@ -2,4 +2,5 @@ import { type GeneratorCallback, type Tree } from '@nx/devkit';
2
2
  export type ProjectPackageManagerWorkspaceState = 'included' | 'excluded' | 'no-workspaces';
3
3
  export declare function getProjectPackageManagerWorkspaceState(tree: Tree, projectRoot: string): ProjectPackageManagerWorkspaceState;
4
4
  export declare function isUsingPackageManagerWorkspaces(tree: Tree): boolean;
5
+ export declare function isWorkspacesEnabled(tree: Tree): boolean;
5
6
  export declare function getProjectPackageManagerWorkspaceStateWarningTask(projectPackageManagerWorkspaceState: ProjectPackageManagerWorkspaceState, workspaceRoot: string): GeneratorCallback;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getProjectPackageManagerWorkspaceState = getProjectPackageManagerWorkspaceState;
4
4
  exports.isUsingPackageManagerWorkspaces = isUsingPackageManagerWorkspaces;
5
+ exports.isWorkspacesEnabled = isWorkspacesEnabled;
5
6
  exports.getProjectPackageManagerWorkspaceStateWarningTask = getProjectPackageManagerWorkspaceStateWarningTask;
6
7
  const devkit_1 = require("@nx/devkit");
7
8
  const minimatch_1 = require("minimatch");
@@ -17,7 +18,19 @@ function getProjectPackageManagerWorkspaceState(tree, projectRoot) {
17
18
  return isIncluded ? 'included' : 'excluded';
18
19
  }
19
20
  function isUsingPackageManagerWorkspaces(tree) {
20
- return (0, devkit_1.isWorkspacesEnabled)((0, devkit_1.detectPackageManager)(tree.root), tree.root);
21
+ return isWorkspacesEnabled(tree);
22
+ }
23
+ function isWorkspacesEnabled(tree
24
+ // packageManager: PackageManager = detectPackageManager(),
25
+ // root: string = workspaceRoot
26
+ ) {
27
+ const packageManager = (0, devkit_1.detectPackageManager)(tree.root);
28
+ if (packageManager === 'pnpm') {
29
+ return tree.exists('pnpm-workspace.yaml');
30
+ }
31
+ // yarn and npm both use the same 'workspaces' property in package.json
32
+ const packageJson = (0, devkit_1.readJson)(tree, 'package.json');
33
+ return !!packageJson?.workspaces;
21
34
  }
22
35
  function getProjectPackageManagerWorkspaceStateWarningTask(projectPackageManagerWorkspaceState, workspaceRoot) {
23
36
  return () => {
@@ -10,4 +10,4 @@ export declare function compileSwc(context: ExecutorContext, normalizedOptions:
10
10
  export declare function compileSwcWatch(context: ExecutorContext, normalizedOptions: NormalizedSwcExecutorOptions, postCompilationCallback: () => Promise<void>): AsyncGenerator<{
11
11
  success: boolean;
12
12
  outfile: string;
13
- }, any, undefined>;
13
+ }, any, any>;
@@ -2,3 +2,4 @@ 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 updateTsconfigFiles(tree: Tree, projectRoot: string, runtimeTsconfigFileName: string, compilerOptions: Record<string, string | boolean | string[]>, exclude?: string[], rootDir?: string): void;
@@ -3,9 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isUsingTypeScriptPlugin = isUsingTypeScriptPlugin;
4
4
  exports.isUsingTsSolutionSetup = isUsingTsSolutionSetup;
5
5
  exports.assertNotUsingTsSolutionSetup = assertNotUsingTsSolutionSetup;
6
+ exports.updateTsconfigFiles = updateTsconfigFiles;
6
7
  const devkit_1 = require("@nx/devkit");
7
8
  const tree_1 = require("nx/src/generators/tree");
8
9
  const package_manager_workspaces_1 = require("../package-manager-workspaces");
10
+ const posix_1 = require("node:path/posix");
9
11
  function isUsingTypeScriptPlugin(tree) {
10
12
  const nxJson = (0, devkit_1.readNxJson)(tree);
11
13
  return (nxJson?.plugins?.some((p) => typeof p === 'string'
@@ -65,3 +67,63 @@ function assertNotUsingTsSolutionSetup(tree, pluginName, generatorName) {
65
67
  });
66
68
  process.exit(1);
67
69
  }
70
+ function updateTsconfigFiles(tree, projectRoot, runtimeTsconfigFileName, compilerOptions, exclude = [], rootDir = 'src') {
71
+ if (!isUsingTsSolutionSetup(tree))
72
+ return;
73
+ const offset = (0, devkit_1.offsetFromRoot)(projectRoot);
74
+ const tsconfig = `${projectRoot}/${runtimeTsconfigFileName}`;
75
+ const tsconfigSpec = `${projectRoot}/tsconfig.spec.json`;
76
+ const e2eRoot = `${projectRoot}-e2e`;
77
+ const tsconfigE2E = `${e2eRoot}/tsconfig.json`;
78
+ if (tree.exists(tsconfig)) {
79
+ (0, devkit_1.updateJson)(tree, tsconfig, (json) => {
80
+ json.extends = (0, devkit_1.joinPathFragments)(offset, 'tsconfig.base.json');
81
+ json.compilerOptions = {
82
+ ...json.compilerOptions,
83
+ // Make sure d.ts files from typecheck does not conflict with bundlers.
84
+ // Other tooling like jest write to "out-tsc/jest" to we just default to "out-tsc/<project-name>".
85
+ outDir: (0, devkit_1.joinPathFragments)('out-tsc', projectRoot.split('/').at(-1)),
86
+ rootDir,
87
+ ...compilerOptions,
88
+ };
89
+ const excludeSet = json.exclude
90
+ ? new Set(['dist', ...json.exclude, ...exclude])
91
+ : new Set(exclude);
92
+ json.exclude = Array.from(excludeSet);
93
+ return json;
94
+ });
95
+ }
96
+ if (tree.exists(tsconfigSpec)) {
97
+ (0, devkit_1.updateJson)(tree, tsconfigSpec, (json) => {
98
+ json.extends = (0, devkit_1.joinPathFragments)(offset, 'tsconfig.base.json');
99
+ json.compilerOptions = {
100
+ ...json.compilerOptions,
101
+ ...compilerOptions,
102
+ };
103
+ const runtimePath = `./${runtimeTsconfigFileName}`;
104
+ json.references ??= [];
105
+ if (!json.references.some((x) => x.path === runtimePath))
106
+ json.references.push({ path: runtimePath });
107
+ return json;
108
+ });
109
+ }
110
+ if (tree.exists(tsconfigE2E)) {
111
+ // tsconfig.json for e2e projects need to have references array
112
+ (0, devkit_1.updateJson)(tree, tsconfigE2E, (json) => {
113
+ json.references ??= [];
114
+ const projectPath = (0, posix_1.relative)(e2eRoot, projectRoot);
115
+ if (!json.references.some((x) => x.path === projectPath))
116
+ json.references.push({ path: projectPath });
117
+ return json;
118
+ });
119
+ }
120
+ if (tree.exists('tsconfig.json')) {
121
+ (0, devkit_1.updateJson)(tree, 'tsconfig.json', (json) => {
122
+ const projectPath = './' + projectRoot;
123
+ json.references ??= [];
124
+ if (!json.references.some((x) => x.path === projectPath))
125
+ json.references.push({ path: projectPath });
126
+ return json;
127
+ });
128
+ }
129
+ }
@@ -8,10 +8,10 @@ export declare const swcNodeVersion = "~1.9.1";
8
8
  export declare const tsLibVersion = "^2.3.0";
9
9
  export declare const typesNodeVersion = "18.16.9";
10
10
  export declare const verdaccioVersion = "^5.0.4";
11
- export declare const typescriptVersion = "~5.5.2";
11
+ export declare const typescriptVersion = "~5.6.2";
12
12
  /**
13
13
  * The minimum version is currently determined from the lowest version
14
14
  * that's supported by the lowest Angular supported version, e.g.
15
- * `npm view @angular/compiler-cli@14.0.0 peerDependencies.typescript`
15
+ * `npm view @angular/compiler-cli@17.0.0 peerDependencies.typescript`
16
16
  */
17
- export declare const supportedTypescriptVersions = ">=4.9.3";
17
+ export declare const supportedTypescriptVersions = ">=5.2.0";
@@ -12,10 +12,10 @@ exports.tsLibVersion = '^2.3.0';
12
12
  exports.typesNodeVersion = '18.16.9';
13
13
  exports.verdaccioVersion = '^5.0.4';
14
14
  // Typescript
15
- exports.typescriptVersion = '~5.5.2';
15
+ exports.typescriptVersion = '~5.6.2';
16
16
  /**
17
17
  * The minimum version is currently determined from the lowest version
18
18
  * that's supported by the lowest Angular supported version, e.g.
19
- * `npm view @angular/compiler-cli@14.0.0 peerDependencies.typescript`
19
+ * `npm view @angular/compiler-cli@17.0.0 peerDependencies.typescript`
20
20
  */
21
- exports.supportedTypescriptVersions = '>=4.9.3';
21
+ exports.supportedTypescriptVersions = '>=5.2.0';