From db4544844cc451a0be40ed2fe7042a8795da0c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leosvel=20P=C3=A9rez=20Espinosa?= Date: Tue, 11 Feb 2025 17:06:44 +0100 Subject: [PATCH] fix(angular): do not generate `@nx/dependency-checks` block in flat root eslint config (#29980) ## Current Behavior Generating a buildable Angular library results in a block for the `@nx/dependency-checks` being added to the root ESLint Flat Config file every time. ## Expected Behavior Generating a buildable Angular library should not add a block for the `@nx/dependency-checks` to the root ESLint Flat Config file. The configuration is meant to be added to the project configuration, which it already does. ## Related Issue(s) Fixes #29970 --- .../add-linting/add-linting.spec.ts | 277 ++++++++++++++++++ .../src/generators/add-linting/add-linting.ts | 16 - 2 files changed, 277 insertions(+), 16 deletions(-) diff --git a/packages/angular/src/generators/add-linting/add-linting.spec.ts b/packages/angular/src/generators/add-linting/add-linting.spec.ts index b8d0e8410f..26a6132adc 100644 --- a/packages/angular/src/generators/add-linting/add-linting.spec.ts +++ b/packages/angular/src/generators/add-linting/add-linting.spec.ts @@ -104,4 +104,281 @@ describe('addLinting generator', () => { const packageJson = readJson(tree, 'package.json'); expect(packageJson).toEqual(initialPackageJson); }); + + it('should correctly generate the eslint.config.mjs file for a buildable library', async () => { + process.env.ESLINT_USE_FLAT_CONFIG = 'true'; + + addProjectConfiguration(tree, 'lib1', { + root: 'libs/lib1', + projectType: 'library', + targets: { build: {} }, + }); + + await addLintingGenerator(tree, { + prefix: 'myOrg', + projectName: 'lib1', + projectRoot: 'libs/lib1', + skipFormat: true, + }); + + expect(tree.read('libs/lib1/eslint.config.mjs', 'utf-8')) + .toMatchInlineSnapshot(` + "import nx from "@nx/eslint-plugin"; + import baseConfig from "../../eslint.config.mjs"; + + export default [ + ...baseConfig, + { + files: [ + "**/*.json" + ], + rules: { + "@nx/dependency-checks": [ + "error", + { + ignoredFiles: [ + "{projectRoot}/eslint.config.{js,cjs,mjs}" + ] + } + ] + }, + languageOptions: { + parser: await import("jsonc-eslint-parser") + } + }, + ...nx.configs["flat/angular"], + ...nx.configs["flat/angular-template"], + { + files: [ + "**/*.ts" + ], + rules: { + "@angular-eslint/directive-selector": [ + "error", + { + type: "attribute", + prefix: "myOrg", + style: "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + type: "element", + prefix: "my-org", + style: "kebab-case" + } + ] + } + }, + { + files: [ + "**/*.html" + ], + // Override or add rules here + rules: {} + } + ]; + " + `); + expect(tree.read('eslint.config.mjs', 'utf-8')).toMatchInlineSnapshot(` + "import nx from "@nx/eslint-plugin"; + + export default [ + ...nx.configs["flat/base"], + ...nx.configs["flat/typescript"], + ...nx.configs["flat/javascript"], + { + ignores: [ + "**/dist" + ] + }, + { + files: [ + "**/*.ts", + "**/*.tsx", + "**/*.js", + "**/*.jsx" + ], + rules: { + "@nx/enforce-module-boundaries": [ + "error", + { + enforceBuildableLibDependency: true, + allow: [ + "^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?js$" + ], + depConstraints: [ + { + sourceTag: "*", + onlyDependOnLibsWithTags: [ + "*" + ] + } + ] + } + ] + } + }, + { + files: [ + "**/*.ts", + "**/*.tsx", + "**/*.cts", + "**/*.mts", + "**/*.js", + "**/*.jsx", + "**/*.cjs", + "**/*.mjs" + ], + // Override or add rules here + rules: {} + } + ]; + " + `); + + delete process.env.ESLINT_USE_FLAT_CONFIG; + }); + + it('should correctly generate the .eslintrc.json file for a buildable library', async () => { + addProjectConfiguration(tree, 'lib1', { + root: 'libs/lib1', + projectType: 'library', + targets: { build: {} }, + }); + + await addLintingGenerator(tree, { + prefix: 'myOrg', + projectName: 'lib1', + projectRoot: 'libs/lib1', + skipFormat: true, + }); + + expect(tree.read('libs/lib1/.eslintrc.json', 'utf-8')) + .toMatchInlineSnapshot(` + "{ + "extends": [ + "../../.eslintrc.json" + ], + "ignorePatterns": [ + "!**/*" + ], + "overrides": [ + { + "files": [ + "*.ts" + ], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "myOrg", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "my-org", + "style": "kebab-case" + } + ] + } + }, + { + "files": [ + "*.html" + ], + "extends": [ + "plugin:@nx/angular-template" + ], + "rules": {} + }, + { + "files": [ + "*.json" + ], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": [ + "{projectRoot}/eslint.config.{js,cjs,mjs}" + ] + } + ] + } + } + ] + } + " + `); + expect(tree.read('.eslintrc.json', 'utf-8')).toMatchInlineSnapshot(` + "{ + "root": true, + "ignorePatterns": [ + "**/*" + ], + "plugins": [ + "@nx" + ], + "overrides": [ + { + "files": [ + "*.ts", + "*.tsx", + "*.js", + "*.jsx" + ], + "rules": { + "@nx/enforce-module-boundaries": [ + "error", + { + "enforceBuildableLibDependency": true, + "allow": [], + "depConstraints": [ + { + "sourceTag": "*", + "onlyDependOnLibsWithTags": [ + "*" + ] + } + ] + } + ] + } + }, + { + "files": [ + "*.ts", + "*.tsx" + ], + "extends": [ + "plugin:@nx/typescript" + ], + "rules": {} + }, + { + "files": [ + "*.js", + "*.jsx" + ], + "extends": [ + "plugin:@nx/javascript" + ], + "rules": {} + } + ] + } + " + `); + }); }); diff --git a/packages/angular/src/generators/add-linting/add-linting.ts b/packages/angular/src/generators/add-linting/add-linting.ts index b66d9dacd5..c912baa0ac 100755 --- a/packages/angular/src/generators/add-linting/add-linting.ts +++ b/packages/angular/src/generators/add-linting/add-linting.ts @@ -89,22 +89,6 @@ export async function addLintingGenerator( files: ['*.html'], rules: {}, }); - - if (isBuildableLibraryProject(tree, options.projectName)) { - addOverrideToLintConfig(tree, '', { - files: ['*.json'], - parser: 'jsonc-eslint-parser', - rules: { - '@nx/dependency-checks': [ - 'error', - { - // With flat configs, we don't want to include imports in the eslint js/cjs/mjs files to be checked - ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs}'], - }, - ], - }, - }); - } } else { replaceOverridesInLintConfig(tree, options.projectRoot, [ ...(rootProject ? [typeScriptOverride, javaScriptOverride] : []),