@nx/js 20.1.0 → 20.2.0-beta.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/js",
3
- "version": "20.1.0",
3
+ "version": "20.2.0-beta.0",
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.1.0",
43
- "@nx/workspace": "20.1.0",
42
+ "@nx/devkit": "20.2.0-beta.0",
43
+ "@nx/workspace": "20.2.0-beta.0",
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",
@@ -35,5 +35,6 @@ function normalizeOptions(options, contextRoot, sourceRoot, projectRoot) {
35
35
  tsConfig: (0, path_1.join)(contextRoot, options.tsConfig),
36
36
  rootDir,
37
37
  mainOutputPath: (0, path_1.resolve)(outputPath, options.main.replace(`${projectRoot}/`, '').replace('.ts', '.js')),
38
+ generatePackageJson: options.generatePackageJson ?? true,
38
39
  };
39
40
  }
@@ -16,13 +16,13 @@
16
16
  "generateExportsField": {
17
17
  "type": "boolean",
18
18
  "alias": "exports",
19
- "description": "Update the output package.json file's 'exports' field. This field is used by Node and bundles.",
19
+ "description": "Update the output package.json file's 'exports' field. This field is used by Node and bundlers. Ignored when `generatePackageJson` is set to `false`.",
20
20
  "default": false,
21
21
  "x-priority": "important"
22
22
  },
23
23
  "additionalEntryPoints": {
24
24
  "type": "array",
25
- "description": "Additional entry-points to add to exports field in the package.json file.",
25
+ "description": "Additional entry-points to add to exports field in the package.json file. Ignored when `generatePackageJson` is set to `false`.",
26
26
  "items": {
27
27
  "type": "string"
28
28
  },
@@ -103,9 +103,14 @@
103
103
  },
104
104
  "generateLockfile": {
105
105
  "type": "boolean",
106
- "description": "Generate a lockfile (e.g. package-lock.json) that matches the workspace lockfile to ensure package versions match.",
106
+ "description": "Generate a lockfile (e.g. package-lock.json) that matches the workspace lockfile to ensure package versions match. Ignored when `generatePackageJson` is set to `false`.",
107
107
  "default": false,
108
108
  "x-priority": "internal"
109
+ },
110
+ "generatePackageJson": {
111
+ "type": "boolean",
112
+ "description": "Generate package.json file in the output folder.",
113
+ "default": true
109
114
  }
110
115
  },
111
116
  "required": ["main", "outputPath", "tsConfig"],
@@ -63,11 +63,13 @@ async function* tscExecutor(_options, context) {
63
63
  }
64
64
  const typescriptCompilation = (0, compile_typescript_files_1.compileTypeScriptFiles)(options, tsCompilationOptions, async () => {
65
65
  await assetHandler.processAllAssetsOnce();
66
- (0, update_package_json_1.updatePackageJson)({
67
- ...options,
68
- additionalEntryPoints: (0, create_entry_points_1.createEntryPoints)(options.additionalEntryPoints, context.root),
69
- format: [determineModuleFormatFromTsConfig(options.tsConfig)],
70
- }, context, target, dependencies);
66
+ if (options.generatePackageJson) {
67
+ (0, update_package_json_1.updatePackageJson)({
68
+ ...options,
69
+ additionalEntryPoints: (0, create_entry_points_1.createEntryPoints)(options.additionalEntryPoints, context.root),
70
+ format: [determineModuleFormatFromTsConfig(options.tsConfig)],
71
+ }, context, target, dependencies);
72
+ }
71
73
  (0, inline_1.postProcessInlinedDependencies)(tsCompilationOptions.outputPath, tsCompilationOptions.projectRoot, inlineProjectGraph);
72
74
  });
73
75
  if (!(0, devkit_1.isDaemonEnabled)() && options.watch) {
@@ -77,15 +79,18 @@ async function* tscExecutor(_options, context) {
77
79
  }
78
80
  if ((0, devkit_1.isDaemonEnabled)() && options.watch) {
79
81
  const disposeWatchAssetChanges = await assetHandler.watchAndProcessOnAssetChange();
80
- const disposePackageJsonChanges = await (0, watch_for_single_file_changes_1.watchForSingleFileChanges)(context.projectName, options.projectRoot, 'package.json', () => (0, update_package_json_1.updatePackageJson)({
81
- ...options,
82
- additionalEntryPoints: (0, create_entry_points_1.createEntryPoints)(options.additionalEntryPoints, context.root),
83
- format: [determineModuleFormatFromTsConfig(options.tsConfig)],
84
- }, context, target, dependencies));
82
+ let disposePackageJsonChanges;
83
+ if (options.generatePackageJson) {
84
+ disposePackageJsonChanges = await (0, watch_for_single_file_changes_1.watchForSingleFileChanges)(context.projectName, options.projectRoot, 'package.json', () => (0, update_package_json_1.updatePackageJson)({
85
+ ...options,
86
+ additionalEntryPoints: (0, create_entry_points_1.createEntryPoints)(options.additionalEntryPoints, context.root),
87
+ format: [determineModuleFormatFromTsConfig(options.tsConfig)],
88
+ }, context, target, dependencies));
89
+ }
85
90
  const handleTermination = async (exitCode) => {
86
91
  await typescriptCompilation.close();
87
92
  disposeWatchAssetChanges();
88
- disposePackageJsonChanges();
93
+ disposePackageJsonChanges?.();
89
94
  process.exit(exitCode);
90
95
  };
91
96
  process.on('SIGINT', () => handleTermination(128 + 2));
@@ -10,17 +10,18 @@ const target_defaults_utils_1 = require("@nx/devkit/src/generators/target-defaul
10
10
  const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-project-command");
11
11
  const find_matching_projects_1 = require("nx/src/utils/find-matching-projects");
12
12
  const path_1 = require("path");
13
+ const generator_prompts_1 = require("../../utils/generator-prompts");
13
14
  const package_manager_workspaces_1 = require("../../utils/package-manager-workspaces");
14
15
  const add_swc_config_1 = require("../../utils/swc/add-swc-config");
15
16
  const add_swc_dependencies_1 = require("../../utils/swc/add-swc-dependencies");
16
17
  const configuration_1 = require("../../utils/typescript/configuration");
17
18
  const create_ts_config_1 = require("../../utils/typescript/create-ts-config");
19
+ const plugin_1 = require("../../utils/typescript/plugin");
18
20
  const ts_config_1 = require("../../utils/typescript/ts-config");
19
21
  const ts_solution_setup_1 = require("../../utils/typescript/ts-solution-setup");
20
22
  const versions_1 = require("../../utils/versions");
21
23
  const init_1 = require("../init/init");
22
24
  const generator_1 = require("../setup-verdaccio/generator");
23
- const plugin_1 = require("../../utils/typescript/plugin");
24
25
  const defaultOutputDirectory = 'dist';
25
26
  async function libraryGenerator(tree, schema) {
26
27
  return await libraryGeneratorInternal(tree, {
@@ -115,12 +116,6 @@ async function libraryGeneratorInternal(tree, schema) {
115
116
  }
116
117
  if (options.isUsingTsSolutionConfig && options.unitTestRunner !== 'none') {
117
118
  (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.spec.json'), (json) => {
118
- const rootOffset = (0, devkit_1.offsetFromRoot)(options.projectRoot);
119
- // ensure it extends from the root tsconfig.base.json
120
- json.extends = (0, devkit_1.joinPathFragments)(rootOffset, 'tsconfig.base.json');
121
- // ensure outDir is set to the correct value
122
- json.compilerOptions ??= {};
123
- json.compilerOptions.outDir = (0, devkit_1.joinPathFragments)(rootOffset, 'dist/out-tsc', options.projectRoot);
124
119
  // add project reference to the runtime tsconfig.lib.json file
125
120
  json.references ??= [];
126
121
  json.references.push({ path: './tsconfig.lib.json' });
@@ -130,7 +125,8 @@ async function libraryGeneratorInternal(tree, schema) {
130
125
  if (!options.skipFormat) {
131
126
  await (0, devkit_1.formatFiles)(tree);
132
127
  }
133
- if (options.isUsingTsSolutionConfig &&
128
+ if (!options.skipWorkspacesWarning &&
129
+ options.isUsingTsSolutionConfig &&
134
130
  options.projectPackageManagerWorkspaceState !== 'included') {
135
131
  tasks.push((0, package_manager_workspaces_1.getProjectPackageManagerWorkspaceStateWarningTask)(options.projectPackageManagerWorkspaceState, tree.root));
136
132
  }
@@ -165,7 +161,8 @@ async function configureProject(tree, options) {
165
161
  if (options.config !== 'npm-scripts' &&
166
162
  (options.bundler === 'swc' ||
167
163
  options.bundler === 'esbuild' ||
168
- (!options.isUsingTsSolutionConfig && options.bundler === 'tsc'))) {
164
+ ((!options.isUsingTsSolutionConfig || options.useTscExecutor) &&
165
+ options.bundler === 'tsc'))) {
169
166
  const outputPath = getOutputPath(options);
170
167
  const executor = getBuildExecutor(options.bundler);
171
168
  (0, target_defaults_utils_1.addBuildTargetDefaults)(tree, executor);
@@ -188,6 +185,9 @@ async function configureProject(tree, options) {
188
185
  if (options.bundler === 'esbuild') {
189
186
  projectConfiguration.targets.build.options.declarationRootDir = `${options.projectRoot}/src`;
190
187
  }
188
+ else if (options.bundler === 'swc') {
189
+ projectConfiguration.targets.build.options.stripLeadingPaths = true;
190
+ }
191
191
  }
192
192
  else {
193
193
  projectConfiguration.targets.build.options.assets = [];
@@ -227,8 +227,6 @@ async function configureProject(tree, options) {
227
227
  if (!projectConfiguration.tags?.length) {
228
228
  delete projectConfiguration.tags;
229
229
  }
230
- // automatically inferred as `library`
231
- delete projectConfiguration.projectType;
232
230
  // empty targets are cleaned up automatically by `updateProjectConfiguration`
233
231
  (0, devkit_1.updateProjectConfiguration)(tree, options.name, projectConfiguration);
234
232
  }
@@ -475,16 +473,10 @@ async function normalizeOptions(tree, options) {
475
473
  options.addPlugin ??=
476
474
  process.env.NX_ADD_PLUGINS !== 'false' &&
477
475
  nxJson.useInferencePlugins !== false;
476
+ options.linter = await (0, generator_prompts_1.normalizeLinterOption)(tree, options.linter);
478
477
  const hasPlugin = (0, ts_solution_setup_1.isUsingTypeScriptPlugin)(tree);
479
478
  const isUsingTsSolutionConfig = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
480
479
  if (isUsingTsSolutionConfig) {
481
- options.linter ??= await (0, prompt_1.promptWhenInteractive)({
482
- type: 'autocomplete',
483
- name: 'linter',
484
- message: `Which linter would you like to use?`,
485
- choices: [{ name: 'none' }, { name: 'eslint' }],
486
- initial: 0,
487
- }, { linter: 'none' }).then(({ linter }) => linter);
488
480
  options.unitTestRunner ??= await (0, prompt_1.promptWhenInteractive)({
489
481
  type: 'autocomplete',
490
482
  name: 'unitTestRunner',
@@ -494,13 +486,6 @@ async function normalizeOptions(tree, options) {
494
486
  }, { unitTestRunner: 'none' }).then(({ unitTestRunner }) => unitTestRunner);
495
487
  }
496
488
  else {
497
- options.linter ??= await (0, prompt_1.promptWhenInteractive)({
498
- type: 'autocomplete',
499
- name: 'linter',
500
- message: `Which linter would you like to use?`,
501
- choices: [{ name: 'eslint' }, { name: 'none' }],
502
- initial: 0,
503
- }, { linter: 'eslint' }).then(({ linter }) => linter);
504
489
  options.unitTestRunner ??= await (0, prompt_1.promptWhenInteractive)({
505
490
  type: 'autocomplete',
506
491
  name: 'unitTestRunner',
@@ -784,10 +769,10 @@ function determineEntryFields(options) {
784
769
  return {
785
770
  type: 'commonjs',
786
771
  main: options.isUsingTsSolutionConfig
787
- ? './dist/src/index.js'
772
+ ? './dist/index.js'
788
773
  : './src/index.js',
789
774
  typings: options.isUsingTsSolutionConfig
790
- ? './dist/src/index.d.ts'
775
+ ? './dist/index.d.ts'
791
776
  : './src/index.d.ts',
792
777
  };
793
778
  case 'rollup':
@@ -37,6 +37,8 @@ export interface LibraryGeneratorSchema {
37
37
  simpleName?: boolean;
38
38
  addPlugin?: boolean;
39
39
  useProjectJson?: boolean;
40
+ skipWorkspacesWarning?: boolean;
41
+ useTscExecutor?: boolean;
40
42
  }
41
43
 
42
44
  export interface NormalizedLibraryGeneratorOptions
@@ -2,13 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.addLocalRegistryScripts = addLocalRegistryScripts;
4
4
  const devkit_1 = require("@nx/devkit");
5
- const startLocalRegistryScript = (localRegistryTarget) => `
6
- /**
5
+ const startLocalRegistryScript = (localRegistryTarget) => `/**
7
6
  * This script starts a local registry for e2e testing purposes.
8
7
  * It is meant to be called in jest's globalSetup.
9
8
  */
9
+
10
+ /// <reference path="registry.d.ts" />
11
+
10
12
  import { startLocalRegistry } from '@nx/js/plugins/jest/local-registry';
11
- import { execFileSync } from 'child_process';
12
13
  import { releasePublish, releaseVersion } from 'nx/release';
13
14
 
14
15
  export default async () => {
@@ -39,23 +40,35 @@ export default async () => {
39
40
  });
40
41
  };
41
42
  `;
42
- const stopLocalRegistryScript = `
43
- /**
43
+ const stopLocalRegistryScript = `/**
44
44
  * This script stops the local registry for e2e testing purposes.
45
45
  * It is meant to be called in jest's globalTeardown.
46
46
  */
47
47
 
48
+ /// <reference path="registry.d.ts" />
49
+
48
50
  export default () => {
49
51
  if (global.stopLocalRegistry) {
50
52
  global.stopLocalRegistry();
51
53
  }
52
54
  };
53
55
  `;
56
+ const registryDeclarationText = `declare function stopLocalRegistry(): void;
57
+ `;
54
58
  function addLocalRegistryScripts(tree) {
55
59
  const startLocalRegistryPath = 'tools/scripts/start-local-registry.ts';
56
60
  const stopLocalRegistryPath = 'tools/scripts/stop-local-registry.ts';
57
- const projectConfiguration = (0, devkit_1.readJson)(tree, 'project.json');
58
- const localRegistryTarget = `${projectConfiguration.name}:local-registry`;
61
+ const registryDeclarationPath = 'tools/scripts/registry.d.ts';
62
+ let projectName;
63
+ try {
64
+ ({ name: projectName } = (0, devkit_1.readJson)(tree, 'project.json'));
65
+ }
66
+ catch {
67
+ // if project.json doesn't exist, try package.json
68
+ const { name, nx } = (0, devkit_1.readJson)(tree, 'package.json');
69
+ projectName = nx?.name ?? name;
70
+ }
71
+ const localRegistryTarget = `${projectName}:local-registry`;
59
72
  if (!tree.exists(startLocalRegistryPath)) {
60
73
  tree.write(startLocalRegistryPath, startLocalRegistryScript(localRegistryTarget));
61
74
  }
@@ -72,5 +85,8 @@ function addLocalRegistryScripts(tree) {
72
85
  if (!tree.exists(stopLocalRegistryPath)) {
73
86
  tree.write(stopLocalRegistryPath, stopLocalRegistryScript);
74
87
  }
88
+ if (!tree.exists(registryDeclarationPath)) {
89
+ tree.write(registryDeclarationPath, registryDeclarationText);
90
+ }
75
91
  return { startLocalRegistryPath, stopLocalRegistryPath };
76
92
  }
@@ -0,0 +1,3 @@
1
+ import type { Tree } from '@nx/devkit';
2
+ export declare function normalizeLinterOption(tree: Tree, linter: undefined | 'none' | 'eslint'): Promise<'none' | 'eslint'>;
3
+ export declare function normalizeUnitTestRunnerOption<T extends 'none' | 'jest' | 'vitest'>(tree: Tree, unitTestRunner: undefined | T, testRunners?: Array<'jest' | 'vitest'>): Promise<T>;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeLinterOption = normalizeLinterOption;
4
+ exports.normalizeUnitTestRunnerOption = normalizeUnitTestRunnerOption;
5
+ const prompt_1 = require("@nx/devkit/src/generators/prompt");
6
+ const ts_solution_setup_1 = require("./typescript/ts-solution-setup");
7
+ async function normalizeLinterOption(tree, linter) {
8
+ if (linter) {
9
+ return linter;
10
+ }
11
+ const isTsSolutionSetup = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
12
+ const choices = isTsSolutionSetup
13
+ ? [{ name: 'none' }, { name: 'eslint' }]
14
+ : [{ name: 'eslint' }, { name: 'none' }];
15
+ const defaultValue = isTsSolutionSetup ? 'none' : 'eslint';
16
+ return await (0, prompt_1.promptWhenInteractive)({
17
+ type: 'autocomplete',
18
+ name: 'linter',
19
+ message: `Which linter would you like to use?`,
20
+ choices,
21
+ initial: 0,
22
+ }, { linter: defaultValue }).then(({ linter }) => linter);
23
+ }
24
+ async function normalizeUnitTestRunnerOption(tree, unitTestRunner, testRunners = ['jest', 'vitest']) {
25
+ if (unitTestRunner) {
26
+ return unitTestRunner;
27
+ }
28
+ const isTsSolutionSetup = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
29
+ const choices = isTsSolutionSetup
30
+ ? [{ name: 'none' }, ...testRunners.map((runner) => ({ name: runner }))]
31
+ : [...testRunners.map((runner) => ({ name: runner })), { name: 'none' }];
32
+ const defaultValue = (isTsSolutionSetup ? 'none' : testRunners[0]);
33
+ return await (0, prompt_1.promptWhenInteractive)({
34
+ type: 'autocomplete',
35
+ name: 'unitTestRunner',
36
+ message: `Which unit test runner would you like to use?`,
37
+ choices,
38
+ initial: 0,
39
+ }, { unitTestRunner: defaultValue }).then(({ unitTestRunner }) => unitTestRunner);
40
+ }
@@ -114,7 +114,7 @@ function addMissingDependencies(packageJson, { projectName, targetName, configur
114
114
  function getExports(options) {
115
115
  const outputDir = getOutputDir(options);
116
116
  const mainFile = options.outputFileName
117
- ? options.outputFileName.replace(/\.[tj]s$/, '')
117
+ ? (0, path_1.basename)(options.outputFileName).replace(/\.[tj]s$/, '')
118
118
  : (0, path_1.basename)(options.main).replace(/\.[tj]s$/, '');
119
119
  const exports = {
120
120
  '.': outputDir + mainFile + options.fileExt,
@@ -218,8 +218,8 @@ function getOutputDir(options) {
218
218
  : options.outputPath;
219
219
  const relativeOutputPath = (0, path_1.relative)(packageJsonDir, options.outputPath);
220
220
  const relativeMainDir = options.outputFileName
221
- ? ''
221
+ ? (0, path_1.dirname)(options.outputFileName)
222
222
  : (0, path_1.relative)(options.rootDir ?? options.projectRoot, (0, path_1.dirname)(options.main));
223
- const outputDir = (0, path_1.join)(relativeOutputPath, relativeMainDir);
223
+ const outputDir = (0, devkit_1.joinPathFragments)(relativeOutputPath, relativeMainDir);
224
224
  return outputDir === '.' ? `./` : `./${outputDir}/`;
225
225
  }
@@ -19,12 +19,14 @@ export interface ExecutorOptions {
19
19
  externalBuildTargets?: string[];
20
20
  generateLockfile?: boolean;
21
21
  stripLeadingPaths?: boolean;
22
+ generatePackageJson?: boolean;
22
23
  }
23
24
 
24
25
  export interface NormalizedExecutorOptions extends ExecutorOptions {
25
26
  rootDir: string;
26
27
  projectRoot: string;
27
28
  mainOutputPath: string;
29
+ generatePackageJson: boolean;
28
30
  files: Array<FileInputOutput>;
29
31
  root?: string;
30
32
  sourceRoot?: string;