From f1c090b640fc1776beb37d1f6e3b9c851923b066 Mon Sep 17 00:00:00 2001 From: Torin Date: Mon, 9 Jun 2025 07:29:19 -0600 Subject: [PATCH] fix(linter): update allowed ESLint config file extensions (#30127) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ESLint added experimental support for typescript config files since [9.9.0](https://eslint.org/blog/2024/08/eslint-v9.9.0-released/#experimental-typescript-configuration-files), and as of [9.18.0](https://eslint.org/blog/2025/01/eslint-v9.18.0-released/#stable-typescript-configuration-file-support) that support is stable. This PR add ts/mts/cts to the list of known eslint config files, and adds the same extensions to config file generators ## Current Behavior When using the eslint executor with a ts file, returns error "When using the new Flat Config with ESLint, all configs must be named eslint.config.js or eslint.config.cjs and .eslintrc files may not be used. See https://eslint.org/docs/latest/use/configure/configuration-files" When using the eslint plugin, the inferred task is not created for projects that do not have a non-ts eslint config. ### Workarounds - Compiling ts rules/configs in a project. Introduces other issues - Using jiti or comparable - For plugin users, having a fake eslint.config.js at the root allows the inferred task to be created. ESLint will still use the ts config. - Cache targets are wrong - Complications in non-monorepo workspaces ## Expected Behavior When using the eslint executor with a ts file, no error is thrown. When using the eslint plugin with a ts file, the inferred task is created. ## Related Issue(s) No issues, but addresses [this discussion](https://github.com/nrwl/nx/discussions/29710#discussion-7856165) --------- Co-authored-by: Leosvel Pérez Espinosa --- .../src/generators/add-linting/add-linting.spec.ts | 4 ++-- .../eslint/src/generators/init/global-eslint-config.ts | 2 +- .../src/generators/lint-project/lint-project.spec.ts | 8 +++++--- .../eslint/src/generators/lint-project/lint-project.ts | 6 ++++-- packages/eslint/src/utils/flat-config.ts | 7 +++++++ .../plugin/src/generators/lint-checks/generator.spec.ts | 2 +- .../src/generators/configuration/configuration.spec.ts | 2 +- 7 files changed, 21 insertions(+), 10 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 3ed1a11070..34d1084673 100644 --- a/packages/angular/src/generators/add-linting/add-linting.spec.ts +++ b/packages/angular/src/generators/add-linting/add-linting.spec.ts @@ -137,7 +137,7 @@ describe('addLinting generator', () => { "error", { ignoredFiles: [ - "{projectRoot}/eslint.config.{js,cjs,mjs}" + "{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}" ] } ] @@ -206,7 +206,7 @@ describe('addLinting generator', () => { { enforceBuildableLibDependency: true, allow: [ - "^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?js$" + "^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?[jt]s$" ], depConstraints: [ { diff --git a/packages/eslint/src/generators/init/global-eslint-config.ts b/packages/eslint/src/generators/init/global-eslint-config.ts index e3ae4233ef..cbc40f25de 100644 --- a/packages/eslint/src/generators/init/global-eslint-config.ts +++ b/packages/eslint/src/generators/init/global-eslint-config.ts @@ -137,7 +137,7 @@ export const getGlobalFlatEslintConfiguration = ( allow: [ // This allows a root project to be present without causing lint errors // since all projects will depend on this base file. - '^.*/eslint(\\.base)?\\.config\\.[cm]?js$', + '^.*/eslint(\\.base)?\\.config\\.[cm]?[jt]s$', ], depConstraints: [ { sourceTag: '*', onlyDependOnLibsWithTags: ['*'] }, diff --git a/packages/eslint/src/generators/lint-project/lint-project.spec.ts b/packages/eslint/src/generators/lint-project/lint-project.spec.ts index b030786844..6e40dfd295 100644 --- a/packages/eslint/src/generators/lint-project/lint-project.spec.ts +++ b/packages/eslint/src/generators/lint-project/lint-project.spec.ts @@ -308,7 +308,7 @@ describe('@nx/eslint:lint-project', () => { { enforceBuildableLibDependency: true, allow: [ - "^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?js$" + "^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?[jt]s$" ], depConstraints: [ { @@ -379,7 +379,7 @@ describe('@nx/eslint:lint-project', () => { { enforceBuildableLibDependency: true, allow: [ - "^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?js$" + "^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?[jt]s$" ], depConstraints: [ { @@ -495,7 +495,9 @@ describe('@nx/eslint:lint-project', () => { "@nx/dependency-checks": [ "error", { - "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] + "ignoredFiles": [ + "{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}" + ] } ] } diff --git a/packages/eslint/src/generators/lint-project/lint-project.ts b/packages/eslint/src/generators/lint-project/lint-project.ts index 2bb334f92d..6c50e1cd6c 100644 --- a/packages/eslint/src/generators/lint-project/lint-project.ts +++ b/packages/eslint/src/generators/lint-project/lint-project.ts @@ -293,8 +293,10 @@ function createEsLintConfiguration( '@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}'], + // With flat configs, we don't want to include imports in the eslint js/cjs/mjs/ts/cts/mts files to be checked + ignoredFiles: [ + '{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}', + ], }, ], }, diff --git a/packages/eslint/src/utils/flat-config.ts b/packages/eslint/src/utils/flat-config.ts index 61ab113ab2..23c6c9f15e 100644 --- a/packages/eslint/src/utils/flat-config.ts +++ b/packages/eslint/src/utils/flat-config.ts @@ -5,13 +5,20 @@ export const eslintFlatConfigFilenames = [ 'eslint.config.cjs', 'eslint.config.js', 'eslint.config.mjs', + 'eslint.config.cts', + 'eslint.config.ts', + 'eslint.config.mts', ]; export const baseEslintConfigFilenames = [ 'eslint.base.js', + 'eslint.base.ts', 'eslint.base.config.cjs', 'eslint.base.config.js', 'eslint.base.config.mjs', + 'eslint.base.config.cts', + 'eslint.base.config.ts', + 'eslint.base.config.mts', ]; export function getRootESLintFlatConfigFilename(tree: Tree): string { diff --git a/packages/plugin/src/generators/lint-checks/generator.spec.ts b/packages/plugin/src/generators/lint-checks/generator.spec.ts index 8c255884f7..60093427fb 100644 --- a/packages/plugin/src/generators/lint-checks/generator.spec.ts +++ b/packages/plugin/src/generators/lint-checks/generator.spec.ts @@ -159,7 +159,7 @@ describe('lint-checks generator', () => { "error", { "ignoredFiles": [ - "{projectRoot}/eslint.config.{js,cjs,mjs}", + "{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}", ], }, ], diff --git a/packages/vite/src/generators/configuration/configuration.spec.ts b/packages/vite/src/generators/configuration/configuration.spec.ts index 7337fb91ab..33dba790a9 100644 --- a/packages/vite/src/generators/configuration/configuration.spec.ts +++ b/packages/vite/src/generators/configuration/configuration.spec.ts @@ -296,7 +296,7 @@ describe('@nx/vite:configuration', () => { 'error', { ignoredFiles: [ - '{projectRoot}/eslint.config.{js,cjs,mjs}', + '{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}', '{projectRoot}/vite.config.{js,ts,mjs,mts}', ], },