vuejs / eslint-config-typescript

ESLint configuration for Vue 3 + TypeScript projects
MIT License
133 stars 30 forks source link

Support ESLint `v9` #76

Closed simensol closed 2 months ago

simensol commented 8 months ago

Just a heads up, ESLint v9 was released recently and it seems to be incompatible with @vue/eslint-config-typescript. Here's the error I got:

npm ERR! ERESOLVE could not resolve
npm ERR! While resolving: @vue/eslint-config-typescript@13.0.0
npm ERR! Found: eslint@9.0.0
npm ERR! node_modules/eslint
npm ERR!   dev eslint@"^9.0.0" from the root project
npm ERR! Could not resolve dependency:
npm ERR! peer eslint@"^8.56.0" from @vue/eslint-config-typescript@13.0.0
npm ERR! node_modules/@vue/eslint-config-typescript
npm ERR!   dev @vue/eslint-config-typescript@"^13.0.0" from the root project
npm ERR! Conflicting peer dependency: eslint@8.57.0
npm ERR! node_modules/eslint
npm ERR!   peer eslint@"^8.56.0" from @vue/eslint-config-typescript@13.0.0
npm ERR!   node_modules/@vue/eslint-config-typescript
npm ERR!     dev @vue/eslint-config-typescript@"^13.0.0" from the root project
lvzhenbo commented 8 months ago

Wait for the maintainer to update it, eslint 9.0 made a lot of destructive changes, including configuration files See this blog for details https://eslint.org/blog/2024/04/eslint-v9.0.0-released/

JoostKersjes commented 7 months ago

I've been working on https://github.com/vuejs/create-eslint-config/pull/25

That helped me understand a bit of what is possible with ESLint v9, so I tried it just now on one of my projects.

When I use ...compat.extends("@vue/eslint-config-typescript"), it throws up a bunch of parsing errors:

But for some reason that doesn't happen with ...compat.extends("@vue/eslint-config-typescript/recommended").

Here is the full config that works for me with ESLint 9, Vue 3, TypeScript & Prettier:

// eslint.config.js
import path from "node:path";
import { fileURLToPath } from "node:url";

import { FlatCompat } from "@eslint/eslintrc";
import js from "@eslint/js";
import pluginVue from "eslint-plugin-vue";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: js.configs.recommended,
});

export default [
  js.configs.recommended,
  ...pluginVue.configs["flat/essential"],
  ...compat.extends("@vue/eslint-config-typescript/recommended"),
  ...compat.extends("@vue/eslint-config-prettier/skip-formatting"),
  {
    files: [
      "**/*.vue",
      "**/*.js",
      "**/*.jsx",
      "**/*.cjs",
      "**/*.mjs",
      "**/*.ts",
      "**/*.tsx",
      "**/*.cts",
      "**/*.mts",
    ],
    languageOptions: {
      ecmaVersion: "latest",
    },
  },
];
susnux commented 7 months ago

This depends on typescript-eslint to provide v9 support first, ref: https://github.com/typescript-eslint/typescript-eslint/issues/8211

riodw commented 6 months ago

EDIT: lol at everyone downvoting this... The fix was not out at the time I had this error, there was no other option.

Full thread for SEO:

% npm i

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: project@1.0.0
npm ERR! Found: eslint@9.2.0
npm ERR! node_modules/eslint
npm ERR!   dev eslint@"9.2.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer eslint@"^8.56.0" from @vue/eslint-config-typescript@13.0.0
npm ERR! node_modules/@vue/eslint-config-typescript
npm ERR!   dev @vue/eslint-config-typescript@"13.0.0" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

Temp fix for this: Downgrade eslint

grindpride commented 6 months ago

wait for support

cweijan commented 6 months ago

I am upgrading eslint v9. After referring to eslint-config-typescript, I found that it is easy to add a new eslint v9 rule to support.

import tseslint from 'typescript-eslint';
{
        files: ["**/*.vue"],
        languageOptions: {
            parserOptions: {
                parser: {
                    'js': 'espree',
                    'jsx': 'espree',
                    'mjs': 'espree',
                    'ts': tseslint.parser,
                    'tsx': tseslint.parser,
                    'mts': tseslint.parser,
                    // Leave the template parser unspecified, so that it could be determined by `<script lang="...">`
                },
                extraFileExtensions: ['.vue'],
                ecmaFeatures: {
                    jsx: true
                }
            }
        }
}

image

n0099 commented 6 months ago

When using flat config, packages @typescript-eslint/{parser,eslint-plugin} should be replaced by the merged typescript-eslint since they only provide flat .configs in that package: https://github.com/typescript-eslint/typescript-eslint/pull/7935

But if you have both @typescript-eslint/{parser,eslint-plugin} and typescript-eslint installed and applying https://github.com/vuejs/eslint-config-typescript/issues/76#issuecomment-2051234597:

import vueESLintConfigTypescriptRecommendedExtends from '@vue/eslint-config-typescript/recommended.js'
import typescriptESLint from 'typescript-eslint';

export default [
    ...compat.config(vueESLintConfigTypescriptRecommendedExtends), // same with ...compat.extends('@vue/eslint-config-typescript/recommended')
    ...typescriptESLint.configs.strictTypeChecked,
    ...typescriptESLint.configs.stylisticTypeChecked,
];

they won't work together:

ConfigError: Config "typescript-eslint/base": Key "plugins": Cannot redefine plugin "@typescript-eslint".
rijenkii commented 5 months ago

Here's the config that I've just wrote. Haven't tested much, but it seems to work:

import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
  ...pluginVue.configs["flat/recommended"],
  {
    languageOptions: {
      parserOptions: {
        parser: tseslint.parser,
        projectService: true,
        extraFileExtensions: ['.vue'],
      },
    },
  },
);

tseslint.configs.*TypeChecked configs also work, but there are issues, see https://github.com/vuejs/vue-eslint-parser/issues/104.

Also, when using *TypeChecked configs be sure to add { "ignore": ["eslint.config.js"] } to your configs, as eslint-plugin-vue is not typed (https://github.com/vuejs/eslint-plugin-vue/issues/2124).

lovetingyuan commented 5 months ago

@sodatea hi, please check out this, It has been a while time after eslint v9 released.

Shyam-Chen commented 5 months ago

I have integrated TypeScript, Vue, and Prettier in ESLint v9, and it is working well.

  "devDependencies": {
    "eslint": "9.6.0",
    "eslint-config-prettier": "9.1.0",
    "eslint-plugin-prettier": "5.1.3",
    "eslint-plugin-vue": "9.27.0",
    "globals": "15.8.0",
    "prettier": "3.3.2",
    "typescript-eslint": "7.15.0"
  }
Tamas-hi commented 4 months ago

typescript-eslint v8 was released yesterday which now fully support eslint v9, so typescript-eslint is no longer a blocker.

Gnuk commented 3 months ago

I've just done #79 PR few days ago, maybe someone of you want to review this draft (I have one issue remaining).

MartinX3 commented 3 months ago

Nice @Gnuk
With the new ESlint 9.9.0 and the needed feature flag you could also use eslint.config.ts.

throrin19 commented 2 months ago

Any news about that ?

bmulholland commented 2 months ago

v8 is EOL in a month: https://eslint.org/version-support/

orimay commented 1 week ago

When using flat config, packages @typescript-eslint/{parser,eslint-plugin} should be replaced by the merged typescript-eslint since they only provide flat .configs in that package: typescript-eslint/typescript-eslint#7935

But if you have both @typescript-eslint/{parser,eslint-plugin} and typescript-eslint installed and applying #76 (comment):

import vueESLintConfigTypescriptRecommendedExtends from '@vue/eslint-config-typescript/recommended.js'
import typescriptESLint from 'typescript-eslint';

export default [
    ...compat.config(vueESLintConfigTypescriptRecommendedExtends), // same with ...compat.extends('@vue/eslint-config-typescript/recommended')
    ...typescriptESLint.configs.strictTypeChecked,
    ...typescriptESLint.configs.stylisticTypeChecked,
];

they won't work together:

ConfigError: Config "typescript-eslint/base": Key "plugins": Cannot redefine plugin "@typescript-eslint".

I handled it like this:

function dedulplicatePlugins(
  ...plugins: TSESLint.FlatConfig.ConfigArray
): TSESLint.FlatConfig.ConfigArray {
  const foundPlugins = new Set<string>();
  return plugins.filter(plugin => {
    if (plugin.name === undefined) return true;
    if (foundPlugins.has(plugin.name)) return false;
    foundPlugins.add(plugin.name);
    if (plugin.name === 'typescript-eslint/base') {
      delete plugin.plugins?.['@typescript-eslint'];
    }
    return true;
  });
}

const eslintConfig: ReturnType<typeof tsESLint.config> = tsESLint.config(
  js.configs.recommended,
  ...dedulplicatePlugins(
    ...tsESLint.configs.strict,
    ...tsESLint.configs.stylistic,
  ),
  // ..