feat(linter): default lintFilePatterns to {projectRoot} (#20313)

This commit is contained in:
Miroslav Jonaš 2023-11-27 14:39:38 +01:00 committed by GitHub
parent 98883bba7a
commit ff5d1bef83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
78 changed files with 343 additions and 597 deletions

View File

@ -20,7 +20,7 @@
"lintFilePatterns": { "lintFilePatterns": {
"type": "array", "type": "array",
"description": "One or more files/dirs/globs to pass directly to ESLint's `lintFiles()` method.", "description": "One or more files/dirs/globs to pass directly to ESLint's `lintFiles()` method.",
"default": [], "default": ["{projectRoot}"],
"items": { "type": "string" } "items": { "type": "string" }
}, },
"format": { "format": {
@ -140,7 +140,6 @@
"default": true "default": true
} }
}, },
"required": ["lintFilePatterns"],
"examplesFile": "Linter can be configured in multiple ways. The basic way is to provide only `lintFilePatterns`, which is a mandatory property. This tells us where to look for files to lint.\n\n`project.json`:\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"]\n }\n}\n```\n\n## Examples\n\n{% tabs %}\n{% tab label=\"Fixing linter issues\" %}\n\nLinter provides an automated way of fixing known issues. To ensure that those changes are properly cached, we need to add an `outputs` property to the `lint` target. Omitting the `outputs` property would produce an invalid cache record. Both of these properties are set by default when scaffolding a new project.\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"]\n }\n}\n```\n\nWith these settings, we can run the command with a `--fix` flag:\n\n```bash\nnx run frontend:lint --fix\n```\n\nWe can also set this flag via project configuration to always fix files when running lint:\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"],\n \"fix\": true\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"Custom output format\" %}\n\nESLint executor uses the `stylish` output format by default. You can change this by specifying the `format` property:\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"],\n \"format\": \"compact\"\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"Silence warnings\" %}\n\nMigrated or legacy projects tend to have an overwhelming amount of lint errors. We might want to change those temporarily to be warnings so they don't block the development. But they would still clutter the report. We can run the command with `--quiet` to hide warning (errors would still break the lint):\n\n```bash\nnx run frontend:lint --quiet\n```\n\nWe can also set this via project configuration as a default option.\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"],\n \"quiet\": true\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"Flat Config file\" %}\n\n`ESLint` provides several ways of specifying the configuration. The default one is using `.eslintrc.json` but you can override it by setting the `eslintConfig` flag. The new `Flat Config` is now also supported:\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"],\n \"eslintConfig\": \"eslint.config.js\"\n }\n}\n```\n\n**Note:** In contrast to other configuration formats, the `Flat Config` requires that all configuration files are converted to `eslint.config.js`. Built-in migrations and generators support only `.eslintrc.json` at the moment.\n\n{% /tab %}\n{% /tabs %}\n\n---\n", "examplesFile": "Linter can be configured in multiple ways. The basic way is to provide only `lintFilePatterns`, which is a mandatory property. This tells us where to look for files to lint.\n\n`project.json`:\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"]\n }\n}\n```\n\n## Examples\n\n{% tabs %}\n{% tab label=\"Fixing linter issues\" %}\n\nLinter provides an automated way of fixing known issues. To ensure that those changes are properly cached, we need to add an `outputs` property to the `lint` target. Omitting the `outputs` property would produce an invalid cache record. Both of these properties are set by default when scaffolding a new project.\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"]\n }\n}\n```\n\nWith these settings, we can run the command with a `--fix` flag:\n\n```bash\nnx run frontend:lint --fix\n```\n\nWe can also set this flag via project configuration to always fix files when running lint:\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"],\n \"fix\": true\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"Custom output format\" %}\n\nESLint executor uses the `stylish` output format by default. You can change this by specifying the `format` property:\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"],\n \"format\": \"compact\"\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"Silence warnings\" %}\n\nMigrated or legacy projects tend to have an overwhelming amount of lint errors. We might want to change those temporarily to be warnings so they don't block the development. But they would still clutter the report. We can run the command with `--quiet` to hide warning (errors would still break the lint):\n\n```bash\nnx run frontend:lint --quiet\n```\n\nWe can also set this via project configuration as a default option.\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"],\n \"quiet\": true\n }\n}\n```\n\n{% /tab %}\n{% tab label=\"Flat Config file\" %}\n\n`ESLint` provides several ways of specifying the configuration. The default one is using `.eslintrc.json` but you can override it by setting the `eslintConfig` flag. The new `Flat Config` is now also supported:\n\n```json\n\"lint\": {\n \"executor\": \"@nx/eslint:lint\",\n \"outputs\": [\"{options.outputFile}\"],\n \"options\": {\n \"lintFilePatterns\": [\"apps/frontend/**/*.ts\"],\n \"eslintConfig\": \"eslint.config.js\"\n }\n}\n```\n\n**Note:** In contrast to other configuration formats, the `Flat Config` requires that all configuration files are converted to `eslint.config.js`. Built-in migrations and generators support only `.eslintrc.json` at the moment.\n\n{% /tab %}\n{% /tabs %}\n\n---\n",
"presets": [] "presets": []
}, },

View File

@ -76,7 +76,6 @@
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"],
"options": { "lintFilePatterns": ["auth/**/*.ts"] },
"configurations": {} "configurations": {}
}, },
"test": { "test": {
@ -155,7 +154,6 @@
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"],
"options": { "lintFilePatterns": ["e2e/**/*.{js,ts}"] },
"configurations": {} "configurations": {}
} }
} }
@ -324,7 +322,7 @@
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"],
"options": { "lintFilePatterns": ["./**/*.ts"] }, "options": { "lintFilePatterns": ["./src"] },
"configurations": {} "configurations": {}
} }
} }

View File

@ -58,7 +58,6 @@
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"],
"options": { "lintFilePatterns": ["auth/**/*.ts"] },
"configurations": {} "configurations": {}
}, },
"test": { "test": {
@ -137,7 +136,6 @@
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"],
"options": { "lintFilePatterns": ["e2e/**/*.{js,ts}"] },
"configurations": {} "configurations": {}
} }
} }

View File

@ -58,7 +58,7 @@
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"],
"options": { "lintFilePatterns": ["auth/**/*.ts"] },
"configurations": {} "configurations": {}
}, },
"test": { "test": {
@ -137,7 +137,6 @@
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"],
"options": { "lintFilePatterns": ["e2e/**/*.{js,ts}"] },
"configurations": {} "configurations": {}
} }
} }
@ -305,7 +304,7 @@
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"],
"options": { "lintFilePatterns": ["./**/*.ts"] }, "options": { "lintFilePatterns": ["./src"] },
"configurations": {} "configurations": {}
} }
} }

View File

@ -120,13 +120,7 @@ const angularV1Json = (appName: string) => `{
} }
}, },
"lint": { "lint": {
"builder": "@nx/eslint:lint", "builder": "@nx/eslint:lint"
"options": {
"lintFilePatterns": [
"${appName}/src/**/*.ts",
"${appName}/src/**/*.html"
]
}
}, },
"test": { "test": {
"builder": "@nx/jest:jest", "builder": "@nx/jest:jest",
@ -159,10 +153,7 @@ const angularV1Json = (appName: string) => `{
}, },
"lint": { "lint": {
"builder": "@nx/eslint:lint", "builder": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["${appName}-e2e/**/*.{js,ts}"]
}
} }
}, },
"tags": [], "tags": [],

View File

@ -407,12 +407,6 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
const projectConfig = readJson(`apps/${project}/project.json`); const projectConfig = readJson(`apps/${project}/project.json`);
expect(projectConfig.targets.lint).toStrictEqual({ expect(projectConfig.targets.lint).toStrictEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
options: {
lintFilePatterns: [
`apps/${project}/src/**/*.ts`,
`apps/${project}/src/**/*.html`,
],
},
}); });
let output = runCLI(`lint ${project}`); let output = runCLI(`lint ${project}`);

View File

@ -465,14 +465,6 @@ describe('Linter', () => {
]; ];
return json; return json;
}); });
updateJson(`libs/${mylib}/project.json`, (json) => {
json.targets.lint.options.lintFilePatterns = [
`libs/${mylib}/**/*.ts`,
`libs/${mylib}/project.json`,
`libs/${mylib}/package.json`,
];
return json;
});
}); });
it('should report dependency check issues', () => { it('should report dependency check issues', () => {

View File

@ -207,10 +207,6 @@ describe('Workspace Tests', () => {
const project = readJson(join(newPath, 'project.json')); const project = readJson(join(newPath, 'project.json'));
expect(project).toBeTruthy(); expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`); expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`shared/${lib1}/data-access/**/*.ts`,
`shared/${lib1}/data-access/package.json`,
]);
/** /**
* Check that the import in lib2 has been updated * Check that the import in lib2 has been updated
@ -343,11 +339,6 @@ describe('Workspace Tests', () => {
const lib3Config = readJson(join(lib3, 'project.json')); const lib3Config = readJson(join(lib3, 'project.json'));
expect(lib3Config.implicitDependencies).toEqual([newName]); expect(lib3Config.implicitDependencies).toEqual([newName]);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`shared/${lib1}/data-access/**/*.ts`,
`shared/${lib1}/data-access/package.json`,
]);
/** /**
* Check that the import in lib2 has been updated * Check that the import in lib2 has been updated
*/ */
@ -479,10 +470,6 @@ describe('Workspace Tests', () => {
const project = readJson(join(newPath, 'project.json')); const project = readJson(join(newPath, 'project.json'));
expect(project).toBeTruthy(); expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`); expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`packages/shared/${lib1}/data-access/**/*.ts`,
`packages/shared/${lib1}/data-access/package.json`,
]);
expect(project.tags).toEqual([]); expect(project.tags).toEqual([]);
/** /**
@ -615,10 +602,6 @@ describe('Workspace Tests', () => {
const project = readJson(join(newPath, 'project.json')); const project = readJson(join(newPath, 'project.json'));
expect(project).toBeTruthy(); expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`); expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`${lib1}/data-access/**/*.ts`,
`${lib1}/data-access/package.json`,
]);
/** /**
* Check that the import in lib2 has been updated * Check that the import in lib2 has been updated
@ -736,10 +719,6 @@ describe('Workspace Tests', () => {
const project = readJson(join(newPath, 'project.json')); const project = readJson(join(newPath, 'project.json'));
expect(project).toBeTruthy(); expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`); expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`shared/${lib1}/data-access/**/*.ts`,
`shared/${lib1}/data-access/package.json`,
]);
/** /**
* Check that the import in lib2 has been updated * Check that the import in lib2 has been updated

View File

@ -72,12 +72,6 @@ describe('addLinting generator', () => {
const project = readProjectConfiguration(tree, appProjectName); const project = readProjectConfiguration(tree, appProjectName);
expect(project.targets.lint).toEqual({ expect(project.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
options: {
lintFilePatterns: [
`${appProjectRoot}/**/*.ts`,
`${appProjectRoot}/**/*.html`,
],
},
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
}); });
}); });

View File

@ -7,7 +7,6 @@ import {
Tree, Tree,
} from '@nx/devkit'; } from '@nx/devkit';
import { Linter, lintProjectGenerator } from '@nx/eslint'; import { Linter, lintProjectGenerator } from '@nx/eslint';
import { mapLintPattern } from '@nx/eslint/src/generators/lint-project/lint-project';
import { addAngularEsLintDependencies } from './lib/add-angular-eslint-dependencies'; import { addAngularEsLintDependencies } from './lib/add-angular-eslint-dependencies';
import type { AddLintingGeneratorSchema } from './schema'; import type { AddLintingGeneratorSchema } from './schema';
import { import {
@ -30,10 +29,6 @@ export async function addLintingGenerator(
joinPathFragments(options.projectRoot, 'tsconfig.app.json'), joinPathFragments(options.projectRoot, 'tsconfig.app.json'),
], ],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [
mapLintPattern(options.projectRoot, 'ts', rootProject),
mapLintPattern(options.projectRoot, 'html', rootProject),
],
setParserOptionsProject: options.setParserOptionsProject, setParserOptionsProject: options.setParserOptionsProject,
skipFormat: true, skipFormat: true,
rootProject: rootProject, rootProject: rootProject,

View File

@ -267,12 +267,6 @@ exports[`app --project-name-and-root-format=derived should generate correctly wh
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"apps/my-dir/my-app/**/*.ts",
"apps/my-dir/my-app/**/*.html",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -339,11 +333,6 @@ exports[`app --project-name-and-root-format=derived should generate correctly wh
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"apps/my-dir/my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -503,12 +492,6 @@ exports[`app --project-name-and-root-format=derived should generate correctly wh
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"apps/my-app/**/*.ts",
"apps/my-app/**/*.html",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -575,11 +558,6 @@ exports[`app --project-name-and-root-format=derived should generate correctly wh
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"apps/my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -963,12 +941,6 @@ exports[`app nested should create project configs 1`] = `
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-dir/my-app/**/*.ts",
"my-dir/my-app/**/*.html",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -1035,11 +1007,6 @@ exports[`app nested should create project configs 2`] = `
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-dir/my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -1112,12 +1079,6 @@ exports[`app not nested should create project configs 1`] = `
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app/**/*.ts",
"my-app/**/*.html",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -1184,11 +1145,6 @@ exports[`app not nested should create project configs 2`] = `
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -506,12 +506,6 @@ describe('app', () => {
.toMatchInlineSnapshot(` .toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app/**/*.ts",
"my-app/**/*.html",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -521,11 +515,6 @@ describe('app', () => {
.toMatchInlineSnapshot(` .toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -1,5 +1,4 @@
export * from './add-files'; export * from './add-files';
export * from './add-path-mapping'; export * from './add-path-mapping';
export * from './normalize-options'; export * from './normalize-options';
export * from './update-linting-file-patterns';
export * from './update-tsconfig-included-files'; export * from './update-tsconfig-included-files';

View File

@ -1,20 +0,0 @@
import { Tree, updateProjectConfiguration } from '@nx/devkit';
import { NormalizedGeneratorOptions } from '../schema';
export function updateLintingFilePatterns(
tree: Tree,
options: NormalizedGeneratorOptions
): void {
const { libraryProject } = options;
if (libraryProject.targets?.lint?.options?.lintFilePatterns) {
libraryProject.targets.lint.options.lintFilePatterns.push(
...[
`${libraryProject.root}/${options.name}/**/*.ts`,
`${libraryProject.root}/${options.name}/**/*.html`,
]
);
updateProjectConfiguration(tree, options.library, libraryProject);
}
}

View File

@ -146,41 +146,6 @@ describe('librarySecondaryEntryPoint generator', () => {
).toStrictEqual(['libs/lib1/testing/src/index.ts']); ).toStrictEqual(['libs/lib1/testing/src/index.ts']);
}); });
it('should add the entry point file patterns to the lint target', async () => {
addProjectConfiguration(tree, 'lib1', {
root: 'libs/lib1',
projectType: 'library',
targets: {
lint: {
executor: '',
options: {
lintFilePatterns: [
'libs/lib1/src/**/*.ts',
'libs/lib1/src/**/*.html',
],
},
},
},
});
tree.write(
'libs/lib1/package.json',
JSON.stringify({ name: '@my-org/lib1' })
);
await librarySecondaryEntryPointGenerator(tree, {
name: 'testing',
library: 'lib1',
});
const project = readProjectConfiguration(tree, 'lib1');
expect(project.targets!.lint.options.lintFilePatterns).toEqual(
expect.arrayContaining([
'libs/lib1/testing/**/*.ts',
'libs/lib1/testing/**/*.html',
])
);
});
it('should update the tsconfig "include" and "exclude" options', async () => { it('should update the tsconfig "include" and "exclude" options', async () => {
await generateTestLibrary(tree, { await generateTestLibrary(tree, {
name: 'lib1', name: 'lib1',

View File

@ -3,7 +3,6 @@ import {
addFiles, addFiles,
addPathMapping, addPathMapping,
normalizeOptions, normalizeOptions,
updateLintingFilePatterns,
updateTsConfigIncludedFiles, updateTsConfigIncludedFiles,
} from './lib'; } from './lib';
import { GeneratorOptions } from './schema'; import { GeneratorOptions } from './schema';
@ -17,7 +16,6 @@ export async function librarySecondaryEntryPointGenerator(
addFiles(tree, options); addFiles(tree, options);
addPathMapping(tree, options); addPathMapping(tree, options);
updateTsConfigIncludedFiles(tree, options); updateTsConfigIncludedFiles(tree, options);
updateLintingFilePatterns(tree, options);
await formatFiles(tree); await formatFiles(tree);
} }

View File

@ -1129,12 +1129,6 @@ describe('lib', () => {
.toMatchInlineSnapshot(` .toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-lib/**/*.ts",
"my-lib/**/*.html",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -322,7 +322,6 @@ export class E2eMigrator extends ProjectMigrator<SupportedTargets> {
await lintProjectGenerator(this.tree, { await lintProjectGenerator(this.tree, {
project: this.project.name, project: this.project.name,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: [`${this.project.newRoot}/**/*.{js,ts}`],
unitTestRunner: this.options.unitTestRunner, unitTestRunner: this.options.unitTestRunner,
tsConfigPaths: [ tsConfigPaths: [
joinPathFragments(this.project.newRoot, 'tsconfig.json'), joinPathFragments(this.project.newRoot, 'tsconfig.json'),

View File

@ -50,11 +50,6 @@ exports[`Cypress Project < v7 nested should update configuration 1`] = `
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-dir/my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -96,11 +91,6 @@ exports[`Cypress Project < v7 project with directory in its name should update c
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-dir/my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -121,11 +111,6 @@ exports[`Cypress Project < v7 should update project configuration (baseUrl) 1`]
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -151,11 +136,6 @@ exports[`Cypress Project < v7 should update project configuration 1`] = `
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -181,11 +161,6 @@ exports[`Cypress Project < v7 should update target configurations 1`] = `
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -268,11 +243,6 @@ exports[`Cypress Project > v10 should set right path names in \`tsconfig.e2e.jso
exports[`Cypress Project > v10 should update configuration when eslint is passed 1`] = ` exports[`Cypress Project > v10 should update configuration when eslint is passed 1`] = `
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -182,11 +182,6 @@ exports[`convertToCypressTen convertCypressProject should infer targets with --a
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],
@ -247,11 +242,6 @@ exports[`convertToCypressTen convertCypressProject should not break when an inva
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"app-e2e/**/*.{js,ts}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -57,9 +57,6 @@ export async function addLinterToCyProject(
linter: options.linter, linter: options.linter,
skipFormat: true, skipFormat: true,
tsConfigPaths: [joinPathFragments(projectConfig.root, 'tsconfig.json')], tsConfigPaths: [joinPathFragments(projectConfig.root, 'tsconfig.json')],
eslintFilePatterns: [
`${projectConfig.root}/**/*.${options.js ? 'js' : '{js,ts}'}`,
],
setParserOptionsProject: options.setParserOptionsProject, setParserOptionsProject: options.setParserOptionsProject,
skipPackageJson: options.skipPackageJson, skipPackageJson: options.skipPackageJson,
rootProject: options.rootProject, rootProject: options.rootProject,

View File

@ -23,7 +23,6 @@ export async function addLinting(host: Tree, options: NormalizedSchema) {
tsConfigPaths: [ tsConfigPaths: [
joinPathFragments(options.e2eProjectRoot, 'tsconfig.app.json'), joinPathFragments(options.e2eProjectRoot, 'tsconfig.app.json'),
], ],
eslintFilePatterns: [`${options.e2eProjectRoot}/**/*.{ts,tsx,js,jsx}`],
skipFormat: true, skipFormat: true,
}); });

View File

@ -32,6 +32,11 @@
"version": "17.1.0-beta.1", "version": "17.1.0-beta.1",
"description": "Updates for @typescript-utils/utils v6.9.1+", "description": "Updates for @typescript-utils/utils v6.9.1+",
"implementation": "./src/migrations/update-17-1-0/update-typescript-eslint" "implementation": "./src/migrations/update-17-1-0/update-typescript-eslint"
},
"simplify-eslint-patterns": {
"version": "17.2.0-beta.0",
"description": "Simplify eslintFilePatterns",
"implementation": "./src/migrations/update-17-2-0/simplify-eslint-patterns"
} }
}, },
"packageJsonUpdates": { "packageJsonUpdates": {

View File

@ -5,6 +5,7 @@ import { dirname, resolve } from 'path';
import type { Schema } from './schema'; import type { Schema } from './schema';
import { resolveAndInstantiateESLint } from './utility/eslint-utils'; import { resolveAndInstantiateESLint } from './utility/eslint-utils';
import { interpolate } from 'nx/src/tasks-runner/utils';
export default async function run( export default async function run(
options: Schema, options: Schema,
@ -84,8 +85,18 @@ export default async function run(
let lintResults: ESLint.LintResult[] = []; let lintResults: ESLint.LintResult[] = [];
const normalizedLintFilePatterns = normalizedOptions.lintFilePatterns.map(
(pattern) => {
return interpolate(pattern, {
workspaceRoot: '',
projectRoot:
context.projectsConfigurations.projects[context.projectName].root,
projectName: context.projectName,
});
}
);
try { try {
lintResults = await eslint.lintFiles(normalizedOptions.lintFilePatterns); lintResults = await eslint.lintFiles(normalizedLintFilePatterns);
} catch (err) { } catch (err) {
if ( if (
err.message.includes( err.message.includes(
@ -117,7 +128,7 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
if (lintResults.length === 0 && errorOnUnmatchedPattern) { if (lintResults.length === 0 && errorOnUnmatchedPattern) {
const ignoredPatterns = ( const ignoredPatterns = (
await Promise.all( await Promise.all(
normalizedOptions.lintFilePatterns.map(async (pattern) => normalizedLintFilePatterns.map(async (pattern) =>
(await eslint.isPathIgnored(pattern)) ? pattern : null (await eslint.isPathIgnored(pattern)) ? pattern : null
) )
) )

View File

@ -17,7 +17,7 @@
"lintFilePatterns": { "lintFilePatterns": {
"type": "array", "type": "array",
"description": "One or more files/dirs/globs to pass directly to ESLint's `lintFiles()` method.", "description": "One or more files/dirs/globs to pass directly to ESLint's `lintFiles()` method.",
"default": [], "default": ["{projectRoot}"],
"items": { "items": {
"type": "string" "type": "string"
} }
@ -144,6 +144,5 @@
"default": true "default": true
} }
}, },
"required": ["lintFilePatterns"],
"examplesFile": "../../../docs/eslint-examples.md" "examplesFile": "../../../docs/eslint-examples.md"
} }

View File

@ -46,7 +46,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -132,7 +131,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -216,7 +214,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -233,12 +230,12 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
tree.write('another-folder/.myeslintignore', 'ignore/me'); tree.write('another-folder/.myeslintignore', 'ignore/me');
updateJson(tree, 'libs/test-lib/project.json', (json) => { updateJson(tree, 'libs/test-lib/project.json', (json) => {
json.targets.lint.options = json.targets.lint.options || {};
json.targets.lint.options.ignorePath = 'another-folder/.myeslintignore'; json.targets.lint.options.ignorePath = 'another-folder/.myeslintignore';
return json; return json;
}); });
@ -262,7 +259,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -281,7 +277,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -301,7 +296,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -320,7 +314,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -342,7 +335,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -364,7 +356,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -381,7 +372,6 @@ describe('convert-to-flat-config generator', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
skipFormat: false, skipFormat: false,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });

View File

@ -55,7 +55,7 @@ export function migrateConfigToMonorepoStyle(
const lintTarget = findLintTarget(project); const lintTarget = findLintTarget(project);
if (lintTarget) { if (lintTarget) {
const eslintFile = const eslintFile =
lintTarget.options.eslintConfig || findEslintFile(tree, project.root); lintTarget.options?.eslintConfig || findEslintFile(tree, project.root);
if (eslintFile) { if (eslintFile) {
const projectEslintPath = joinPathFragments(project.root, eslintFile); const projectEslintPath = joinPathFragments(project.root, eslintFile);
migrateEslintFile(projectEslintPath, tree); migrateEslintFile(projectEslintPath, tree);

View File

@ -44,7 +44,6 @@ describe('@nx/eslint:lint-project', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
...defaultOptions, ...defaultOptions,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['libs/test-lib/**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -72,13 +71,33 @@ describe('@nx/eslint:lint-project', () => {
" "
`); `);
const projectConfig = readProjectConfiguration(tree, 'test-lib');
expect(projectConfig.targets.lint).toMatchInlineSnapshot(`
{
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}",
],
}
`);
});
it('should generate a project config with lintFilePatterns if provided', async () => {
await lintProjectGenerator(tree, {
...defaultOptions,
linter: Linter.EsLint,
project: 'test-lib',
eslintFilePatterns: ['libs/test-lib/src/**/*.ts'],
setParserOptionsProject: false,
});
const projectConfig = readProjectConfiguration(tree, 'test-lib'); const projectConfig = readProjectConfiguration(tree, 'test-lib');
expect(projectConfig.targets.lint).toMatchInlineSnapshot(` expect(projectConfig.targets.lint).toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": { "options": {
"lintFilePatterns": [ "lintFilePatterns": [
"libs/test-lib/**/*.ts", "libs/test-lib/src/**/*.ts",
], ],
}, },
"outputs": [ "outputs": [
@ -92,7 +111,6 @@ describe('@nx/eslint:lint-project', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
...defaultOptions, ...defaultOptions,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['libs/buildable-lib/**/*.ts'],
project: 'buildable-lib', project: 'buildable-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -127,14 +145,34 @@ describe('@nx/eslint:lint-project', () => {
" "
`); `);
const projectConfig = readProjectConfiguration(tree, 'buildable-lib');
expect(projectConfig.targets.lint).toMatchInlineSnapshot(`
{
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}",
],
}
`);
});
it('should generate a project config for buildable lib with lintFilePatterns if provided', async () => {
await lintProjectGenerator(tree, {
...defaultOptions,
linter: Linter.EsLint,
project: 'buildable-lib',
setParserOptionsProject: false,
eslintFilePatterns: ['libs/test-lib/src/**/*.ts'],
});
const projectConfig = readProjectConfiguration(tree, 'buildable-lib'); const projectConfig = readProjectConfiguration(tree, 'buildable-lib');
expect(projectConfig.targets.lint).toMatchInlineSnapshot(` expect(projectConfig.targets.lint).toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": { "options": {
"lintFilePatterns": [ "lintFilePatterns": [
"libs/buildable-lib/**/*.ts", "libs/test-lib/src/**/*.ts",
"libs/buildable-lib/package.json", "{projectRoot}/package.json",
], ],
}, },
"outputs": [ "outputs": [
@ -150,7 +188,6 @@ describe('@nx/eslint:lint-project', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
...defaultOptions, ...defaultOptions,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['libs/test-lib/**/*.ts'],
project: 'test-lib', project: 'test-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -189,7 +226,6 @@ describe('@nx/eslint:lint-project', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
...defaultOptions, ...defaultOptions,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['libs/buildable-lib/**/*.ts'],
project: 'buildable-lib', project: 'buildable-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });
@ -213,7 +249,6 @@ describe('@nx/eslint:lint-project', () => {
await lintProjectGenerator(tree, { await lintProjectGenerator(tree, {
...defaultOptions, ...defaultOptions,
linter: Linter.EsLint, linter: Linter.EsLint,
eslintFilePatterns: ['libs/buildable-lib/**/*.ts'],
project: 'buildable-lib', project: 'buildable-lib',
setParserOptionsProject: false, setParserOptionsProject: false,
}); });

View File

@ -47,18 +47,6 @@ interface LintProjectOptions {
rootProject?: boolean; rootProject?: boolean;
} }
export function mapLintPattern(
projectRoot: string,
extension: string,
rootProject?: boolean
) {
if (rootProject && (projectRoot === '.' || projectRoot === '')) {
return `${projectRoot}/src/**/*.${extension}`;
} else {
return `${projectRoot}/**/*.${extension}`;
}
}
export async function lintProjectGenerator( export async function lintProjectGenerator(
tree: Tree, tree: Tree,
options: LintProjectOptions options: LintProjectOptions
@ -71,19 +59,29 @@ export async function lintProjectGenerator(
}); });
const projectConfig = readProjectConfiguration(tree, options.project); const projectConfig = readProjectConfiguration(tree, options.project);
const lintFilePatterns = options.eslintFilePatterns ?? [];
if (isBuildableLibraryProject(projectConfig)) {
lintFilePatterns.push(`${projectConfig.root}/package.json`);
}
projectConfig.targets['lint'] = { projectConfig.targets['lint'] = {
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: lintFilePatterns,
},
}; };
let lintFilePatterns = options.eslintFilePatterns;
if (!lintFilePatterns && options.rootProject && projectConfig.root === '.') {
lintFilePatterns = ['./src'];
}
if (lintFilePatterns && lintFilePatterns.length) {
if (
isBuildableLibraryProject(projectConfig) &&
!lintFilePatterns.includes('{projectRoot}')
) {
lintFilePatterns.push(`{projectRoot}/package.json`);
}
// only add lintFilePatterns if they are explicitly defined
projectConfig.targets['lint'].options = {
lintFilePatterns,
};
}
// we are adding new project which is not the root project or // we are adding new project which is not the root project or
// companion e2e app so we should check if migration to // companion e2e app so we should check if migration to
// monorepo style is needed // monorepo style is needed

View File

@ -0,0 +1,145 @@
import { Tree, addProjectConfiguration, readJson } from '@nx/devkit';
import update from './simplify-eslint-patterns';
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
describe('simplify-eslint-patterns migration', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
tree.write('.eslintrc.json', '{}');
});
it('should remove pattern if matches default', async () => {
addProjectConfiguration(tree, 'test-lib', {
root: 'libs/test-lib',
projectType: 'library',
targets: {
lint: {
executor: '@nx/eslint:lint',
options: {
lintFilePatterns: ['libs/test-lib/**/*.{ts,html}'],
},
},
},
});
await update(tree);
const projJson = readJson(tree, 'libs/test-lib/project.json');
expect(projJson.targets.lint).toMatchInlineSnapshot(`
{
"executor": "@nx/eslint:lint",
}
`);
});
it('should not remove options if other fields are set', async () => {
addProjectConfiguration(tree, 'test-lib', {
root: 'libs/test-lib',
projectType: 'library',
targets: {
lint: {
executor: '@nx/eslint:lint',
options: {
lintFilePatterns: ['libs/test-lib/**/*.{ts,html}'],
ignorePatterns: ['**/node_modules/**'],
},
},
},
});
await update(tree);
const projJson = readJson(tree, 'libs/test-lib/project.json');
expect(projJson.targets.lint).toMatchInlineSnapshot(`
{
"executor": "@nx/eslint:lint",
"options": {
"ignorePatterns": [
"**/node_modules/**",
],
},
}
`);
});
it('should remove multiple lint patterns if matches default', async () => {
addProjectConfiguration(tree, 'test-lib', {
root: 'libs/test-lib',
projectType: 'library',
targets: {
lint: {
executor: '@nx/eslint:lint',
options: {
lintFilePatterns: [
'libs/test-lib/**/*.ts',
'libs/test-lib/**/*.html',
'libs/test-lib/**/*.tsx',
],
},
},
},
});
await update(tree);
const projJson = readJson(tree, 'libs/test-lib/project.json');
expect(projJson.targets.lint).toMatchInlineSnapshot(`
{
"executor": "@nx/eslint:lint",
}
`);
});
it('should persist external patterns', async () => {
addProjectConfiguration(tree, 'test-lib', {
root: 'libs/test-lib',
projectType: 'library',
targets: {
lint: {
executor: '@nx/eslint:lint',
options: {
lintFilePatterns: [
'libs/test-lib/**/*.ts',
'libs/some-external/**/*.html',
'libs/test-lib/**/*.tsx',
'**/*.js',
],
},
},
},
});
await update(tree);
const projJson = readJson(tree, 'libs/test-lib/project.json');
expect(projJson.targets.lint.options.lintFilePatterns).toEqual([
'libs/test-lib',
'libs/some-external/**/*.html',
'**/*.js',
]);
});
it('should update standalone projects lint patterns', async () => {
addProjectConfiguration(tree, 'test-lib', {
root: '',
sourceRoot: './src',
projectType: 'library',
targets: {
lint: {
executor: '@nx/eslint:lint',
options: {
lintFilePatterns: ['./src/**/*.{ts,html}'],
},
},
},
});
await update(tree);
const projJson = readJson(tree, 'project.json');
expect(projJson.targets.lint.options.lintFilePatterns).toEqual(['./src']);
});
});

View File

@ -0,0 +1,66 @@
import {
ProjectConfiguration,
Tree,
formatFiles,
getProjects,
updateProjectConfiguration,
} from '@nx/devkit';
export default async function update(tree: Tree) {
const projects = getProjects(tree);
for (const [projectName, projectConfiguration] of projects) {
let needsUpdate = false;
for (const [targetName, targetConfig] of Object.entries(
projectConfiguration.targets ?? {}
)) {
if (targetConfig.executor !== '@nx/eslint:lint') {
continue;
}
needsUpdate = true;
if (projectConfiguration.targets[targetName].options?.lintFilePatterns) {
const rootPattern = getLintRoot(projectConfiguration);
const nonRootPatterns = projectConfiguration.targets[
targetName
].options.lintFilePatterns.filter(
(p) => !p.startsWith(rootPattern) && !p.startsWith('{projectRoot}')
);
if (
nonRootPatterns.length === 0 &&
rootPattern === projectConfiguration.root
) {
// delete the lintFilePatterns option if it's the only option and matches the root of the project
delete projectConfiguration.targets[targetName].options
.lintFilePatterns;
if (
Object.keys(projectConfiguration.targets[targetName].options)
.length === 0
) {
delete projectConfiguration.targets[targetName].options;
}
} else {
projectConfiguration.targets[targetName].options.lintFilePatterns = [
rootPattern,
...nonRootPatterns,
];
}
}
}
if (needsUpdate) {
updateProjectConfiguration(tree, projectName, projectConfiguration);
}
}
await formatFiles(tree);
}
function getLintRoot({ root, sourceRoot }: ProjectConfiguration): string {
if (root === '' || root === '.') {
return sourceRoot || './src';
}
return root;
}

View File

@ -42,9 +42,6 @@ describe('lib', () => {
expect(projectConfiguration.targets.lint).toEqual({ expect(projectConfiguration.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-lib/**/*.{ts,tsx,js,jsx}'],
},
}); });
expect(projectConfiguration.tags).toEqual(['one', 'two']); expect(projectConfiguration.tags).toEqual(['one', 'two']);
}); });
@ -151,9 +148,6 @@ describe('lib', () => {
expect(projectConfiguration.targets.lint).toEqual({ expect(projectConfiguration.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-dir/my-lib/**/*.{ts,tsx,js,jsx}'],
},
}); });
}); });
@ -200,9 +194,6 @@ describe('lib', () => {
expect(projectConfiguration.targets.test).toBeUndefined(); expect(projectConfiguration.targets.test).toBeUndefined();
expect(projectConfiguration.targets.lint).toMatchObject({ expect(projectConfiguration.targets.lint).toMatchObject({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
options: {
lintFilePatterns: ['my-lib/**/*.{ts,tsx,js,jsx}'],
},
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
}); });
}); });

View File

@ -31,7 +31,6 @@ export async function addLinting(host: Tree, options: NormalizedSchema) {
linter: options.linter, linter: options.linter,
project: options.projectName, project: options.projectName,
tsConfigPaths: options.tsConfigPaths, tsConfigPaths: options.tsConfigPaths,
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`],
skipFormat: true, skipFormat: true,
skipPackageJson: options.skipPackageJson, skipPackageJson: options.skipPackageJson,
}); });

View File

@ -496,9 +496,6 @@ describe('lib', () => {
expect(readProjectConfiguration(tree, 'my-lib').targets.lint).toEqual({ expect(readProjectConfiguration(tree, 'my-lib').targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-lib/**/*.ts', 'my-lib/package.json'],
},
}); });
}); });
@ -569,12 +566,6 @@ describe('lib', () => {
expect(readProjectConfiguration(tree, 'my-lib').targets.lint).toEqual({ expect(readProjectConfiguration(tree, 'my-lib').targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: [
'my-dir/my-lib/**/*.ts',
'my-dir/my-lib/package.json',
],
},
}); });
}); });
@ -711,10 +702,6 @@ describe('lib', () => {
js: true, js: true,
projectNameAndRootFormat: 'as-provided', projectNameAndRootFormat: 'as-provided',
}); });
expect(
readProjectConfiguration(tree, 'my-lib').targets.lint.options
.lintFilePatterns
).toEqual(['my-dir/my-lib/**/*.js', 'my-dir/my-lib/package.json']);
expect(readJson(tree, 'my-dir/my-lib/.eslintrc.json')) expect(readJson(tree, 'my-dir/my-lib/.eslintrc.json'))
.toMatchInlineSnapshot(` .toMatchInlineSnapshot(`
{ {

View File

@ -270,9 +270,6 @@ export async function addLint(
options: AddLintOptions options: AddLintOptions
): Promise<GeneratorCallback> { ): Promise<GeneratorCallback> {
const { lintProjectGenerator } = ensurePackage('@nx/eslint', nxVersion); const { lintProjectGenerator } = ensurePackage('@nx/eslint', nxVersion);
const { mapLintPattern } =
// nx-ignore-next-line
require('@nx/eslint/src/generators/lint-project/lint-project');
const projectConfiguration = readProjectConfiguration(tree, options.name); const projectConfiguration = readProjectConfiguration(tree, options.name);
const task = lintProjectGenerator(tree, { const task = lintProjectGenerator(tree, {
project: options.name, project: options.name,
@ -282,13 +279,6 @@ export async function addLint(
joinPathFragments(options.projectRoot, 'tsconfig.lib.json'), joinPathFragments(options.projectRoot, 'tsconfig.lib.json'),
], ],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [
mapLintPattern(
options.projectRoot,
options.js ? 'js' : 'ts',
options.rootProject
),
],
setParserOptionsProject: options.setParserOptionsProject, setParserOptionsProject: options.setParserOptionsProject,
rootProject: options.rootProject, rootProject: options.rootProject,
}); });

View File

@ -54,11 +54,6 @@ exports[`lib --unit-test-runner none should not generate test configuration 1`]
exports[`lib --unit-test-runner none should not generate test configuration 2`] = ` exports[`lib --unit-test-runner none should not generate test configuration 2`] = `
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-lib/**/*.ts",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -25,9 +25,6 @@ describe('lib', () => {
expect(config.targets.lint).toEqual({ expect(config.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: [`my-lib/**/*.ts`],
},
}); });
expect(config.targets.test).toEqual({ expect(config.targets.test).toEqual({
executor: '@nx/jest:jest', executor: '@nx/jest:jest',
@ -214,9 +211,6 @@ describe('lib', () => {
expect(project.targets.lint).toEqual({ expect(project.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: [`my-dir/my-lib/**/*.ts`],
},
}); });
}); });

View File

@ -15,7 +15,6 @@ import {
isEslintConfigSupported, isEslintConfigSupported,
updateOverrideInLintConfig, updateOverrideInLintConfig,
} from '@nx/eslint/src/generators/utils/eslint-file'; } from '@nx/eslint/src/generators/utils/eslint-file';
import { mapLintPattern } from '@nx/eslint/src/generators/lint-project/lint-project';
export async function addLinting( export async function addLinting(
host: Tree, host: Tree,
@ -28,13 +27,6 @@ export async function addLinting(
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
], ],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [
mapLintPattern(
options.appProjectRoot,
'{ts,tsx,js,jsx}',
options.rootProject
),
],
skipFormat: true, skipFormat: true,
rootProject: options.rootProject, rootProject: options.rootProject,
}); });

View File

@ -71,9 +71,6 @@ describe('app', () => {
expect(project.targets.lint).toEqual({ expect(project.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-node-app/**/*.ts'],
},
}); });
expect(() => expect(() =>
readProjectConfiguration(tree, 'my-node-app-e2e') readProjectConfiguration(tree, 'my-node-app-e2e')
@ -195,9 +192,6 @@ describe('app', () => {
expect(project.targets.lint).toEqual({ expect(project.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-dir/my-node-app/**/*.ts'],
},
}); });
expect(() => expect(() =>
@ -284,11 +278,6 @@ describe('app', () => {
expect(project.targets.lint).toMatchInlineSnapshot(` expect(project.targets.lint).toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-node-app/**/*.ts",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -24,7 +24,6 @@ import { configurationGenerator } from '@nx/jest';
import { getRelativePathToRootTsConfig, tsConfigBaseOptions } from '@nx/js'; import { getRelativePathToRootTsConfig, tsConfigBaseOptions } from '@nx/js';
import { esbuildVersion } from '@nx/js/src/utils/versions'; import { esbuildVersion } from '@nx/js/src/utils/versions';
import { Linter, lintProjectGenerator } from '@nx/eslint'; import { Linter, lintProjectGenerator } from '@nx/eslint';
import { mapLintPattern } from '@nx/eslint/src/generators/lint-project/lint-project';
import { join } from 'path'; import { join } from 'path';
import { import {
expressTypingsVersion, expressTypingsVersion,
@ -268,13 +267,6 @@ export async function addLintingToApplication(
tsConfigPaths: [ tsConfigPaths: [
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
], ],
eslintFilePatterns: [
mapLintPattern(
options.appProjectRoot,
options.js ? 'js' : 'ts',
options.rootProject
),
],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
skipFormat: true, skipFormat: true,
setParserOptionsProject: options.setParserOptionsProject, setParserOptionsProject: options.setParserOptionsProject,

View File

@ -115,7 +115,6 @@ export async function e2eProjectGeneratorInternal(
tsConfigPaths: [ tsConfigPaths: [
joinPathFragments(options.e2eProjectRoot, 'tsconfig.json'), joinPathFragments(options.e2eProjectRoot, 'tsconfig.json'),
], ],
eslintFilePatterns: [`${options.e2eProjectRoot}/**/*.{js,ts}`],
setParserOptionsProject: false, setParserOptionsProject: false,
skipPackageJson: false, skipPackageJson: false,
rootProject: options.rootProject, rootProject: options.rootProject,

View File

@ -31,9 +31,6 @@ describe('lib', () => {
expect(configuration.targets.lint).toEqual({ expect(configuration.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-lib/**/*.ts'],
},
}); });
expect(configuration.targets.test).toEqual({ expect(configuration.targets.test).toEqual({
executor: '@nx/jest:jest', executor: '@nx/jest:jest',
@ -224,9 +221,6 @@ describe('lib', () => {
expect(project.targets.lint).toEqual({ expect(project.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-dir/my-lib/**/*.ts'],
},
}); });
}); });

View File

@ -84,10 +84,7 @@ exports[`app generated files content - as-provided general application should co
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["my-app/**/*.{ts,tsx,js,jsx,vue}"]
}
}, },
"test": { "test": {
"executor": "@nx/vite:test", "executor": "@nx/vite:test",

View File

@ -27,7 +27,6 @@ export async function addLinting(
project: options.projectName, project: options.projectName,
tsConfigPaths: [joinPathFragments(options.projectRoot, 'tsconfig.json')], tsConfigPaths: [joinPathFragments(options.projectRoot, 'tsconfig.json')],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx,vue}`],
skipFormat: true, skipFormat: true,
rootProject: options.rootProject, rootProject: options.rootProject,
}); });

View File

@ -240,7 +240,7 @@ function createProjectJson(
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: { options: {
lintFilePatterns: ['src/**/*.ts', 'test/**/*.ts'], lintFilePatterns: ['./src', './test'],
}, },
}; };

View File

@ -49,9 +49,6 @@ export async function addLinterToPlaywrightProject(
linter: options.linter, linter: options.linter,
skipFormat: true, skipFormat: true,
tsConfigPaths: [joinPathFragments(projectConfig.root, 'tsconfig.json')], tsConfigPaths: [joinPathFragments(projectConfig.root, 'tsconfig.json')],
eslintFilePatterns: [
`${projectConfig.root}/**/*.${options.js ? 'js' : '{js,ts}'}`,
],
setParserOptionsProject: options.setParserOptionsProject, setParserOptionsProject: options.setParserOptionsProject,
skipPackageJson: options.skipPackageJson, skipPackageJson: options.skipPackageJson,
rootProject: options.rootProject, rootProject: options.rootProject,

View File

@ -164,9 +164,6 @@ describe('NxPlugin e2e-project Generator', () => {
expect(projectsConfigurations.get('my-plugin-e2e').targets.lint).toEqual({ expect(projectsConfigurations.get('my-plugin-e2e').targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['apps/my-plugin-e2e/**/*.ts'],
},
}); });
}); });
}); });

View File

@ -168,7 +168,6 @@ async function addLintingToApplication(
tsConfigPaths: [ tsConfigPaths: [
joinPathFragments(options.projectRoot, 'tsconfig.app.json'), joinPathFragments(options.projectRoot, 'tsconfig.app.json'),
], ],
eslintFilePatterns: [`${options.projectRoot}/**/*.ts`],
unitTestRunner: 'jest', unitTestRunner: 'jest',
skipFormat: true, skipFormat: true,
setParserOptionsProject: false, setParserOptionsProject: false,

View File

@ -10,7 +10,6 @@ import {
import type { Linter as ESLint } from 'eslint'; import type { Linter as ESLint } from 'eslint';
import { Linter } from '@nx/eslint'; import { Linter } from '@nx/eslint';
import { Schema as EsLintExecutorOptions } from '@nx/eslint/src/executors/lint/schema';
import generator from './generator'; import generator from './generator';
import pluginGenerator from '../plugin/plugin'; import pluginGenerator from '../plugin/plugin';
@ -53,21 +52,11 @@ describe('lint-checks generator', () => {
await generator(tree, { projectName: 'plugin' }); await generator(tree, { projectName: 'plugin' });
const projectConfig = readProjectConfiguration(tree, 'plugin'); const projectConfig = readProjectConfiguration(tree, 'plugin');
const targetConfig = projectConfig.targets?.['lint'];
const eslintConfig: ESLint.Config = readJson( const eslintConfig: ESLint.Config = readJson(
tree, tree,
`${projectConfig.root}/.eslintrc.json` `${projectConfig.root}/.eslintrc.json`
); );
expect(targetConfig.options.lintFilePatterns).toContain(
`${projectConfig.root}/generators.json`
);
expect(targetConfig.options.lintFilePatterns).toContain(
`${projectConfig.root}/executors.json`
);
expect(targetConfig.options.lintFilePatterns).toContain(
`${projectConfig.root}/package.json`
);
expect(eslintConfig.overrides).toContainEqual( expect(eslintConfig.overrides).toContainEqual(
expect.objectContaining({ expect.objectContaining({
files: expect.arrayContaining([ files: expect.arrayContaining([
@ -86,19 +75,11 @@ describe('lint-checks generator', () => {
await generator(tree, { projectName: 'plugin' }); await generator(tree, { projectName: 'plugin' });
await generator(tree, { projectName: 'plugin' }); await generator(tree, { projectName: 'plugin' });
const projectConfig = readProjectConfiguration(tree, 'plugin'); const projectConfig = readProjectConfiguration(tree, 'plugin');
const targetConfig = projectConfig.targets?.['lint']
.options as EsLintExecutorOptions;
const eslintConfig: ESLint.Config = readJson( const eslintConfig: ESLint.Config = readJson(
tree, tree,
`${projectConfig.root}/.eslintrc.json` `${projectConfig.root}/.eslintrc.json`
); );
const uniqueLintFilePatterns = new Set(targetConfig.lintFilePatterns);
expect(targetConfig.lintFilePatterns).toHaveLength(
uniqueLintFilePatterns.size
);
expect( expect(
eslintConfig.overrides.filter((x) => '@nx/nx-plugin-checks' in x.rules) eslintConfig.overrides.filter((x) => '@nx/nx-plugin-checks' in x.rules)
).toHaveLength(1); ).toHaveLength(1);
@ -125,27 +106,11 @@ describe('lint-checks generator', () => {
); );
await generator(tree, { projectName: 'plugin' }); await generator(tree, { projectName: 'plugin' });
const projectConfig = readProjectConfiguration(tree, 'plugin'); const projectConfig = readProjectConfiguration(tree, 'plugin');
const targetConfig = projectConfig.targets?.['lint'];
const eslintConfig: ESLint.Config = readJson( const eslintConfig: ESLint.Config = readJson(
tree, tree,
`${projectConfig.root}/.eslintrc.json` `${projectConfig.root}/.eslintrc.json`
); );
expect(targetConfig.options.lintFilePatterns).not.toContain(
`${projectConfig.root}/generators.json`
);
expect(targetConfig.options.lintFilePatterns).toContain(
`${projectConfig.root}/collection.json`
);
expect(targetConfig.options.lintFilePatterns).not.toContain(
`${projectConfig.root}/executors.json`
);
expect(targetConfig.options.lintFilePatterns).toContain(
`${projectConfig.root}/builders.json`
);
expect(targetConfig.options.lintFilePatterns).toContain(
`${projectConfig.root}/migrations.json`
);
expect(eslintConfig.overrides).toContainEqual( expect(eslintConfig.overrides).toContainEqual(
expect.objectContaining({ expect.objectContaining({
files: expect.arrayContaining([ files: expect.arrayContaining([

View File

@ -94,15 +94,20 @@ export function addMigrationJsonChecks(
relativeMigrationsJsonPath relativeMigrationsJsonPath
); );
if (!eslintTarget) {
return;
}
// Add path to lintFilePatterns if different than default "{projectRoot}"
if ( if (
eslintTarget && eslintTargetConfiguration.options?.lintFilePatterns &&
!eslintTargetConfiguration.options?.lintFilePatterns?.includes( !eslintTargetConfiguration.options.lintFilePatterns.includes(
migrationsJsonPath migrationsJsonPath
) )
) { ) {
// Add to lintFilePatterns
eslintTargetConfiguration.options.lintFilePatterns.push(migrationsJsonPath); eslintTargetConfiguration.options.lintFilePatterns.push(migrationsJsonPath);
updateProjectConfiguration(host, options.projectName, projectConfiguration); updateProjectConfiguration(host, options.projectName, projectConfiguration);
}
// Update project level eslintrc // Update project level eslintrc
updateOverrideInLintConfig( updateOverrideInLintConfig(
@ -121,7 +126,6 @@ export function addMigrationJsonChecks(
} }
); );
} }
}
function updateProjectTarget( function updateProjectTarget(
host: Tree, host: Tree,
@ -135,9 +139,9 @@ function updateProjectTarget(
for (const [target, configuration] of Object.entries(project.targets)) { for (const [target, configuration] of Object.entries(project.targets)) {
if ( if (
configuration.executor === '@nx/eslint:lint' || configuration.executor === '@nx/eslint:lint' &&
configuration.executor === '@nx/linter:eslint' || // only add patterns if there are already hardcoded ones
configuration.executor === '@nrwl/linter:eslint' configuration.options?.lintFilePatterns
) { ) {
const opts: EsLintExecutorOptions = configuration.options ?? {}; const opts: EsLintExecutorOptions = configuration.options ?? {};
opts.lintFilePatterns ??= []; opts.lintFilePatterns ??= [];

View File

@ -71,12 +71,6 @@ describe('NxPlugin Plugin Generator', () => {
expect(project.targets.lint).toEqual({ expect(project.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: expect.arrayContaining([
'libs/my-plugin/**/*.ts',
'libs/my-plugin/package.json',
]),
},
}); });
expect(project.targets.test).toEqual({ expect(project.targets.test).toEqual({
executor: '@nx/jest:jest', executor: '@nx/jest:jest',

View File

@ -420,7 +420,6 @@ export async function createTestUILib(libName: string): Promise<Tree> {
const currentWorkspaceJson = getProjects(appTree); const currentWorkspaceJson = getProjects(appTree);
const projectConfig = currentWorkspaceJson.get(libName); const projectConfig = currentWorkspaceJson.get(libName);
projectConfig.targets.lint.options.linter = 'eslint';
updateProjectConfiguration(appTree, libName, projectConfig); updateProjectConfiguration(appTree, libName, projectConfig);

View File

@ -36,9 +36,6 @@ describe('lib', () => {
expect(projectConfiguration.targets.lint).toEqual({ expect(projectConfiguration.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-lib/**/*.{ts,tsx,js,jsx}'],
},
}); });
expect(projectConfiguration.tags).toEqual(['one', 'two']); expect(projectConfiguration.tags).toEqual(['one', 'two']);
}); });
@ -160,9 +157,6 @@ describe('lib', () => {
expect(projectConfiguration.targets.lint).toEqual({ expect(projectConfiguration.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-dir/**/*.{ts,tsx,js,jsx}'],
},
}); });
}); });
@ -241,9 +235,6 @@ describe('lib', () => {
expect(projectConfiguration.targets.test).toBeUndefined(); expect(projectConfiguration.targets.test).toBeUndefined();
expect(projectConfiguration.targets.lint).toMatchObject({ expect(projectConfiguration.targets.lint).toMatchObject({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
options: {
lintFilePatterns: ['my-lib/**/*.{ts,tsx,js,jsx}'],
},
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
}); });
}); });

View File

@ -31,7 +31,6 @@ export async function addLinting(host: Tree, options: NormalizedSchema) {
linter: options.linter, linter: options.linter,
project: options.projectName, project: options.projectName,
tsConfigPaths: options.tsConfigPaths, tsConfigPaths: options.tsConfigPaths,
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`],
skipFormat: true, skipFormat: true,
skipPackageJson: options.skipPackageJson, skipPackageJson: options.skipPackageJson,
}); });

View File

@ -472,9 +472,6 @@ describe('app', () => {
expect(projectsConfigurations.get('my-app').targets.lint).toEqual({ expect(projectsConfigurations.get('my-app').targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-app/**/*.{ts,tsx,js,jsx}'],
},
}); });
}); });
@ -495,11 +492,6 @@ describe('app', () => {
.toMatchInlineSnapshot(` .toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app/**/*.{ts,tsx,js,jsx}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -22,7 +22,6 @@ import {
import reactInitGenerator from '../init/init'; import reactInitGenerator from '../init/init';
import { Linter, lintProjectGenerator } from '@nx/eslint'; import { Linter, lintProjectGenerator } from '@nx/eslint';
import { mapLintPattern } from '@nx/eslint/src/generators/lint-project/lint-project';
import { import {
babelLoaderVersion, babelLoaderVersion,
nxRspackVersion, nxRspackVersion,
@ -49,13 +48,6 @@ async function addLinting(host: Tree, options: NormalizedSchema) {
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
], ],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [
mapLintPattern(
options.appProjectRoot,
'{ts,tsx,js,jsx}',
options.rootProject
),
],
skipFormat: true, skipFormat: true,
rootProject: options.rootProject, rootProject: options.rootProject,
skipPackageJson: options.skipPackageJson, skipPackageJson: options.skipPackageJson,

View File

@ -539,7 +539,6 @@ export async function createTestUILib(libName: string): Promise<Tree> {
const currentWorkspaceJson = getProjects(appTree); const currentWorkspaceJson = getProjects(appTree);
const projectConfig = currentWorkspaceJson.get(libName); const projectConfig = currentWorkspaceJson.get(libName);
projectConfig.targets.lint.options.linter = 'eslint';
updateProjectConfiguration(appTree, libName, projectConfig); updateProjectConfiguration(appTree, libName, projectConfig);

View File

@ -19,7 +19,6 @@ export async function addLinting(host: Tree, options: NormalizedSchema) {
joinPathFragments(options.projectRoot, 'tsconfig.lib.json'), joinPathFragments(options.projectRoot, 'tsconfig.lib.json'),
], ],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`],
skipFormat: true, skipFormat: true,
skipPackageJson: options.skipPackageJson, skipPackageJson: options.skipPackageJson,
setParserOptionsProject: options.setParserOptionsProject, setParserOptionsProject: options.setParserOptionsProject,

View File

@ -55,9 +55,6 @@ describe('lib', () => {
expect(project.targets.lint).toEqual({ expect(project.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-lib/**/*.{ts,tsx,js,jsx}'],
},
}); });
}); });
@ -319,9 +316,6 @@ describe('lib', () => {
expect(config.targets.lint).toEqual({ expect(config.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-dir/my-lib/**/*.{ts,tsx,js,jsx}'],
},
}); });
}); });
@ -416,11 +410,6 @@ describe('lib', () => {
expect(config.targets.lint).toMatchInlineSnapshot(` expect(config.targets.lint).toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-lib/**/*.{ts,tsx,js,jsx}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -48,11 +48,6 @@ exports[`@nx/storybook:configuration for Storybook v7 basic functionalities shou
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"test-ui-lib/**/*.ts",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -160,13 +160,7 @@
"defaultConfiguration": "production" "defaultConfiguration": "production"
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint"
"options": {
"lintFilePatterns": [
"libs/nglibuild/**/*.ts",
"libs/nglibuild/**/*.html"
]
}
} }
}, },
"react-swc": { "react-swc": {

View File

@ -85,11 +85,7 @@
"lint": { "lint": {
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["apps/main-webpack/**/*.{ts,tsx,js,jsx}"]
},
"configurations": {}
}, },
"test": { "test": {
"inputs": [ "inputs": [

View File

@ -115,12 +115,7 @@ exports[`@nx/vite:configuration library mode should set up non buildable library
"targets": { "targets": {
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": [
"libs/react-lib-nonb-jest/**/*.{ts,tsx,js,jsx}"
]
}
}, },
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",
@ -196,12 +191,7 @@ exports[`@nx/vite:configuration library mode should set up non buildable library
"targets": { "targets": {
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": [
"libs/react-lib-nonb-vitest/**/*.{ts,tsx,js,jsx}"
]
}
}, },
"test": { "test": {
"executor": "@nx/vite:test", "executor": "@nx/vite:test",
@ -256,12 +246,7 @@ exports[`@nx/vite:configuration transform React app to use Vite by providing cus
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": [
"apps/my-test-mixed-react-app/**/*.{ts,tsx,js,jsx}"
]
}
}, },
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",
@ -399,10 +384,7 @@ exports[`@nx/vite:configuration transform React app to use Vite should transform
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["apps/my-test-react-app/**/*.{ts,tsx,js,jsx}"]
}
}, },
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",
@ -528,10 +510,7 @@ exports[`@nx/vite:configuration transform Web app to use Vite should transform w
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["apps/my-test-web-app/**/*.ts"]
}
}, },
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",

View File

@ -7,10 +7,7 @@
"targets": { "targets": {
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["libs/react-lib-nonb-jest/**/*.{ts,tsx,js,jsx}"]
}
}, },
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",

View File

@ -7,10 +7,7 @@
"targets": { "targets": {
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["libs/react-lib-nonb-vitest/**/*.{ts,tsx,js,jsx}"]
}
}, },
"test": { "test": {
"executor": "@nx/vite:test", "executor": "@nx/vite:test",

View File

@ -32,12 +32,7 @@
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": [
"apps/my-test-mixed-react-app/**/*.{ts,tsx,js,jsx}"
]
}
}, },
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",

View File

@ -67,10 +67,7 @@
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["apps/my-test-react-app/**/*.{ts,tsx,js,jsx}"]
}
}, },
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",

View File

@ -47,10 +47,7 @@
}, },
"lint": { "lint": {
"executor": "@nrwl/linter:eslint", "executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["apps/my-test-react-vite-app/**/*.{ts,tsx,js,jsx}"]
}
} }
}, },
"tags": [] "tags": []

View File

@ -55,10 +55,7 @@
}, },
"lint": { "lint": {
"executor": "@random/something:test", "executor": "@random/something:test",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["apps/my-test-random-app/**/*.ts"]
}
}, },
"test": { "test": {
"executor": "@random/something:test", "executor": "@random/something:test",

View File

@ -55,10 +55,7 @@
}, },
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["apps/my-test-web-app/**/*.ts"]
}
}, },
"test": { "test": {
"executor": "@nx/jest:jest", "executor": "@nx/jest:jest",

View File

@ -86,10 +86,7 @@ exports[`application generator should set up project correctly with given option
"targets": { "targets": {
"lint": { "lint": {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"], "outputs": ["{options.outputFile}"]
"options": {
"lintFilePatterns": ["test/**/*.{ts,tsx,js,jsx,vue}"]
}
}, },
"build": { "build": {
"executor": "@nx/vite:build", "executor": "@nx/vite:build",

View File

@ -44,9 +44,6 @@ describe('lib', () => {
expect(project.targets.lint).toEqual({ expect(project.targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-lib/**/*.{ts,tsx,js,jsx,vue}'],
},
}); });
}); });
@ -205,13 +202,6 @@ describe('lib', () => {
const config = readProjectConfiguration(tree, 'my-dir-my-lib'); const config = readProjectConfiguration(tree, 'my-dir-my-lib');
expect(config.root).toEqual('my-dir/my-lib'); expect(config.root).toEqual('my-dir/my-lib');
expect(config.targets.lint).toEqual({
executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-dir/my-lib/**/*.{ts,tsx,js,jsx,vue}'],
},
});
}); });
it('should update root tsconfig.base.json', async () => { it('should update root tsconfig.base.json', async () => {
@ -254,11 +244,6 @@ describe('lib', () => {
expect(config.targets.lint).toMatchInlineSnapshot(` expect(config.targets.lint).toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-lib/**/*.{ts,tsx,js,jsx,vue}",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -123,7 +123,6 @@ export async function createTestUILib(libName: string): Promise<Tree> {
const currentWorkspaceJson = getProjects(appTree); const currentWorkspaceJson = getProjects(appTree);
const projectConfig = currentWorkspaceJson.get(libName); const projectConfig = currentWorkspaceJson.get(libName);
projectConfig.targets.lint.options.linter = 'eslint';
updateProjectConfiguration(appTree, libName, projectConfig); updateProjectConfiguration(appTree, libName, projectConfig);

View File

@ -11,7 +11,6 @@ import {
addExtendsToLintConfig, addExtendsToLintConfig,
isEslintConfigSupported, isEslintConfigSupported,
} from '@nx/eslint/src/generators/utils/eslint-file'; } from '@nx/eslint/src/generators/utils/eslint-file';
import { mapLintPattern } from '@nx/eslint/src/generators/lint-project/lint-project';
export async function addLinting( export async function addLinting(
host: Tree, host: Tree,
@ -34,13 +33,6 @@ export async function addLinting(
joinPathFragments(options.projectRoot, `tsconfig.${projectType}.json`), joinPathFragments(options.projectRoot, `tsconfig.${projectType}.json`),
], ],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [
mapLintPattern(
options.projectRoot,
'{ts,tsx,js,jsx,vue}',
options.rootProject
),
],
skipFormat: true, skipFormat: true,
setParserOptionsProject: options.setParserOptionsProject, setParserOptionsProject: options.setParserOptionsProject,
rootProject: options.rootProject, rootProject: options.rootProject,

View File

@ -442,9 +442,6 @@ describe('app', () => {
expect(readProjectConfiguration(tree, 'my-app').targets.lint).toEqual({ expect(readProjectConfiguration(tree, 'my-app').targets.lint).toEqual({
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-app/**/*.ts'],
},
}); });
}); });
@ -479,11 +476,6 @@ describe('app', () => {
expect(projectConfiguration.targets.lint).toMatchInlineSnapshot(` expect(projectConfiguration.targets.lint).toMatchInlineSnapshot(`
{ {
"executor": "@nx/eslint:lint", "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": [
"my-app/**/*.ts",
],
},
"outputs": [ "outputs": [
"{options.outputFile}", "{options.outputFile}",
], ],

View File

@ -274,7 +274,6 @@ export async function applicationGeneratorInternal(host: Tree, schema: Schema) {
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
], ],
unitTestRunner: options.unitTestRunner, unitTestRunner: options.unitTestRunner,
eslintFilePatterns: [`${options.appProjectRoot}/**/*.ts`],
skipFormat: true, skipFormat: true,
setParserOptionsProject: options.setParserOptionsProject, setParserOptionsProject: options.setParserOptionsProject,
}); });

View File

@ -100,13 +100,6 @@ describe('moveProjectConfiguration', () => {
}, },
lint: { lint: {
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
options: {
lintFilePatterns: [
'{projectRoot}/**/*.{ts,tsx,js,jsx}',
'{projectRoot}/**/*.{html,htm}',
'{projectRoot}/project.json',
],
},
}, },
test: { test: {
executor: '@nx/jest:jest', executor: '@nx/jest:jest',
@ -141,13 +134,6 @@ describe('moveProjectConfiguration', () => {
}, },
lint: { lint: {
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
options: {
lintFilePatterns: [
'{projectRoot}/**/*.{ts,tsx,js,jsx}',
'{projectRoot}/**/*.{html,htm}',
'{projectRoot}/project.json',
],
},
}, },
}, },
}); });

View File

@ -139,9 +139,6 @@ describe('move', () => {
lint: { lint: {
executor: '@nx/eslint:lint', executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'], outputs: ['{options.outputFile}'],
options: {
lintFilePatterns: ['my-lib/src/**/*.ts', 'my-lib/package.json'],
},
}, },
test: { test: {
executor: '@nx/jest:jest', executor: '@nx/jest:jest',