iamturns / eslint-config-airbnb-typescript

Airbnb's ESLint config with TypeScript support
MIT License
1.05k stars 98 forks source link

Support "Flat Config" (ESLint 9) #331

Open JoshuaKGoldberg opened 9 months ago

JoshuaKGoldberg commented 9 months ago

👋 Coming over from https://github.com/eslint/eslint/issues/18093: ESLint is migrating to a new "flat config" format that will be the default in ESLint v9.

It doesn't look like eslint-config-airbnb-typescript has support yet. I'm posting this issue here as a reference & cross-linking it to the table in https://github.com/eslint/eslint/issues/18093. If there's anything technical blocking the extension from supporting flat configs, please let us know - we'd be happy to try to help! 💜

Additional resources:

samuelneff commented 5 months ago

Are there any plans to add support for flat config to this project?

samuelneff commented 5 months ago

Some more searching and I stumbled across the compatibility helpers that allow this project to be used with flat config.

Example:

import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import eslintConfigPrettier from "eslint-config-prettier";

import { FlatCompat } from "@eslint/eslintrc";
import path from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const compat = new FlatCompat({
  baseDirectory: __dirname
});

export default tseslint.config(
  eslint.configs.recommended,
  ...compat.extends("airbnb-base"),
  ...compat.extends("airbnb-typescript/base"),
  ...tseslint.configs.recommendedTypeChecked,
  eslintConfigPrettier,
  {
    languageOptions: {
      parserOptions: {
        project: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  {
      files: ['**/*.{js,jsx,cjs,mjs}'],
      extends: [tseslint.configs.disableTypeChecked],
  }
);

From: https://stackoverflow.com/questions/78253188/flat-config-file-with-configs-from-legacy-eslintrc-compat-error

My setup based on this one works. 🙏

RashiqAzhan commented 5 months ago

I'm getting this error with the compat helpers.

Oops! Something went wrong! :(

ESLint: 8.57.0

Error: Key "plugins": Cannot redefine plugin "@typescript-eslint".

Relevant installs in package.json

"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^8.57.0",
"@typescript-eslint/eslint-plugin": "^7.12.0",
"@typescript-eslint/parser": "^7.12.0",
"eslint": "^8.57.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript":  "^18.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"typescript-eslint": "^7.3.1",

eslint.config.mjs

import eslint from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import tsEslint from "typescript-eslint";

import { FlatCompat } from "@eslint/eslintrc";
import path from "path";
import { fileURLToPath } from "url";

const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);

const compat = new FlatCompat({
  baseDirectory: dirname
});

export default tsEslint.config(
  eslint.configs.recommended,
  ...compat.extends("airbnb-base"),
  ...compat.extends("airbnb-typescript/base"),
  ...tsEslint.configs.recommendedTypeChecked,
  // This disables the formatting rules in ESLint that Prettier is going to be responsible for handling.
  // Make sure it's always the last config, so it gets the chance to override other configs.
  eslintConfigPrettier,
  {
    ignores: ["dist", "distServer", "node_modules", "build"],
  },
  {
    languageOptions: {
      parserOptions: {
        project        : true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  {
    files: ["**/*.{js,jsx,cjs,mjs}"],
    ...tsEslint.configs.disableTypeChecked
  },
);
dominik-zeglen commented 5 months ago

Hey, any news here? Like @RashiqAzhan I also can't make it work with FlatCompat. I'm using eslint v9.4.0 though.

samuelneff commented 5 months ago

I'm getting this error with the compat helpers.

My working config looks almost exactly like yours; just no Prettier.

import { FlatCompat } from "@eslint/eslintrc";
import eslint from '@eslint/js';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import perfectionistConfig from 'eslint-plugin-perfectionist/configs/recommended-natural';
import regexpPlugin from 'eslint-plugin-regexp';
import simpleImportSort from "eslint-plugin-simple-import-sort";
import unicorn from 'eslint-plugin-unicorn';
import tseslint from 'typescript-eslint';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const compat = new FlatCompat({
  baseDirectory: __dirname
});

export default tseslint.config(
  eslint.configs.recommended,
  ...compat.extends("airbnb"),
  ...compat.extends("airbnb-typescript"),
  ...tseslint.configs.recommendedTypeChecked,
  perfectionistConfig,
  regexpPlugin.configs['flat/recommended'],
  {
    plugins: {
      'simple-import-sort': simpleImportSort,
      unicorn,
    },
    languageOptions: {
      parserOptions: {
        project: true,
        tsconfigRootDir: __dirname,
      },
    },
    rules: {
    }
  },
  {
    ignores: [
      'src/client/vite-env.d.ts',
    ]
  }
);
  "devDependencies": {
    "@eslint/eslintrc": "^3.1.0",
    "@eslint/js": "^9.4.0",
    "@nabla/vite-plugin-eslint": "^2.0.4",
    "@typescript-eslint/eslint-plugin": "^7.2.0",
    "@typescript-eslint/parser": "^7.2.0",
    "eslint": "^8.57.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-airbnb-typescript": "^18.0.0",
    "eslint-plugin-perfectionist": "^2.10.0",
    "eslint-plugin-react": "^7.34.2",
    "eslint-plugin-regexp": "^2.6.0",
    "eslint-plugin-simple-import-sort": "^12.1.0",
    "eslint-plugin-unicorn": "^53.0.0",
    "typescript": "^5.2.2",
    "typescript-eslint": "^7.12.0",
  }
tiavina-mika commented 5 months ago

Following @samuelneff solution, I have this error: ` Oops! Something went wrong! :(

ESLint: 9.4.0

ESLint couldn't find the plugin "@typescript-eslint/eslint-plugin". `

It's because with typescript-eslint (v8)[https://typescript-eslint.io/blog/announcing-typescript-eslint-v7/#new-features---flat-config-support] @typescript-eslint/eslint-plugin no longer exists

samuelneff commented 5 months ago

@tiavina-mika Look carefully at the instructions on the page you linked to. It's a little confusing.

Note for others: This answer and the question it responds to are about typescript-eslint and not eslint-config-airbnb-typescript. So a little off topic, but related.

This error:

ESLint couldn't find the plugin "@typescript-eslint/eslint-plugin".

Is because of the first commands:

npm un @typescript-eslint/parser @typescript-eslint/eslint-plugin
npm i typescript-eslint

The first one uninstalls @typescript-eslint/eslint-plugin. That is the old plugin that does not support flat config. typescript-eslint is the new one that does support it and is being installed.

If you're getting that error, then there is still a reference to it in your eslint.config.js file. Remove that reference and use typescript-eslint instead.

In your import statements there should only be one that references typescript:

import tseslint from 'typescript-eslint';

and your plugins should not reference anything related to TypeScript (you'll be destructuring ...tseslint.configs.recommendedTypeChecked instead of referencing it as a plugin).

ento-io commented 5 months ago

I' m getting this error using FlatCompat:

Oops! Something went wrong! :(

ESLint: 9.4.0

ConfigError: Config (unnamed): Key "plugins": Cannot redefine plugin "@typescript-eslint".
samuelneff commented 5 months ago

@ento-io sounds like you're defining the plugin within your config and also including the recommended config which itself defines the plugin. Remove your plugin definition.

Kenneth-Sills commented 3 months ago

Once #356 is merged, we'll at least have documentation on how to use this project in a modern codebase. Then I'll begin work on moving us to a flat config. But ESLint 9 support will have to wait for upstream to finish; that's the only real holdout at this point.