vue-eslint-parser icon indicating copy to clipboard operation
vue-eslint-parser copied to clipboard

Provide support for eslint 9's flat configuration

Open ajmas opened this issue 9 months ago • 9 comments

It is not clear whether vue-eslint-parser supports eslint 9's flat configuration, but the current issue I am running into suggest that flat configuration may not be supported.

I currently have the following eslint.config.js:

import importPlugin from 'eslint-plugin-import';
import vueParser from 'vue-eslint-parser';
import tsParser from '@typescript-eslint/parser';
import tsPlugin from '@typescript-eslint/eslint-plugin';
import { FlatCompat } from '@eslint/eslintrc';
import path from 'path';
import { fileURLToPath } from 'url';

// mimic CommonJS variables -- not needed if using CommonJS
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

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

export default [
  ...compat.extends('plugin:vue/vue3-recommended'),
  {
    files: [
      '**/*.vue', '**/*.js', '**/*.jsx', '**/*.cjs', 
      '**/*.mjs', '**/*.ts', '**/*.tsx', '**/*.cts', 
      '**/*.mts'
   ],
    ignores: ['.gitignore'],
    plugins: {
      import: importPlugin,
      '@typescript-eslint': tsPlugin
    },
    languageOptions: {
      parser: vueParser,
      parserOptions: {
        parser: tsParser
      },
      ecmaVersion: 'latest',
    },
    rules: {
      // allow async-await
      'generator-star-spacing': 'off',
      // allow paren-less arrow functions
      'arrow-parens': 'off',
      'one-var': 'off',
      'no-void': 'off',
      'multiline-ternary': 'off',

      'import/first': 'off',
      'import/namespace': 'error',
      'import/default': 'error',
      'import/export': 'error',
      'import/extensions': 'off',
      'import/no-unresolved': 'off',
      'import/no-extraneous-dependencies': 'off',
      'prefer-promise-reject-errors': 'off',
      'space-before-function-paren': 'error',
      semi: [2, 'always'],
      indent: ['error', 2],
      'vue/multi-word-component-names': 'warn',

      // TypeScript
      quotes: ['warn', 'single', { avoidEscape: true }],
      '@typescript-eslint/explicit-function-return-type': 'off',
      '@typescript-eslint/explicit-module-boundary-types': 'off',
      '@typescript-eslint/no-unnecessary-type-assertion': 'off',
      '@typescript-eslint/no-unsafe-assignment': 'off',
      '@typescript-eslint/no-unsafe-member-access': 'off',
      '@typescript-eslint/no-unsafe-call': 'off',
      '@typescript-eslint/no-explicit-any': 'off',
      '@typescript-eslint/restrict-template-expressions': 'off',
      '@typescript-eslint/no-misused-promises': 'off',
      '@typescript-eslint/no-unsafe-argument': 'off',

      'vue/singleline-html-element-content-newline': 'off',
      'vue/max-attributes-per-line': 'off',

      // allow debugger during development only
      'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
    }
  }
];

This is currently giving me errors of the type:

35:38 error Parse errors in imported module 'vue': parserPath or languageOptions.parser is required! (undefined:undefined) import/namespace 36:31 error Parse errors in imported module 'vue': parserPath or languageOptions.parser is required! (undefined:undefined) imp

Related dependencies:

    "@vue/cli-service": "~5.0.8",
    "@vue/eslint-config-prettier": "^9.0.0",
    "@vue/eslint-config-typescript": "^13.0.0",
    "@vue/tsconfig": "^0.5.1",
    "eslint": "^9.2.0",
    "eslint-config-standard": "^17.0.0",
    "eslint-plugin-import": "^2.27.5",
    "eslint-plugin-n": "^17.4.0",
    "eslint-plugin-promise": "^6.1.1",
    "eslint-plugin-vue": "^9.10.0",

ajmas avatar May 04 '24 21:05 ajmas

You are using eslint-plugin-import which does not support flat config yet. That could be the issue.

abdul-alhasany avatar May 05 '24 13:05 abdul-alhasany

Thanks. I’ll explore this as a possibility. Short term I’ve downgraded back to eslint 8.

ajmas avatar May 06 '24 15:05 ajmas

It looks like this doesn't support eslint 9 yet, I see "eslint": "^8.12.0" in the package.json as of now.

KyleBrown-804 avatar Jul 12 '24 00:07 KyleBrown-804

Its releases' changelog doesn't include any content related to ESLint 9, so...

jynxioxiao-lb avatar Jul 22 '24 09:07 jynxioxiao-lb

Bumping this, does anyone know what needs to be fixed to get ESLint support? Happy to help contribute as it's blocking our team's ability to upgrade to ESLint 9

ratherblue avatar Aug 05 '24 18:08 ratherblue

@ratherblue: I currently have vue3 + typescript + eslint9, not using vue-eslint-parser though, but I wonder why it is actually needed here. Not sure it helps your case, but here it is:

In package.json (extract only):

"@eslint/js": "^9.8.0",
"@types/eslint__js": "^8.42.3",
"@vue/tsconfig": "^0.5.1",
"eslint": "^9.8.0",
"eslint-plugin-promise": "^7.0.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-vue": "^9.27.0",
"typescript": "~5.5.4",
"typescript-eslint": "^8.0.0",

Here is my eslint.config.js :

import js from '@eslint/js';
import pluginPromise from 'eslint-plugin-promise';
import simpleImportSort from 'eslint-plugin-simple-import-sort';
import vue from 'eslint-plugin-vue';
import ts from 'typescript-eslint';

export default [
  {
    languageOptions: {
      ecmaVersion: 'latest',
    },
  },

  // js
  js.configs.recommended,

  // ts
  ...ts.configs.recommended,
  {
    rules: {
      '@typescript-eslint/no-explicit-any': 'warn',
      '@typescript-eslint/no-unused-expressions': ['error', { allowTernary: true }],
    },
  },

  // vue
  ...vue.configs['flat/recommended'],
  {
    // files: ['*.vue', '**/*.vue'],
    languageOptions: {
      parserOptions: {
        parser: ts.parser,
      },
    },
  },
  {
    rules: {
      'vue/multi-word-component-names': 'off',
      'vue/no-unused-vars': ['error', { ignorePattern: '^_' }],
      'vue/max-attributes-per-line': ['error', { singleline: 5 }],
    },
  },

  // Sort imports
  {
    plugins: {
      'simple-import-sort': simpleImportSort,
    },
    rules: {
      'simple-import-sort/imports': [
        'error',
        {
          groups: [
            [
              '^\\u0000', // all side effects (0 at start)
              '^[^/\\.].*\u0000$', // external types (0 at end)
              '^\\..*\u0000$', // internal types (0 at end)
              '^@?\\w', // Starts with @
              '^[^.]', // any
              '^\\.', // local
            ],
          ],
        },
      ],
      'simple-import-sort/exports': 'error',
    },
  },

  // Promise
  pluginPromise.configs['flat/recommended'],
];

dclause avatar Aug 06 '24 08:08 dclause

@dclause can you try it with type information enabled for typescript-eslint? That's not working for me.

sid-6581 avatar Sep 06 '24 21:09 sid-6581

@sid-6581 Not sure what you ask here: You can change my previous example as such :

// ts
// ...ts.configs.recommended,
...ts.configs.recommendedTypeChecked,
{
files: ['**/*.ts', '**/*.tsx', '**/*.cts', '**/*.mts'],
languageOptions: {
  parserOptions: {
    project: true,
    tsconfigRootDir: import.meta.dirname,
    parser: ts.parser,
    extraFileExtensions: ['.vue'],
  },
},
rules: {
  '@typescript-eslint/no-explicit-any': 'warn',
  '@typescript-eslint/no-unused-expressions': ['error', { allowTernary: true }],
},
},

dclause avatar Sep 19 '24 08:09 dclause

@dclause Thanks! I was able to get it to work eventually, it was a little more complicated by the fact that I'm using pug and I have a monorepo. Here is what I ended up with:

import js from "@eslint/js";
import ts from "typescript-eslint";
import vue from "eslint-plugin-vue";
import vuePug from "eslint-plugin-vue-pug";
import vueParser from "vue-eslint-parser";
import stylistic from "@stylistic/eslint-plugin";

export default ts.config(
  {
    files: ["**/*.js", "**/*.ts", "**/*.vue"],
  },

  {
    ignores: ["**/dist/*", "**/wwwroot/*", "**/api.ts", "**/bin/*", "**/obj/*"],
  },

  js.configs.recommended,
  stylistic.configs["recommended-flat"],
  ...ts.configs.strictTypeChecked,
  ...ts.configs.stylisticTypeChecked,
  ...vue.configs["flat/recommended"],
  stylistic.configs["disable-legacy"],

  {
    languageOptions: {
      parser: vueParser,
      parserOptions: {
        ecmaVersion: "latest",
        extraFileExtensions: [".vue"],
        parser: ts.parser,
        project: ["./tsconfig.json", "./src/FrontEnd.Shared/tsconfig.json"],
        sourceType: "module",
        templateTokenizer: {
          pug: "vue-eslint-parser-template-tokenizer-pug",
        },
        tsconfigRootDir: import.meta.dirname,
      },
    },

    plugins: {
      "vue-pug": vuePug,
    },

   rules: { ... }
}

sid-6581 avatar Sep 20 '24 15:09 sid-6581