From 9adebc0b64a5caf83ad96f2a7a4ac15b587f72f9 Mon Sep 17 00:00:00 2001 From: Moreno Feltscher Date: Fri, 6 Dec 2024 14:45:48 +0100 Subject: [PATCH] feat: add configuration for Next.js (#37) --- README.md | 3 +++ package.json | 6 +++++- src/index.ts | 33 +++++++++++++++++++++++------ src/typings/eslint-config-next.d.ts | 6 ++++++ 4 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 src/typings/eslint-config-next.d.ts diff --git a/README.md b/README.md index 109ec13..3f603a9 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ export default configs.typescript; // .. or React applications export default configs.react; + +// .. or Next.js applications +export default configs.next; ``` ### Legacy Config (`.eslintrc`) diff --git a/package.json b/package.json index ff4c5f6..0cd7f09 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ }, "homepage": "https://github.com/smartive/eslint-config#readme", "dependencies": { + "@eslint/eslintrc": "^3.2.0", "@typescript-eslint/eslint-plugin": "^8.15.0", "@typescript-eslint/parser": "^8.15.0", "eslint-config-prettier": "^9.1.0", @@ -50,17 +51,20 @@ "typescript-eslint": "^8.15.0" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "eslint-config-next": "^14.0.0 || ^15.0.0" }, "devDependencies": { "@commitlint/cli": "^19.6.0", "@commitlint/config-conventional": "^19.6.0", "@eslint/js": "^9.15.0", "@smartive/prettier-config": "^3.0.0", + "@types/eslint__eslintrc": "^2.1.2", "@types/node": "^22.9.1", "cz-conventional-changelog": "^3.3.0", "esbuild": "0.24.0", "eslint": "^9.15.0", + "eslint-config-next": "^15.0.4", "husky": "^9.1.7", "prettier": "^3.3.3", "typescript": "^5.6.3" diff --git a/src/index.ts b/src/index.ts index 44cf7f9..985b551 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +import { FlatCompat } from '@eslint/eslintrc'; import js from '@eslint/js'; import type { Linter } from 'eslint'; import { flatConfigs as eslintPluginImportConfigs } from 'eslint-plugin-import'; @@ -86,16 +87,34 @@ const flatConfigTypescript = tsEslint.config( }, ); -const flatConfigReact = tsEslint.config( - flatConfigTypescript, - reactPlugin.configs.flat!.recommended as unknown as Linter.Config, - reactPlugin.configs.flat!['jsx-runtime'] as unknown as Linter.Config, - { rules: reactRules }, -); +// This is just a workaround until Next.js decides to provide a flat config +// the same way the rest of the world does.. +// Nid hässig, nur entüüscht. +const flatConfigNext = () => + new FlatCompat().extends('next').map((config) => { + const { plugins } = config; + if (plugins?.import) { + // ugly workaround to fix an issue when reusing the import plugin + // see https://github.com/eslint/eslintrc/issues/135 + plugins.import = eslintPluginImportConfigs.errors.plugins!.import; + } + + return config; + }); + +const flatConfigReact = (includeNextConfig = false) => + tsEslint.config( + flatConfigTypescript, + reactPlugin.configs.flat!.recommended as unknown as Linter.Config, + reactPlugin.configs.flat!['jsx-runtime'] as unknown as Linter.Config, + ...(includeNextConfig ? flatConfigNext() : []), + { rules: reactRules }, + ); export const configs = { typescript: flatConfigTypescript, - react: flatConfigReact, + react: flatConfigReact(), + next: flatConfigReact(true), }; export const generateLegacyConfig = (react: boolean): Linter.LegacyConfig => ({ diff --git a/src/typings/eslint-config-next.d.ts b/src/typings/eslint-config-next.d.ts new file mode 100644 index 0000000..c7185da --- /dev/null +++ b/src/typings/eslint-config-next.d.ts @@ -0,0 +1,6 @@ +import type { Linter } from 'eslint'; + +declare module 'eslint-config-next' { + const plugin: Linter.LegacyConfig; + export = plugin; +}