@nx/eslint 17.0.4 → 17.0.6

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 (55) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +4 -9
  3. package/generators.json +0 -6
  4. package/migrations.json +0 -68
  5. package/package.json +8 -9
  6. package/src/executors/lint/hasher.js +1 -1
  7. package/src/executors/lint/lint.impl.js +33 -67
  8. package/src/executors/lint/schema.d.ts +0 -1
  9. package/src/executors/lint/schema.json +3 -7
  10. package/src/executors/lint/utility/eslint-utils.js +1 -5
  11. package/src/generators/convert-to-flat-config/converters/json-converter.d.ts +1 -6
  12. package/src/generators/convert-to-flat-config/converters/json-converter.js +33 -28
  13. package/src/generators/convert-to-flat-config/generator.js +17 -73
  14. package/src/generators/convert-to-flat-config/schema.json +1 -1
  15. package/src/generators/init/global-eslint-config.js +5 -9
  16. package/src/generators/init/init-migration.d.ts +1 -1
  17. package/src/generators/init/init-migration.js +14 -53
  18. package/src/generators/init/init.d.ts +5 -5
  19. package/src/generators/init/init.js +35 -63
  20. package/src/generators/lint-project/lint-project.d.ts +3 -9
  21. package/src/generators/lint-project/lint-project.js +40 -76
  22. package/src/generators/utils/eslint-file.d.ts +5 -2
  23. package/src/generators/utils/eslint-file.js +30 -37
  24. package/src/generators/utils/flat-config/ast-utils.d.ts +5 -4
  25. package/src/generators/utils/flat-config/ast-utils.js +38 -35
  26. package/src/generators/utils/flat-config/path-utils.d.ts +1 -2
  27. package/src/generators/utils/flat-config/path-utils.js +12 -9
  28. package/src/generators/workspace-rule/files/__name__.ts__tmpl__ +2 -2
  29. package/src/generators/workspace-rule/schema.json +1 -1
  30. package/src/generators/workspace-rule/workspace-rule.js +2 -7
  31. package/src/generators/workspace-rules-project/files/tsconfig.json__tmpl__ +1 -2
  32. package/src/generators/workspace-rules-project/schema.json +1 -1
  33. package/src/generators/workspace-rules-project/workspace-rules-project.d.ts +2 -3
  34. package/src/generators/workspace-rules-project/workspace-rules-project.js +9 -11
  35. package/src/migrations/update-15-0-0/add-eslint-inputs.js +2 -2
  36. package/src/migrations/update-15-7-1/add-eslint-ignore.js +2 -2
  37. package/src/utils/versions.d.ts +2 -2
  38. package/src/utils/versions.js +2 -2
  39. package/plugin.d.ts +0 -1
  40. package/plugin.js +0 -5
  41. package/src/generators/init/schema.json +0 -28
  42. package/src/generators/lint-project/setup-root-eslint.d.ts +0 -7
  43. package/src/generators/lint-project/setup-root-eslint.js +0 -33
  44. package/src/generators/utils/plugin.d.ts +0 -2
  45. package/src/generators/utils/plugin.js +0 -11
  46. package/src/migrations/update-17-1-0/update-typescript-eslint.d.ts +0 -2
  47. package/src/migrations/update-17-1-0/update-typescript-eslint.js +0 -74
  48. package/src/migrations/update-17-2-0/simplify-eslint-patterns.d.ts +0 -2
  49. package/src/migrations/update-17-2-0/simplify-eslint-patterns.js +0 -46
  50. package/src/migrations/update-17-2-9/move-options-to-target-defaults.d.ts +0 -2
  51. package/src/migrations/update-17-2-9/move-options-to-target-defaults.js +0 -107
  52. package/src/plugins/plugin.d.ts +0 -6
  53. package/src/plugins/plugin.js +0 -117
  54. package/src/utils/config-file.d.ts +0 -4
  55. package/src/utils/config-file.js +0 -18
@@ -3,29 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertToFlatConfigGenerator = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const eslint_file_1 = require("../utils/eslint-file");
6
- const path_1 = require("path");
7
- const versions_1 = require("../../utils/versions");
8
6
  const json_converter_1 = require("./converters/json-converter");
9
- const js_yaml_1 = require("js-yaml");
10
7
  async function convertToFlatConfigGenerator(tree, options) {
11
8
  const eslintFile = (0, eslint_file_1.findEslintFile)(tree);
12
9
  if (!eslintFile) {
13
10
  throw new Error('Could not find root eslint file');
14
11
  }
15
- if (eslintFile.endsWith('.js')) {
16
- throw new Error('Only json and yaml eslint config files are supported for conversion');
12
+ if (!eslintFile.endsWith('.json')) {
13
+ throw new Error('Only json eslint config files are supported for conversion');
17
14
  }
18
- const eslintIgnoreFiles = new Set(['.eslintignore']);
19
- // convert root eslint config to eslint.config.js
15
+ // rename root eslint config to eslint.config.js
20
16
  convertRootToFlatConfig(tree, eslintFile);
21
- // convert project eslint files to eslint.config.js
17
+ // rename and map files
22
18
  const projects = (0, devkit_1.getProjects)(tree);
23
19
  for (const [project, projectConfig] of projects) {
24
- convertProjectToFlatConfig(tree, project, projectConfig, (0, devkit_1.readNxJson)(tree), eslintIgnoreFiles);
25
- }
26
- // delete all .eslintignore files
27
- for (const ignoreFile of eslintIgnoreFiles) {
28
- tree.delete(ignoreFile);
20
+ convertProjectToFlatConfig(tree, project, projectConfig, (0, devkit_1.readNxJson)(tree));
29
21
  }
30
22
  // replace references in nx.json
31
23
  updateNxJsonConfig(tree);
@@ -37,42 +29,27 @@ async function convertToFlatConfigGenerator(tree, options) {
37
29
  exports.convertToFlatConfigGenerator = convertToFlatConfigGenerator;
38
30
  exports.default = convertToFlatConfigGenerator;
39
31
  function convertRootToFlatConfig(tree, eslintFile) {
40
- if (/\.base\.(js|json|yml|yaml)$/.test(eslintFile)) {
41
- convertConfigToFlatConfig(tree, '', eslintFile, 'eslint.base.config.js');
32
+ if (eslintFile.endsWith('.base.json')) {
33
+ convertConfigToFlatConfig(tree, '', '.eslintrc.base.json', 'eslint.base.config.js');
42
34
  }
43
- convertConfigToFlatConfig(tree, '', eslintFile.replace('.base.', '.'), 'eslint.config.js');
35
+ convertConfigToFlatConfig(tree, '', '.eslintrc.json', 'eslint.config.js');
44
36
  }
45
- function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslintIgnoreFiles) {
46
- const eslintFile = (0, eslint_file_1.findEslintFile)(tree, projectConfig.root);
47
- if (eslintFile && !eslintFile.endsWith('.js')) {
37
+ function convertProjectToFlatConfig(tree, project, projectConfig, nxJson) {
38
+ if (tree.exists(`${projectConfig.root}/.eslintrc.json`)) {
48
39
  if (projectConfig.targets) {
49
- const eslintTargets = Object.keys(projectConfig.targets || {}).filter((t) => projectConfig.targets[t].executor === '@nx/eslint:lint' ||
50
- projectConfig.targets[t].command?.includes('eslint'));
51
- let ignorePath;
40
+ const eslintTargets = Object.keys(projectConfig.targets || {}).filter((t) => projectConfig.targets[t].executor === '@nx/eslint:lint');
52
41
  for (const target of eslintTargets) {
53
42
  // remove any obsolete `eslintConfig` options pointing to the old config file
54
43
  if (projectConfig.targets[target].options?.eslintConfig) {
55
44
  delete projectConfig.targets[target].options.eslintConfig;
56
45
  }
57
- if (projectConfig.targets[target].options?.ignorePath) {
58
- ignorePath = projectConfig.targets[target].options.ignorePath;
59
- delete projectConfig.targets[target].options.ignorePath;
60
- }
61
46
  (0, devkit_1.updateProjectConfiguration)(tree, project, projectConfig);
62
47
  }
63
- const nxHasEsLintTargets = Object.keys(nxJson.targetDefaults || {}).some((t) => (t === '@nx/eslint:lint' ||
64
- nxJson.targetDefaults[t].executor === '@nx/eslint:lint' ||
65
- nxJson.targetDefaults[t].command?.includes('eslint')) &&
48
+ const nxHasLintTargets = Object.keys(nxJson.targetDefaults || {}).some((t) => (t === '@nx/eslint:lint' ||
49
+ nxJson.targetDefaults[t].executor === '@nx/eslint:lint') &&
66
50
  projectConfig.targets?.[t]);
67
- const nxHasEsLintPlugin = (nxJson.plugins || []).some((p) => typeof p === 'string'
68
- ? p === '@nx/eslint/plugin'
69
- : p.plugin === '@nx/eslint/plugin');
70
- if (nxHasEsLintTargets || nxHasEsLintPlugin || eslintTargets.length > 0) {
71
- convertConfigToFlatConfig(tree, projectConfig.root, eslintFile, 'eslint.config.js', ignorePath);
72
- eslintIgnoreFiles.add(`${projectConfig.root}/.eslintignore`);
73
- if (ignorePath) {
74
- eslintIgnoreFiles.add(ignorePath);
75
- }
51
+ if (nxHasLintTargets || eslintTargets.length > 0) {
52
+ convertConfigToFlatConfig(tree, projectConfig.root, '.eslintrc.json', 'eslint.config.js');
76
53
  }
77
54
  }
78
55
  }
@@ -101,39 +78,6 @@ function updateNxJsonConfig(tree) {
101
78
  });
102
79
  }
103
80
  }
104
- function convertConfigToFlatConfig(tree, root, source, target, ignorePath) {
105
- const ignorePaths = ignorePath
106
- ? [ignorePath, `${root}/.eslintignore`]
107
- : [`${root}/.eslintignore`];
108
- if (source.endsWith('.json')) {
109
- const config = (0, devkit_1.readJson)(tree, `${root}/${source}`);
110
- const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths);
111
- return processConvertedConfig(tree, root, source, target, conversionResult);
112
- }
113
- if (source.endsWith('.yaml') || source.endsWith('.yml')) {
114
- const originalContent = tree.read(`${root}/${source}`, 'utf-8');
115
- const config = (0, js_yaml_1.load)(originalContent, {
116
- json: true,
117
- filename: source,
118
- });
119
- const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths);
120
- return processConvertedConfig(tree, root, source, target, conversionResult);
121
- }
122
- }
123
- function processConvertedConfig(tree, root, source, target, { content, addESLintRC, addESLintJS, }) {
124
- // remove original config file
125
- tree.delete((0, path_1.join)(root, source));
126
- // save new
127
- tree.write((0, path_1.join)(root, target), content);
128
- // add missing packages
129
- if (addESLintRC) {
130
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
131
- '@eslint/eslintrc': versions_1.eslintrcVersion,
132
- });
133
- }
134
- if (addESLintJS) {
135
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
136
- '@eslint/js': versions_1.eslintVersion,
137
- });
138
- }
81
+ function convertConfigToFlatConfig(tree, root, source, target) {
82
+ (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, source, target);
139
83
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://json-schema.org/schema",
2
+ "$schema": "http://json-schema.org/schema",
3
3
  "$id": "ConvertToFlatConfig",
4
4
  "cli": "nx",
5
5
  "description": "Convert an Nx workspace's ESLint configs to use Flat Config.",
@@ -80,23 +80,19 @@ const getGlobalEsLintConfiguration = (unitTestRunner, rootProject) => {
80
80
  exports.getGlobalEsLintConfiguration = getGlobalEsLintConfiguration;
81
81
  const getGlobalFlatEslintConfiguration = (unitTestRunner, rootProject) => {
82
82
  const nodeList = (0, ast_utils_1.createNodeList)(new Map(), [], true);
83
- let content = (0, ast_utils_1.stringifyNodeList)(nodeList);
83
+ let content = (0, ast_utils_1.stringifyNodeList)(nodeList, '', 'eslint.config.js');
84
84
  content = (0, ast_utils_1.addImportToFlatConfig)(content, 'nxPlugin', '@nx/eslint-plugin');
85
85
  content = (0, ast_utils_1.addPluginsToExportsBlock)(content, [
86
86
  { name: '@nx', varName: 'nxPlugin', imp: '@nx/eslint-plugin' },
87
87
  ]);
88
88
  if (!rootProject) {
89
- content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)(moduleBoundariesOverride));
89
+ content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)(moduleBoundariesOverride, ''));
90
90
  }
91
- content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)(exports.typeScriptOverride));
92
- content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)(exports.javaScriptOverride));
91
+ content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)(exports.typeScriptOverride, ''));
92
+ content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)(exports.javaScriptOverride, ''));
93
93
  if (unitTestRunner === 'jest') {
94
- content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)(jestOverride));
94
+ content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)(jestOverride, ''));
95
95
  }
96
- // add ignore for .nx folder
97
- content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateAst)({
98
- ignores: ['.nx'],
99
- }));
100
96
  return content;
101
97
  };
102
98
  exports.getGlobalFlatEslintConfiguration = getGlobalFlatEslintConfiguration;
@@ -1,3 +1,3 @@
1
1
  import { ProjectConfiguration, TargetConfiguration, Tree } from '@nx/devkit';
2
- export declare function migrateConfigToMonorepoStyle(projects: ProjectConfiguration[], tree: Tree, unitTestRunner: string, keepExistingVersions?: boolean): void;
2
+ export declare function migrateConfigToMonorepoStyle(projects: ProjectConfiguration[], tree: Tree, unitTestRunner: string): void;
3
3
  export declare function findLintTarget(project: ProjectConfiguration): TargetConfiguration;
@@ -8,58 +8,24 @@ const global_eslint_config_1 = require("./global-eslint-config");
8
8
  const flat_config_1 = require("../../utils/flat-config");
9
9
  const versions_1 = require("../../utils/versions");
10
10
  const ast_utils_1 = require("../utils/flat-config/ast-utils");
11
- const plugin_1 = require("../utils/plugin");
12
- const config_file_1 = require("../../utils/config-file");
13
- function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner, keepExistingVersions) {
14
- const rootEslintConfig = (0, eslint_file_1.findEslintFile)(tree);
15
- let skipCleanup = false;
16
- if (rootEslintConfig?.match(/\.base\./) &&
17
- !projects.some((p) => p.root === '.')) {
18
- // if the migration has been run already, we need to rename the base config
19
- // and only update the extends paths
20
- tree.rename(rootEslintConfig, rootEslintConfig.replace('.base.', '.'));
21
- skipCleanup = true;
11
+ function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner) {
12
+ if ((0, flat_config_1.useFlatConfig)(tree)) {
13
+ // we need this for the compat
14
+ (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
15
+ '@eslint/js': versions_1.eslintVersion,
16
+ });
17
+ tree.write('eslint.base.config.js', (0, global_eslint_config_1.getGlobalFlatEslintConfiguration)(unitTestRunner));
22
18
  }
23
19
  else {
24
- if ((0, flat_config_1.useFlatConfig)(tree)) {
25
- // we need this for the compat
26
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
27
- '@eslint/js': versions_1.eslintVersion,
28
- }, undefined, keepExistingVersions);
29
- tree.write(tree.exists('eslint.config.js')
30
- ? 'eslint.base.config.js'
31
- : 'eslint.config.js', (0, global_eslint_config_1.getGlobalFlatEslintConfiguration)(unitTestRunner));
32
- }
33
- else {
34
- const eslintFile = (0, eslint_file_1.findEslintFile)(tree, '.');
35
- (0, devkit_1.writeJson)(tree, eslintFile ? '.eslintrc.base.json' : '.eslintrc.json', (0, global_eslint_config_1.getGlobalEsLintConfiguration)(unitTestRunner));
36
- }
20
+ (0, devkit_1.writeJson)(tree, '.eslintrc.base.json', (0, global_eslint_config_1.getGlobalEsLintConfiguration)(unitTestRunner));
37
21
  }
38
- // update extends in all projects' eslint configs
22
+ // update extens in all projects' eslint configs
39
23
  projects.forEach((project) => {
40
- let eslintFile;
41
24
  const lintTarget = findLintTarget(project);
42
25
  if (lintTarget) {
43
- // If target is configured in project.json, read file from target options.
44
- eslintFile =
45
- lintTarget.options?.eslintConfig || (0, eslint_file_1.findEslintFile)(tree, project.root);
46
- }
47
- else if ((0, plugin_1.hasEslintPlugin)(tree)) {
48
- // Otherwise, if `@nx/eslint/plugin` is used, match any of the known config files.
49
- for (const f of config_file_1.ESLINT_CONFIG_FILENAMES) {
50
- if (tree.exists((0, devkit_1.joinPathFragments)(project.root, f))) {
51
- eslintFile = f;
52
- break;
53
- }
54
- }
55
- }
56
- if (eslintFile) {
57
- const projectEslintPath = (0, devkit_1.joinPathFragments)(project.root, eslintFile);
58
- if (skipCleanup) {
59
- const content = tree.read(projectEslintPath, 'utf-8');
60
- tree.write(projectEslintPath, content.replace(rootEslintConfig, rootEslintConfig.replace('.base.', '.')));
61
- }
62
- else {
26
+ const eslintFile = lintTarget.options.eslintConfig || (0, eslint_file_1.findEslintFile)(tree, project.root);
27
+ if (eslintFile) {
28
+ const projectEslintPath = (0, devkit_1.joinPathFragments)(project.root, eslintFile);
63
29
  migrateEslintFile(projectEslintPath, tree);
64
30
  }
65
31
  }
@@ -73,14 +39,13 @@ function findLintTarget(project) {
73
39
  }
74
40
  exports.findLintTarget = findLintTarget;
75
41
  function migrateEslintFile(projectEslintPath, tree) {
76
- const baseFile = (0, eslint_file_1.findEslintFile)(tree);
77
42
  if ((0, eslint_file_1.isEslintConfigSupported)(tree)) {
78
43
  if ((0, flat_config_1.useFlatConfig)(tree)) {
79
44
  let config = tree.read(projectEslintPath, 'utf-8');
80
45
  // remove @nx plugin
81
46
  config = (0, ast_utils_1.removePlugin)(config, '@nx', '@nx/eslint-plugin-nx');
82
47
  // extend eslint.base.config.js
83
- config = (0, ast_utils_1.addImportToFlatConfig)(config, 'baseConfig', `${(0, devkit_1.offsetFromRoot)((0, path_1.dirname)(projectEslintPath))}${baseFile}`);
48
+ config = (0, ast_utils_1.addImportToFlatConfig)(config, 'baseConfig', `${(0, devkit_1.offsetFromRoot)((0, path_1.dirname)(projectEslintPath))}eslint.base.config.js`);
84
49
  config = (0, ast_utils_1.addBlockToFlatConfigExport)(config, (0, ast_utils_1.generateSpreadElement)('baseConfig'), { insertAtTheEnd: false });
85
50
  // cleanup file extends
86
51
  config = (0, ast_utils_1.removeCompatExtends)(config, [
@@ -104,11 +69,7 @@ function migrateEslintFile(projectEslintPath, tree) {
104
69
  }
105
70
  // add extends
106
71
  json.extends = json.extends || [];
107
- // ensure extends is an array
108
- if (typeof json.extends === 'string') {
109
- json.extends = [json.extends];
110
- }
111
- const pathToRootConfig = `${(0, devkit_1.offsetFromRoot)((0, path_1.dirname)(projectEslintPath))}${baseFile}`;
72
+ const pathToRootConfig = `${(0, devkit_1.offsetFromRoot)((0, path_1.dirname)(projectEslintPath))}.eslintrc.base.json`;
112
73
  if (json.extends.indexOf(pathToRootConfig) === -1) {
113
74
  json.extends.push(pathToRootConfig);
114
75
  }
@@ -1,9 +1,9 @@
1
1
  import type { GeneratorCallback, Tree } from '@nx/devkit';
2
+ import { Linter } from '../utils/linter';
2
3
  export interface LinterInitOptions {
4
+ linter?: Linter;
5
+ unitTestRunner?: string;
3
6
  skipPackageJson?: boolean;
4
- keepExistingVersions?: boolean;
5
- updatePackageScripts?: boolean;
6
- addPlugin?: boolean;
7
+ rootProject?: boolean;
7
8
  }
8
- export declare function initEsLint(tree: Tree, options: LinterInitOptions): Promise<GeneratorCallback>;
9
- export declare function lintInitGenerator(tree: Tree, options: LinterInitOptions): Promise<GeneratorCallback>;
9
+ export declare function lintInitGenerator(tree: Tree, options: LinterInitOptions): GeneratorCallback;
@@ -1,29 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lintInitGenerator = exports.initEsLint = void 0;
3
+ exports.lintInitGenerator = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
- const update_package_scripts_1 = require("@nx/devkit/src/utils/update-package-scripts");
6
5
  const versions_1 = require("../../utils/versions");
7
6
  const eslint_file_1 = require("../utils/eslint-file");
8
- const plugin_1 = require("../../plugins/plugin");
9
- const plugin_2 = require("../utils/plugin");
10
- function updateProductionFileset(tree) {
7
+ const global_eslint_config_1 = require("./global-eslint-config");
8
+ function addTargetDefaults(tree) {
11
9
  const nxJson = (0, devkit_1.readNxJson)(tree);
12
10
  const productionFileSet = nxJson.namedInputs?.production;
13
11
  if (productionFileSet) {
12
+ // Remove .eslintrc.json
14
13
  productionFileSet.push('!{projectRoot}/.eslintrc.json');
15
14
  productionFileSet.push('!{projectRoot}/eslint.config.js');
16
15
  // Dedupe and set
17
16
  nxJson.namedInputs.production = Array.from(new Set(productionFileSet));
18
17
  }
19
- (0, devkit_1.updateNxJson)(tree, nxJson);
20
- }
21
- function addTargetDefaults(tree) {
22
- const nxJson = (0, devkit_1.readNxJson)(tree);
23
18
  nxJson.targetDefaults ??= {};
24
- nxJson.targetDefaults['@nx/eslint:lint'] ??= {};
25
- nxJson.targetDefaults['@nx/eslint:lint'].cache ??= true;
26
- nxJson.targetDefaults['@nx/eslint:lint'].inputs ??= [
19
+ nxJson.targetDefaults.lint ??= {};
20
+ nxJson.targetDefaults.lint.inputs ??= [
27
21
  'default',
28
22
  `{workspaceRoot}/.eslintrc.json`,
29
23
  `{workspaceRoot}/.eslintignore`,
@@ -31,63 +25,41 @@ function addTargetDefaults(tree) {
31
25
  ];
32
26
  (0, devkit_1.updateNxJson)(tree, nxJson);
33
27
  }
34
- function addPlugin(tree) {
35
- const nxJson = (0, devkit_1.readNxJson)(tree);
36
- nxJson.plugins ??= [];
37
- for (const plugin of nxJson.plugins) {
38
- if (typeof plugin === 'string'
39
- ? plugin === '@nx/eslint/plugin'
40
- : plugin.plugin === '@nx/eslint/plugin') {
41
- return;
42
- }
43
- }
44
- nxJson.plugins.push({
45
- plugin: '@nx/eslint/plugin',
46
- options: {
47
- targetName: 'lint',
48
- },
49
- });
50
- (0, devkit_1.updateNxJson)(tree, nxJson);
51
- }
52
- async function initEsLint(tree, options) {
53
- const nxJson = (0, devkit_1.readNxJson)(tree);
54
- const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
55
- nxJson.useInferencePlugins !== false;
56
- options.addPlugin ??= addPluginDefault;
57
- const hasPlugin = (0, plugin_2.hasEslintPlugin)(tree);
58
- const rootEslintFile = (0, eslint_file_1.findEslintFile)(tree);
59
- if (rootEslintFile && options.addPlugin && !hasPlugin) {
60
- addPlugin(tree);
61
- if (options.updatePackageScripts) {
62
- await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
63
- }
64
- return () => { };
65
- }
66
- if (rootEslintFile) {
28
+ /**
29
+ * Initializes ESLint configuration in a workspace and adds necessary dependencies.
30
+ */
31
+ function initEsLint(tree, options) {
32
+ if ((0, eslint_file_1.findEslintFile)(tree)) {
67
33
  return () => { };
68
34
  }
69
- updateProductionFileset(tree);
70
- if (options.addPlugin) {
71
- addPlugin(tree);
35
+ if (!options.skipPackageJson) {
36
+ (0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/eslint'], []);
72
37
  }
73
- else {
74
- addTargetDefaults(tree);
38
+ (0, devkit_1.writeJson)(tree, '.eslintrc.json', (0, global_eslint_config_1.getGlobalEsLintConfiguration)(options.unitTestRunner, options.rootProject));
39
+ tree.write('.eslintignore', 'node_modules\n');
40
+ addTargetDefaults(tree);
41
+ if (tree.exists('.vscode/extensions.json')) {
42
+ (0, devkit_1.updateJson)(tree, '.vscode/extensions.json', (json) => {
43
+ json.recommendations ||= [];
44
+ const extension = 'dbaeumer.vscode-eslint';
45
+ if (!json.recommendations.includes(extension)) {
46
+ json.recommendations.push(extension);
47
+ }
48
+ return json;
49
+ });
75
50
  }
76
- const tasks = [];
77
- if (!options.skipPackageJson) {
78
- tasks.push((0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/eslint'], []));
79
- tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
51
+ return !options.skipPackageJson
52
+ ? (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
80
53
  '@nx/eslint': versions_1.nxVersion,
54
+ '@nx/eslint-plugin': versions_1.nxVersion,
55
+ '@typescript-eslint/parser': versions_1.typescriptESLintVersion,
56
+ '@typescript-eslint/eslint-plugin': versions_1.typescriptESLintVersion,
81
57
  eslint: versions_1.eslintVersion,
82
- }, undefined, options.keepExistingVersions));
83
- }
84
- if (options.updatePackageScripts) {
85
- await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
86
- }
87
- return (0, devkit_1.runTasksInSerial)(...tasks);
58
+ 'eslint-config-prettier': versions_1.eslintConfigPrettierVersion,
59
+ })
60
+ : () => { };
88
61
  }
89
- exports.initEsLint = initEsLint;
90
- async function lintInitGenerator(tree, options) {
91
- return await initEsLint(tree, { addPlugin: false, ...options });
62
+ function lintInitGenerator(tree, options) {
63
+ return initEsLint(tree, options);
92
64
  }
93
65
  exports.lintInitGenerator = lintInitGenerator;
@@ -1,4 +1,4 @@
1
- import type { GeneratorCallback, Tree } from '@nx/devkit';
1
+ import type { Tree } from '@nx/devkit';
2
2
  import { Linter as LinterEnum } from '../utils/linter';
3
3
  interface LintProjectOptions {
4
4
  project: string;
@@ -10,13 +10,7 @@ interface LintProjectOptions {
10
10
  skipPackageJson?: boolean;
11
11
  unitTestRunner?: string;
12
12
  rootProject?: boolean;
13
- keepExistingVersions?: boolean;
14
- addPlugin?: boolean;
15
- /**
16
- * @internal
17
- */
18
- addExplicitTargets?: boolean;
19
13
  }
20
- export declare function lintProjectGenerator(tree: Tree, options: LintProjectOptions): Promise<GeneratorCallback>;
21
- export declare function lintProjectGeneratorInternal(tree: Tree, options: LintProjectOptions): Promise<GeneratorCallback>;
14
+ export declare function mapLintPattern(projectRoot: string, extension: string, rootProject?: boolean): string;
15
+ export declare function lintProjectGenerator(tree: Tree, options: LintProjectOptions): Promise<import("@nx/devkit").GeneratorCallback>;
22
16
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lintProjectGeneratorInternal = exports.lintProjectGenerator = void 0;
3
+ exports.lintProjectGenerator = exports.mapLintPattern = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const eslint_file_1 = require("../utils/eslint-file");
6
6
  const path_1 = require("path");
@@ -9,64 +9,34 @@ const init_migration_1 = require("../init/init-migration");
9
9
  const project_configuration_1 = require("nx/src/generators/utils/project-configuration");
10
10
  const flat_config_1 = require("../../utils/flat-config");
11
11
  const ast_utils_1 = require("../utils/flat-config/ast-utils");
12
- const config_file_1 = require("../../utils/config-file");
13
- const plugin_1 = require("../utils/plugin");
14
- const setup_root_eslint_1 = require("./setup-root-eslint");
15
- function lintProjectGenerator(tree, options) {
16
- return lintProjectGeneratorInternal(tree, { addPlugin: false, ...options });
12
+ function mapLintPattern(projectRoot, extension, rootProject) {
13
+ if (rootProject && (projectRoot === '.' || projectRoot === '')) {
14
+ return `${projectRoot}/src/**/*.${extension}`;
15
+ }
16
+ else {
17
+ return `${projectRoot}/**/*.${extension}`;
18
+ }
17
19
  }
18
- exports.lintProjectGenerator = lintProjectGenerator;
19
- async function lintProjectGeneratorInternal(tree, options) {
20
- const nxJson = (0, devkit_1.readNxJson)(tree);
21
- const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
22
- nxJson.useInferencePlugins !== false;
23
- options.addPlugin ??= addPluginDefault;
24
- const tasks = [];
25
- const initTask = await (0, init_1.lintInitGenerator)(tree, {
26
- skipPackageJson: options.skipPackageJson,
27
- addPlugin: options.addPlugin,
28
- });
29
- tasks.push(initTask);
30
- const rootEsLintTask = (0, setup_root_eslint_1.setupRootEsLint)(tree, {
20
+ exports.mapLintPattern = mapLintPattern;
21
+ async function lintProjectGenerator(tree, options) {
22
+ const installTask = (0, init_1.lintInitGenerator)(tree, {
23
+ linter: options.linter,
31
24
  unitTestRunner: options.unitTestRunner,
32
25
  skipPackageJson: options.skipPackageJson,
33
26
  rootProject: options.rootProject,
34
27
  });
35
- tasks.push(rootEsLintTask);
36
28
  const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
37
- let lintFilePatterns = options.eslintFilePatterns;
38
- if (!lintFilePatterns && options.rootProject && projectConfig.root === '.') {
39
- lintFilePatterns = ['./src'];
40
- }
41
- if (lintFilePatterns &&
42
- lintFilePatterns.length &&
43
- !lintFilePatterns.includes('{projectRoot}') &&
44
- isBuildableLibraryProject(projectConfig)) {
45
- lintFilePatterns.push(`{projectRoot}/package.json`);
46
- }
47
- const hasPlugin = (0, plugin_1.hasEslintPlugin)(tree);
48
- if (hasPlugin && !options.addExplicitTargets) {
49
- if (lintFilePatterns &&
50
- lintFilePatterns.length &&
51
- lintFilePatterns.some((p) => !['./src', '{projectRoot}', projectConfig.root].includes(p))) {
52
- projectConfig.targets['lint'] = {
53
- command: `eslint ${lintFilePatterns
54
- .join(' ')
55
- .replace('{projectRoot}', projectConfig.root)}`,
56
- };
57
- }
58
- }
59
- else {
60
- projectConfig.targets['lint'] = {
61
- executor: '@nx/eslint:lint',
62
- };
63
- if (lintFilePatterns && lintFilePatterns.length) {
64
- // only add lintFilePatterns if they are explicitly defined
65
- projectConfig.targets['lint'].options = {
66
- lintFilePatterns,
67
- };
68
- }
29
+ const lintFilePatterns = options.eslintFilePatterns ?? [];
30
+ if (isBuildableLibraryProject(projectConfig)) {
31
+ lintFilePatterns.push(`${projectConfig.root}/package.json`);
69
32
  }
33
+ projectConfig.targets['lint'] = {
34
+ executor: '@nx/eslint:lint',
35
+ outputs: ['{options.outputFile}'],
36
+ options: {
37
+ lintFilePatterns: lintFilePatterns,
38
+ },
39
+ };
70
40
  // we are adding new project which is not the root project or
71
41
  // companion e2e app so we should check if migration to
72
42
  // monorepo style is needed
@@ -81,14 +51,14 @@ async function lintProjectGeneratorInternal(tree, options) {
81
51
  filteredProjects.push(project);
82
52
  }
83
53
  });
84
- (0, init_migration_1.migrateConfigToMonorepoStyle)(filteredProjects, tree, options.unitTestRunner, options.keepExistingVersions);
54
+ (0, init_migration_1.migrateConfigToMonorepoStyle)(filteredProjects, tree, options.unitTestRunner);
85
55
  }
86
56
  }
87
57
  // our root `.eslintrc` is already the project config, so we should not override it
88
58
  // additionally, the companion e2e app would have `rootProject: true`
89
59
  // so we need to check for the root path as well
90
60
  if (!options.rootProject || projectConfig.root !== '.') {
91
- createEsLintConfiguration(tree, projectConfig, options.setParserOptionsProject, options.rootProject);
61
+ createEsLintConfiguration(tree, projectConfig, options.setParserOptionsProject);
92
62
  }
93
63
  // Buildable libs need source analysis enabled for linting `package.json`.
94
64
  if (isBuildableLibraryProject(projectConfig) &&
@@ -104,14 +74,13 @@ async function lintProjectGeneratorInternal(tree, options) {
104
74
  if (!options.skipFormat) {
105
75
  await (0, devkit_1.formatFiles)(tree);
106
76
  }
107
- return (0, devkit_1.runTasksInSerial)(...tasks);
77
+ return installTask;
108
78
  }
109
- exports.lintProjectGeneratorInternal = lintProjectGeneratorInternal;
110
- function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject, rootProject) {
111
- // we are only extending root for non-standalone projects or their complementary e2e apps
112
- const extendedRootConfig = rootProject ? undefined : (0, eslint_file_1.findEslintFile)(tree);
113
- const pathToRootConfig = extendedRootConfig
114
- ? `${(0, devkit_1.offsetFromRoot)(projectConfig.root)}${extendedRootConfig}`
79
+ exports.lintProjectGenerator = lintProjectGenerator;
80
+ function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject) {
81
+ const eslintConfig = (0, eslint_file_1.findEslintFile)(tree);
82
+ const pathToRootConfig = eslintConfig
83
+ ? `${(0, devkit_1.offsetFromRoot)(projectConfig.root)}${eslintConfig}`
115
84
  : undefined;
116
85
  const addDependencyChecks = isBuildableLibraryProject(projectConfig);
117
86
  const overrides = [
@@ -163,20 +132,20 @@ function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject,
163
132
  const isCompatNeeded = addDependencyChecks;
164
133
  const nodes = [];
165
134
  const importMap = new Map();
166
- if (extendedRootConfig) {
135
+ if (eslintConfig) {
167
136
  importMap.set(pathToRootConfig, 'baseConfig');
168
137
  nodes.push((0, ast_utils_1.generateSpreadElement)('baseConfig'));
169
138
  }
170
139
  overrides.forEach((override) => {
171
- nodes.push((0, ast_utils_1.generateFlatOverride)(override));
140
+ nodes.push((0, ast_utils_1.generateFlatOverride)(override, projectConfig.root));
172
141
  });
173
142
  const nodeList = (0, ast_utils_1.createNodeList)(importMap, nodes, isCompatNeeded);
174
- const content = (0, ast_utils_1.stringifyNodeList)(nodeList);
143
+ const content = (0, ast_utils_1.stringifyNodeList)(nodeList, projectConfig.root, 'eslint.config.js');
175
144
  tree.write((0, path_1.join)(projectConfig.root, 'eslint.config.js'), content);
176
145
  }
177
146
  else {
178
147
  (0, devkit_1.writeJson)(tree, (0, path_1.join)(projectConfig.root, `.eslintrc.json`), {
179
- extends: extendedRootConfig ? [pathToRootConfig] : undefined,
148
+ extends: eslintConfig ? [pathToRootConfig] : undefined,
180
149
  // Include project files to be linted since the global one excludes all files.
181
150
  ignorePatterns: ['!**/*'],
182
151
  overrides,
@@ -200,8 +169,8 @@ function isBuildableLibraryProject(projectConfig) {
200
169
  */
201
170
  function isMigrationToMonorepoNeeded(projects, tree) {
202
171
  // the base config is already created, migration has been done
203
- if (tree.exists(config_file_1.baseEsLintConfigFile) ||
204
- tree.exists(config_file_1.baseEsLintFlatConfigFile)) {
172
+ if (tree.exists(eslint_file_1.baseEsLintConfigFile) ||
173
+ tree.exists(eslint_file_1.baseEsLintFlatConfigFile)) {
205
174
  return false;
206
175
  }
207
176
  const configs = Object.values(projects);
@@ -213,15 +182,10 @@ function isMigrationToMonorepoNeeded(projects, tree) {
213
182
  if (!rootProject || !rootProject.targets) {
214
183
  return false;
215
184
  }
216
- // check if we're inferring lint target from `@nx/eslint/plugin`
217
- if ((0, plugin_1.hasEslintPlugin)(tree)) {
218
- for (const f of config_file_1.ESLINT_CONFIG_FILENAMES) {
219
- if (tree.exists(f)) {
220
- return true;
221
- }
222
- }
223
- }
224
185
  // find if root project has lint target
225
186
  const lintTarget = (0, init_migration_1.findLintTarget)(rootProject);
226
- return !!lintTarget;
187
+ if (!lintTarget) {
188
+ return false;
189
+ }
190
+ return true;
227
191
  }
@@ -1,5 +1,8 @@
1
- import type { Tree } from '@nx/devkit';
2
- import type { Linter } from 'eslint';
1
+ import { Tree } from '@nx/devkit';
2
+ import { Linter } from 'eslint';
3
+ export declare const eslintConfigFileWhitelist: string[];
4
+ export declare const baseEsLintConfigFile = ".eslintrc.base.json";
5
+ export declare const baseEsLintFlatConfigFile = "eslint.base.config.js";
3
6
  export declare function findEslintFile(tree: Tree, projectRoot?: string): string | null;
4
7
  export declare function isEslintConfigSupported(tree: Tree, projectRoot?: string): boolean;
5
8
  export declare function updateRelativePathsInConfig(tree: Tree, sourcePath: string, destinationPath: string): void;