@nx/js 20.0.0-beta.2 → 20.0.0-beta.4

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.
Files changed (38) hide show
  1. package/generators.json +1 -1
  2. package/package.json +5 -4
  3. package/src/generators/init/files/ts-solution/tsconfig.base.json__tmpl__ +34 -0
  4. package/src/generators/init/files/ts-solution/tsconfig.json__tmpl__ +6 -0
  5. package/src/generators/init/init.js +52 -9
  6. package/src/generators/init/schema.d.ts +4 -1
  7. package/src/generators/init/schema.json +6 -6
  8. package/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ +4 -4
  9. package/src/generators/library/files/lib/src/lib/__fileName__.ts__tmpl__ +1 -1
  10. package/src/generators/library/files/readme/README.md +3 -11
  11. package/src/generators/library/files/tsconfig-lib/ts-solution/tsconfig.lib.json__tmpl__ +14 -0
  12. package/src/generators/library/library.d.ts +2 -11
  13. package/src/generators/library/library.js +294 -93
  14. package/src/generators/library/schema.d.ts +53 -0
  15. package/src/generators/library/schema.json +18 -17
  16. package/src/generators/library/utils/package-manager-workspaces.d.ts +3 -0
  17. package/src/generators/library/utils/package-manager-workspaces.js +52 -0
  18. package/src/generators/library/utils/plugin-registrations.d.ts +3 -0
  19. package/src/generators/library/utils/plugin-registrations.js +108 -0
  20. package/src/generators/setup-prettier/generator.js +3 -3
  21. package/src/generators/setup-verdaccio/generator.js +14 -10
  22. package/src/generators/typescript-sync/typescript-sync.d.ts +1 -1
  23. package/src/generators/typescript-sync/typescript-sync.js +9 -8
  24. package/src/plugins/typescript/plugin.js +8 -0
  25. package/src/utils/find-npm-dependencies.js +12 -0
  26. package/src/utils/package-manager-workspaces.d.ts +4 -0
  27. package/src/utils/package-manager-workspaces.js +19 -0
  28. package/src/utils/prettier.d.ts +1 -0
  29. package/src/utils/prettier.js +53 -0
  30. package/src/utils/schema.d.ts +0 -32
  31. package/src/utils/swc/add-swc-dependencies.d.ts +4 -0
  32. package/src/utils/swc/add-swc-dependencies.js +11 -4
  33. package/src/utils/typescript/configuration.d.ts +7 -0
  34. package/src/utils/typescript/configuration.js +64 -0
  35. package/src/utils/typescript/ts-solution-setup.d.ts +3 -0
  36. package/src/utils/typescript/ts-solution-setup.js +48 -0
  37. /package/src/generators/init/files/{__fileName__ → non-ts-solution/__fileName__} +0 -0
  38. /package/src/generators/library/files/{lib → tsconfig-lib/non-ts-solution}/tsconfig.lib.json__tmpl__ +0 -0
@@ -7,19 +7,27 @@ const devkit_1 = require("@nx/devkit");
7
7
  const project_name_and_root_utils_1 = require("@nx/devkit/src/generators/project-name-and-root-utils");
8
8
  const target_defaults_utils_1 = require("@nx/devkit/src/generators/target-defaults-utils");
9
9
  const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-project-command");
10
+ const enquirer_1 = require("enquirer");
10
11
  const find_matching_projects_1 = require("nx/src/utils/find-matching-projects");
12
+ const is_ci_1 = require("nx/src/utils/is-ci");
11
13
  const path_1 = require("path");
14
+ const package_manager_workspaces_1 = require("../../utils/package-manager-workspaces");
12
15
  const add_swc_config_1 = require("../../utils/swc/add-swc-config");
13
16
  const add_swc_dependencies_1 = require("../../utils/swc/add-swc-dependencies");
17
+ const configuration_1 = require("../../utils/typescript/configuration");
14
18
  const create_ts_config_1 = require("../../utils/typescript/create-ts-config");
15
19
  const ts_config_1 = require("../../utils/typescript/ts-config");
20
+ const ts_solution_setup_1 = require("../../utils/typescript/ts-solution-setup");
16
21
  const versions_1 = require("../../utils/versions");
17
22
  const init_1 = require("../init/init");
18
23
  const generator_1 = require("../setup-verdaccio/generator");
24
+ const package_manager_workspaces_2 = require("./utils/package-manager-workspaces");
25
+ const plugin_registrations_1 = require("./utils/plugin-registrations");
19
26
  const defaultOutputDirectory = 'dist';
20
27
  async function libraryGenerator(tree, schema) {
21
28
  return await libraryGeneratorInternal(tree, {
22
29
  addPlugin: false,
30
+ useProjectJson: true,
23
31
  ...schema,
24
32
  });
25
33
  }
@@ -29,10 +37,13 @@ async function libraryGeneratorInternal(tree, schema) {
29
37
  ...schema,
30
38
  skipFormat: true,
31
39
  tsConfigName: schema.rootProject ? 'tsconfig.json' : 'tsconfig.base.json',
40
+ addTsConfigBase: true,
41
+ // In the new setup, Prettier is prompted for and installed during `create-nx-workspace`.
42
+ formatter: (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree) ? 'none' : 'prettier',
32
43
  }));
33
44
  const options = await normalizeOptions(tree, schema);
34
45
  createFiles(tree, options);
35
- await addProject(tree, options);
46
+ await configureProject(tree, options);
36
47
  if (!options.skipPackageJson) {
37
48
  tasks.push(addProjectDependencies(tree, options));
38
49
  }
@@ -98,17 +109,32 @@ async function libraryGeneratorInternal(tree, schema) {
98
109
  testEnvironment: options.testEnvironment,
99
110
  }, true);
100
111
  }
101
- if (!schema.skipTsConfig) {
112
+ if (!schema.skipTsConfig && !options.isUsingTsSolutionConfig) {
102
113
  (0, ts_config_1.addTsConfigPath)(tree, options.importPath, [
103
114
  (0, devkit_1.joinPathFragments)(options.projectRoot, './src', 'index.' + (options.js ? 'js' : 'ts')),
104
115
  ]);
105
116
  }
106
- if (options.bundler !== 'none') {
107
- addBundlerDependencies(tree, options);
117
+ if (options.isUsingTsSolutionConfig && options.unitTestRunner !== 'none') {
118
+ (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.spec.json'), (json) => {
119
+ const rootOffset = (0, devkit_1.offsetFromRoot)(options.projectRoot);
120
+ // ensure it extends from the root tsconfig.base.json
121
+ json.extends = (0, devkit_1.joinPathFragments)(rootOffset, 'tsconfig.base.json');
122
+ // ensure outDir is set to the correct value
123
+ json.compilerOptions ??= {};
124
+ json.compilerOptions.outDir = (0, devkit_1.joinPathFragments)(rootOffset, 'dist/out-tsc', options.projectRoot);
125
+ // add project reference to the runtime tsconfig.lib.json file
126
+ json.references ??= [];
127
+ json.references.push({ path: './tsconfig.lib.json' });
128
+ return json;
129
+ });
108
130
  }
109
131
  if (!options.skipFormat) {
110
132
  await (0, devkit_1.formatFiles)(tree);
111
133
  }
134
+ if (options.isUsingTsSolutionConfig &&
135
+ options.projectPackageManagerWorkspaceState !== 'included') {
136
+ tasks.push((0, package_manager_workspaces_2.getProjectPackageManagerWorkspaceStateWarningTask)(options.projectPackageManagerWorkspaceState, tree.root));
137
+ }
112
138
  if (options.publishable) {
113
139
  tasks.push(() => {
114
140
  logNxReleaseDocsInfo();
@@ -119,7 +145,28 @@ async function libraryGeneratorInternal(tree, schema) {
119
145
  });
120
146
  return (0, devkit_1.runTasksInSerial)(...tasks);
121
147
  }
122
- async function addProject(tree, options) {
148
+ async function configureProject(tree, options) {
149
+ if (options.hasPlugin) {
150
+ const nxJson = (0, devkit_1.readNxJson)(tree);
151
+ if (options.bundler === 'none') {
152
+ (0, plugin_registrations_1.ensureProjectIsExcludedFromPluginRegistrations)(nxJson, options.projectRoot);
153
+ }
154
+ else {
155
+ (0, plugin_registrations_1.ensureProjectIsIncludedInPluginRegistrations)(nxJson, options.projectRoot);
156
+ }
157
+ (0, devkit_1.updateNxJson)(tree, nxJson);
158
+ }
159
+ if (!options.useProjectJson) {
160
+ if (options.name !== options.importPath) {
161
+ // if the name is different than the package.json name, we need to set
162
+ // the proper name in the configuration
163
+ (0, devkit_1.updateProjectConfiguration)(tree, options.name, {
164
+ name: options.name,
165
+ root: options.projectRoot,
166
+ });
167
+ }
168
+ return;
169
+ }
123
170
  const projectConfiguration = {
124
171
  root: options.projectRoot,
125
172
  sourceRoot: (0, devkit_1.joinPathFragments)(options.projectRoot, 'src'),
@@ -185,7 +232,7 @@ async function addProject(tree, options) {
185
232
  root: projectConfiguration.root,
186
233
  tags: projectConfiguration.tags,
187
234
  targets: {},
188
- }, true);
235
+ });
189
236
  }
190
237
  }
191
238
  async function addLint(tree, options) {
@@ -267,39 +314,6 @@ async function addLint(tree, options) {
267
314
  }
268
315
  return task;
269
316
  }
270
- function addBundlerDependencies(tree, options) {
271
- (0, devkit_1.updateJson)(tree, `${options.projectRoot}/package.json`, (json) => {
272
- if (options.bundler === 'tsc') {
273
- json.dependencies = {
274
- ...json.dependencies,
275
- tslib: versions_1.tsLibVersion,
276
- };
277
- }
278
- else if (options.bundler === 'swc') {
279
- json.dependencies = {
280
- ...json.dependencies,
281
- '@swc/helpers': versions_1.swcHelpersVersion,
282
- };
283
- }
284
- return json;
285
- });
286
- }
287
- function updateTsConfig(tree, options) {
288
- (0, devkit_1.updateJson)(tree, (0, path_1.join)(options.projectRoot, 'tsconfig.json'), (json) => {
289
- if (options.strict) {
290
- json.compilerOptions = {
291
- ...json.compilerOptions,
292
- forceConsistentCasingInFileNames: true,
293
- strict: true,
294
- noImplicitOverride: true,
295
- noPropertyAccessFromIndexSignature: true,
296
- noImplicitReturns: true,
297
- noFallthroughCasesInSwitch: true,
298
- };
299
- }
300
- return json;
301
- });
302
- }
303
317
  function addBabelRc(tree, options) {
304
318
  const filename = '.babelrc';
305
319
  const babelrc = {
@@ -309,7 +323,7 @@ function addBabelRc(tree, options) {
309
323
  }
310
324
  function createFiles(tree, options) {
311
325
  const { className, name, propertyName } = (0, devkit_1.names)(options.projectNames.projectFileName);
312
- createProjectTsConfigJson(tree, options);
326
+ createProjectTsConfigs(tree, options);
313
327
  (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, './files/lib'), options.projectRoot, {
314
328
  ...options,
315
329
  dot: '.',
@@ -341,7 +355,6 @@ function createFiles(tree, options) {
341
355
  });
342
356
  }
343
357
  if (options.bundler === 'swc' || options.bundler === 'rollup') {
344
- (0, add_swc_dependencies_1.addSwcDependencies)(tree);
345
358
  (0, add_swc_config_1.addSwcConfig)(tree, options.projectRoot, options.bundler === 'swc' ? 'commonjs' : 'es6');
346
359
  }
347
360
  else if (options.includeBabelRc) {
@@ -366,6 +379,11 @@ function createFiles(tree, options) {
366
379
  if (!options.publishable && !options.rootProject) {
367
380
  json.private = true;
368
381
  }
382
+ if (options.isUsingTsSolutionConfig && options.publishable) {
383
+ // package.json and README.md are always included by default
384
+ // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#files
385
+ json.files = ['dist', '!**/*.tsbuildinfo'];
386
+ }
369
387
  return {
370
388
  ...json,
371
389
  dependencies: {
@@ -386,6 +404,11 @@ function createFiles(tree, options) {
386
404
  if (!options.publishable && !options.rootProject) {
387
405
  packageJson.private = true;
388
406
  }
407
+ if (options.isUsingTsSolutionConfig && options.publishable) {
408
+ // package.json and README.md are always included by default
409
+ // https://docs.npmjs.com/cli/v10/configuring-npm/package-json#files
410
+ packageJson.files = ['dist', '!**/*.tsbuildinfo'];
411
+ }
389
412
  (0, devkit_1.writeJson)(tree, packageJsonPath, packageJson);
390
413
  }
391
414
  if (options.config === 'npm-scripts') {
@@ -397,14 +420,9 @@ function createFiles(tree, options) {
397
420
  return json;
398
421
  });
399
422
  }
400
- else if ((!options.bundler || options.bundler === 'none') &&
401
- !(options.projectRoot === '.')) {
402
- tree.delete(packageJsonPath);
403
- }
404
423
  if (options.minimal && !(options.projectRoot === '.')) {
405
424
  tree.delete((0, path_1.join)(options.projectRoot, 'README.md'));
406
425
  }
407
- updateTsConfig(tree, options);
408
426
  }
409
427
  async function addJest(tree, options) {
410
428
  const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/jest', versions_1.nxVersion);
@@ -443,33 +461,117 @@ function replaceJestConfig(tree, options) {
443
461
  testEnvironment: options.testEnvironment,
444
462
  });
445
463
  }
464
+ function isNonInteractive() {
465
+ return ((0, is_ci_1.isCI)() || !process.stdout.isTTY || process.env.NX_INTERACTIVE !== 'true');
466
+ }
467
+ async function promptWhenInteractive(questions, defaultValue) {
468
+ if (isNonInteractive()) {
469
+ return defaultValue;
470
+ }
471
+ return await (0, enquirer_1.prompt)(questions);
472
+ }
446
473
  async function normalizeOptions(tree, options) {
447
474
  const nxJson = (0, devkit_1.readNxJson)(tree);
448
- const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' &&
449
- nxJson.useInferencePlugins !== false;
450
- options.addPlugin ??= addPlugin;
451
- /**
452
- * We are deprecating the compiler and the buildable options.
453
- * However, we want to keep the existing behavior for now.
454
- *
455
- * So, if the user has not provided a bundler, we will use the compiler option, if any.
456
- *
457
- * If the user has not provided a bundler and no compiler, but has set buildable to true,
458
- * we will use tsc, since that is the compiler the old generator used to default to, if buildable was true
459
- * and no compiler was provided.
460
- *
461
- * If the user has not provided a bundler and no compiler, and has not set buildable to true, then
462
- * set the bundler to tsc, to preserve old default behaviour (buildable: true by default).
463
- *
464
- * If it's publishable, we need to build the code before publishing it, so again
465
- * we default to `tsc`. In the previous version of this, it would set `buildable` to true
466
- * and that would default to `tsc`.
467
- *
468
- * In the past, the only way to get a non-buildable library was to set buildable to false.
469
- * Now, the only way to get a non-buildble library is to set bundler to none.
470
- * By default, with nothing provided, libraries are buildable with `@nx/js:tsc`.
471
- */
472
- options.bundler = options.bundler ?? options.compiler ?? 'tsc';
475
+ options.addPlugin ??=
476
+ process.env.NX_ADD_PLUGINS !== 'false' &&
477
+ nxJson.useInferencePlugins !== false;
478
+ const hasPlugin = (0, ts_solution_setup_1.isUsingTypeScriptPlugin)(tree);
479
+ const isUsingTsSolutionConfig = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
480
+ if (isUsingTsSolutionConfig) {
481
+ if (options.bundler === 'esbuild' || options.bundler === 'swc') {
482
+ throw new Error(`Cannot use the "${options.bundler}" bundler when using the @nx/js/typescript plugin.`);
483
+ }
484
+ if (options.bundler === undefined && options.compiler === undefined) {
485
+ options.bundler = await promptWhenInteractive({
486
+ type: 'select',
487
+ name: 'bundler',
488
+ message: `Which bundler would you like to use to build the library? Choose 'none' to skip build setup.`,
489
+ choices: [
490
+ { name: 'tsc' },
491
+ { name: 'rollup' },
492
+ { name: 'vite' },
493
+ { name: 'none' },
494
+ ],
495
+ initial: 0,
496
+ }, { bundler: 'tsc' }).then(({ bundler }) => bundler);
497
+ }
498
+ options.linter ??= await promptWhenInteractive({
499
+ type: 'select',
500
+ name: 'linter',
501
+ message: `Which linter would you like to use?`,
502
+ choices: [{ name: 'none' }, { name: 'eslint' }],
503
+ initial: 0,
504
+ }, { linter: 'none' }).then(({ linter }) => linter);
505
+ options.unitTestRunner ??= await promptWhenInteractive({
506
+ type: 'select',
507
+ name: 'unitTestRunner',
508
+ message: `Which unit test runner would you like to use?`,
509
+ choices: [{ name: 'none' }, { name: 'vitest' }, { name: 'jest' }],
510
+ initial: 0,
511
+ }, { unitTestRunner: 'none' }).then(({ unitTestRunner }) => unitTestRunner);
512
+ }
513
+ else {
514
+ if (options.bundler === undefined && options.compiler === undefined) {
515
+ options.bundler = await promptWhenInteractive({
516
+ type: 'select',
517
+ name: 'bundler',
518
+ message: `Which bundler would you like to use to build the library? Choose 'none' to skip build setup.`,
519
+ choices: [
520
+ { name: 'swc' },
521
+ { name: 'tsc' },
522
+ { name: 'rollup' },
523
+ { name: 'vite' },
524
+ { name: 'esbuild' },
525
+ { name: 'none' },
526
+ ],
527
+ initial: 1,
528
+ }, { bundler: 'tsc' }).then(({ bundler }) => bundler);
529
+ }
530
+ else {
531
+ /**
532
+ * We are deprecating the compiler and the buildable options.
533
+ * However, we want to keep the existing behavior for now.
534
+ *
535
+ * So, if the user has not provided a bundler, we will use the compiler option, if any.
536
+ *
537
+ * If the user has not provided a bundler and no compiler, but has set buildable to true,
538
+ * we will use tsc, since that is the compiler the old generator used to default to, if buildable was true
539
+ * and no compiler was provided.
540
+ *
541
+ * If the user has not provided a bundler and no compiler, and has not set buildable to true, then
542
+ * set the bundler to tsc, to preserve old default behaviour (buildable: true by default).
543
+ *
544
+ * If it's publishable, we need to build the code before publishing it, so again
545
+ * we default to `tsc`. In the previous version of this, it would set `buildable` to true
546
+ * and that would default to `tsc`.
547
+ *
548
+ * In the past, the only way to get a non-buildable library was to set buildable to false.
549
+ * Now, the only way to get a non-buildble library is to set bundler to none.
550
+ * By default, with nothing provided, libraries are buildable with `@nx/js:tsc`.
551
+ */
552
+ options.bundler ??= options.compiler;
553
+ }
554
+ options.linter ??= await promptWhenInteractive({
555
+ type: 'select',
556
+ name: 'linter',
557
+ message: `Which linter would you like to use?`,
558
+ choices: [{ name: 'eslint' }, { name: 'none' }],
559
+ initial: 0,
560
+ }, { linter: 'eslint' }).then(({ linter }) => linter);
561
+ options.unitTestRunner ??= await promptWhenInteractive({
562
+ type: 'select',
563
+ name: 'unitTestRunner',
564
+ message: `Which unit test runner would you like to use?`,
565
+ choices: [{ name: 'jest' }, { name: 'vitest' }, { name: 'none' }],
566
+ initial: 0,
567
+ }, { unitTestRunner: undefined }).then(({ unitTestRunner }) => unitTestRunner);
568
+ if (!options.unitTestRunner && options.bundler === 'vite') {
569
+ options.unitTestRunner = 'vitest';
570
+ }
571
+ else if (!options.unitTestRunner && options.config !== 'npm-scripts') {
572
+ options.unitTestRunner = 'jest';
573
+ }
574
+ }
473
575
  // ensure programmatic runs have an expected default
474
576
  if (!options.config) {
475
577
  options.config = 'project';
@@ -486,25 +588,15 @@ async function normalizeOptions(tree, options) {
486
588
  if (options.publishable === false && options.buildable === false) {
487
589
  options.bundler = 'none';
488
590
  }
489
- const { Linter } = (0, devkit_1.ensurePackage)('@nx/eslint', versions_1.nxVersion);
490
591
  if (options.config === 'npm-scripts') {
491
592
  options.unitTestRunner = 'none';
492
- options.linter = Linter.None;
593
+ options.linter = 'none';
493
594
  options.bundler = 'none';
494
595
  }
495
596
  if ((options.bundler === 'swc' || options.bundler === 'rollup') &&
496
597
  options.skipTypeCheck == null) {
497
598
  options.skipTypeCheck = false;
498
599
  }
499
- if (!options.unitTestRunner && options.bundler === 'vite') {
500
- options.unitTestRunner = 'vitest';
501
- }
502
- else if (!options.unitTestRunner && options.config !== 'npm-scripts') {
503
- options.unitTestRunner = 'jest';
504
- }
505
- if (!options.linter && options.config !== 'npm-scripts') {
506
- options.linter = Linter.EsLint;
507
- }
508
600
  const { projectName, names: projectNames, projectRoot, importPath, } = await (0, project_name_and_root_utils_1.determineProjectNameAndRootOptions)(tree, {
509
601
  name: options.name,
510
602
  projectType: 'library',
@@ -521,6 +613,9 @@ async function normalizeOptions(tree, options) {
521
613
  ? options.tags.split(',').map((s) => s.trim())
522
614
  : [];
523
615
  options.minimal ??= false;
616
+ const projectPackageManagerWorkspaceState = (0, package_manager_workspaces_1.getProjectPackageManagerWorkspaceState)(tree, projectRoot);
617
+ // We default to generate a project.json file if the new setup is not being used
618
+ options.useProjectJson ??= !isUsingTsSolutionConfig;
524
619
  return {
525
620
  ...options,
526
621
  fileName,
@@ -529,6 +624,9 @@ async function normalizeOptions(tree, options) {
529
624
  projectRoot,
530
625
  parsedTags,
531
626
  importPath,
627
+ hasPlugin,
628
+ isUsingTsSolutionConfig,
629
+ projectPackageManagerWorkspaceState,
532
630
  };
533
631
  }
534
632
  function addProjectDependencies(tree, options) {
@@ -540,7 +638,19 @@ function addProjectDependencies(tree, options) {
540
638
  });
541
639
  }
542
640
  else if (options.bundler == 'rollup') {
543
- return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@nx/rollup': versions_1.nxVersion, '@types/node': versions_1.typesNodeVersion });
641
+ const { dependencies, devDependencies } = (0, add_swc_dependencies_1.getSwcDependencies)();
642
+ return (0, devkit_1.addDependenciesToPackageJson)(tree, { ...dependencies }, {
643
+ ...devDependencies,
644
+ '@nx/rollup': versions_1.nxVersion,
645
+ '@types/node': versions_1.typesNodeVersion,
646
+ });
647
+ }
648
+ else if (options.bundler === 'tsc') {
649
+ return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { tslib: versions_1.tsLibVersion, '@types/node': versions_1.typesNodeVersion });
650
+ }
651
+ else if (options.bundler === 'swc') {
652
+ const { dependencies, devDependencies } = (0, add_swc_dependencies_1.getSwcDependencies)();
653
+ return (0, devkit_1.addDependenciesToPackageJson)(tree, { ...dependencies }, { ...devDependencies, '@types/node': versions_1.typesNodeVersion });
544
654
  }
545
655
  else {
546
656
  return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@types/node': versions_1.typesNodeVersion });
@@ -575,15 +685,92 @@ function getOutputPath(options) {
575
685
  }
576
686
  return (0, devkit_1.joinPathFragments)(...parts);
577
687
  }
578
- function createProjectTsConfigJson(tree, options) {
688
+ function createProjectTsConfigs(tree, options) {
689
+ const rootOffset = (0, devkit_1.offsetFromRoot)(options.projectRoot);
690
+ let compilerOptionOverrides = {
691
+ module: options.isUsingTsSolutionConfig
692
+ ? options.bundler === 'rollup'
693
+ ? 'esnext'
694
+ : 'nodenext'
695
+ : 'commonjs',
696
+ ...(options.isUsingTsSolutionConfig
697
+ ? options.bundler === 'rollup'
698
+ ? { moduleResolution: 'bundler' }
699
+ : { moduleResolution: 'nodenext' }
700
+ : {}),
701
+ ...(options.js ? { allowJs: true } : {}),
702
+ ...(options.strict
703
+ ? {
704
+ forceConsistentCasingInFileNames: true,
705
+ strict: true,
706
+ importHelpers: true,
707
+ noImplicitOverride: true,
708
+ noImplicitReturns: true,
709
+ noFallthroughCasesInSwitch: true,
710
+ ...(!options.isUsingTsSolutionConfig
711
+ ? { noPropertyAccessFromIndexSignature: true }
712
+ : {}),
713
+ }
714
+ : {}),
715
+ };
716
+ if (!options.rootProject || options.isUsingTsSolutionConfig) {
717
+ // filter out options already set with the same value in root tsconfig file that we're going to extend from
718
+ compilerOptionOverrides = (0, configuration_1.getNeededCompilerOptionOverrides)(tree, compilerOptionOverrides,
719
+ // must have been created by now
720
+ (0, ts_config_1.getRootTsConfigFileName)(tree));
721
+ }
722
+ // tsconfig.lib.json
723
+ (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files/tsconfig-lib', options.isUsingTsSolutionConfig ? 'ts-solution' : 'non-ts-solution'), options.projectRoot, {
724
+ ...options,
725
+ offsetFromRoot: rootOffset,
726
+ js: !!options.js,
727
+ compilerOptions: Object.entries(compilerOptionOverrides)
728
+ .map(([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`)
729
+ .join(',\n '),
730
+ tmpl: '',
731
+ });
732
+ // tsconfig.json
733
+ if (options.isUsingTsSolutionConfig) {
734
+ if (options.rootProject) {
735
+ // the root tsconfig.json is already created with the expected settings
736
+ // for the TS plugin, we just need to update it with the project-specific
737
+ // settings
738
+ (0, devkit_1.updateJson)(tree, 'tsconfig.json', (json) => {
739
+ json.references.push({
740
+ path: './tsconfig.lib.json',
741
+ });
742
+ return json;
743
+ });
744
+ }
745
+ else {
746
+ // create a new tsconfig.json for the project
747
+ const tsconfig = {
748
+ extends: (0, ts_config_1.getRelativePathToRootTsConfig)(tree, options.projectRoot),
749
+ files: [],
750
+ include: [],
751
+ references: [{ path: './tsconfig.lib.json' }],
752
+ };
753
+ (0, devkit_1.writeJson)(tree, (0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.json'), tsconfig);
754
+ // update root project tsconfig.json references with the new lib tsconfig
755
+ (0, devkit_1.updateJson)(tree, 'tsconfig.json', (json) => {
756
+ json.references ??= [];
757
+ json.references.push({
758
+ path: options.projectRoot.startsWith('./')
759
+ ? options.projectRoot
760
+ : './' + options.projectRoot,
761
+ });
762
+ return json;
763
+ });
764
+ }
765
+ return;
766
+ }
579
767
  const tsconfig = {
580
768
  extends: options.rootProject
581
769
  ? undefined
582
770
  : (0, ts_config_1.getRelativePathToRootTsConfig)(tree, options.projectRoot),
583
771
  compilerOptions: {
584
772
  ...(options.rootProject ? create_ts_config_1.tsConfigBaseOptions : {}),
585
- module: 'commonjs',
586
- allowJs: options.js ? true : undefined,
773
+ ...compilerOptionOverrides,
587
774
  },
588
775
  files: [],
589
776
  include: [],
@@ -618,8 +805,12 @@ function determineEntryFields(options) {
618
805
  case 'tsc':
619
806
  return {
620
807
  type: 'commonjs',
621
- main: './src/index.js',
622
- typings: './src/index.d.ts',
808
+ main: options.isUsingTsSolutionConfig
809
+ ? './dist/index.js'
810
+ : './src/index.js',
811
+ typings: options.isUsingTsSolutionConfig
812
+ ? './dist/index.d.ts'
813
+ : './src/index.d.ts',
623
814
  };
624
815
  case 'swc':
625
816
  return {
@@ -631,16 +822,26 @@ function determineEntryFields(options) {
631
822
  return {
632
823
  // Since we're publishing both formats, skip the type field.
633
824
  // Bundlers or Node will determine the entry point to use.
634
- main: './index.cjs',
635
- module: './index.js',
825
+ main: options.isUsingTsSolutionConfig
826
+ ? './dist/index.cjs'
827
+ : './index.cjs',
828
+ module: options.isUsingTsSolutionConfig
829
+ ? './dist/index.js'
830
+ : './index.js',
636
831
  };
637
832
  case 'vite':
638
833
  return {
639
834
  // Since we're publishing both formats, skip the type field.
640
835
  // Bundlers or Node will determine the entry point to use.
641
- main: './index.js',
642
- module: './index.mjs',
643
- typings: './index.d.ts',
836
+ main: options.isUsingTsSolutionConfig
837
+ ? './dist/index.js'
838
+ : './index.js',
839
+ module: options.isUsingTsSolutionConfig
840
+ ? './dist/index.mjs'
841
+ : './index.mjs',
842
+ typings: options.isUsingTsSolutionConfig
843
+ ? './dist/index.d.ts'
844
+ : './index.d.ts',
644
845
  };
645
846
  case 'esbuild':
646
847
  // For libraries intended for Node, use CJS.
@@ -0,0 +1,53 @@
1
+ import type {
2
+ ProjectNameAndRootFormat,
3
+ ProjectNameAndRootOptions,
4
+ } from '@nx/devkit/src/generators/project-name-and-root-utils';
5
+ // nx-ignore-next-line
6
+ const { Linter, LinterType } = require('@nx/eslint'); // use require to import to avoid circular dependency
7
+ import type { ProjectPackageManagerWorkspaceState } from '../../utils/package-manager-workspaces';
8
+
9
+ export type Compiler = 'tsc' | 'swc';
10
+ export type Bundler = 'swc' | 'tsc' | 'rollup' | 'vite' | 'esbuild' | 'none';
11
+
12
+ export interface LibraryGeneratorSchema {
13
+ name: string;
14
+ directory?: string;
15
+ projectNameAndRootFormat?: ProjectNameAndRootFormat;
16
+ skipFormat?: boolean;
17
+ tags?: string;
18
+ skipTsConfig?: boolean;
19
+ skipPackageJson?: boolean;
20
+ includeBabelRc?: boolean;
21
+ unitTestRunner?: 'jest' | 'vitest' | 'none';
22
+ linter?: Linter | LinterType;
23
+ testEnvironment?: 'jsdom' | 'node';
24
+ importPath?: string;
25
+ js?: boolean;
26
+ pascalCaseFiles?: boolean;
27
+ strict?: boolean;
28
+ publishable?: boolean;
29
+ buildable?: boolean;
30
+ setParserOptionsProject?: boolean;
31
+ config?: 'workspace' | 'project' | 'npm-scripts';
32
+ compiler?: Compiler;
33
+ bundler?: Bundler;
34
+ skipTypeCheck?: boolean;
35
+ minimal?: boolean;
36
+ rootProject?: boolean;
37
+ simpleName?: boolean;
38
+ addPlugin?: boolean;
39
+ useProjectJson?: boolean;
40
+ }
41
+
42
+ export interface NormalizedLibraryGeneratorOptions
43
+ extends LibraryGeneratorSchema {
44
+ name: string;
45
+ projectNames: ProjectNameAndRootOptions['names'];
46
+ fileName: string;
47
+ projectRoot: string;
48
+ parsedTags: string[];
49
+ importPath?: string;
50
+ hasPlugin: boolean;
51
+ isUsingTsSolutionConfig: boolean;
52
+ projectPackageManagerWorkspaceState: ProjectPackageManagerWorkspaceState;
53
+ }