Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The plugin does not function properly when languageOptions.projectService is enabled #2634

Open
2 tasks done
A-kirami opened this issue Dec 1, 2024 · 8 comments
Open
2 tasks done

Comments

@A-kirami
Copy link

A-kirami commented Dec 1, 2024

Checklist

  • I have tried restarting my IDE and the issue persists.
  • I have read the FAQ and my problem is not listed.

Tell us about your environment

  • ESLint version: 9.16.0
  • eslint-plugin-vue version: 9.32.0
  • Vue version: 3.5.13
  • Node version: 22.11.0
  • Operating System: Windows11

Please show your full configuration:

// @ts-check

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"],
  {
    files: ["*.vue", "**/*.vue"],
    languageOptions: {
      parserOptions: {
        parser: tseslint.parser,
        ecmaFeatures: {
          jsx: true,
        },
        extraFileExtensions: [".vue"],
        projectService: true, // If you comment out this line, it will work.
        tsconfigRootDir: import.meta.dirname,
      },
    },
  }
);

What did you do?

When languageOptions.projectService is set to true, it reports errors for JSX but does not report errors for Vue.

<script setup lang="tsx">
const jsxComponent = <div>This is a jsx component</div>
</script>

<template>
  <jsxComponent></jsxComponent>
  <div></div>
</template>

What did you expect to happen?

The errors related to JSX should not be reported, and errors related to Vue should be reported.

/project/workspace/src/App.vue
  6:3  warning  Require self-closing on Vue.js custom components (<jsxComponent>)  vue/html-self-closing
  7:3  warning  Require self-closing on HTML elements (<div>)                      vue/html-self-closing

✖ 2 problems (0 errors, 2 warnings)
  0 errors and 2 warnings potentially fixable with the `--fix` option.

What actually happened?

/project/workspace/src/App.vue
  2:31  error  Parsing error: ',' expected

✖ 1 problem (1 error, 0 warnings)

Repository to reproduce this issue

https://codesandbox.io/p/devbox/cvwhrs

@FloEdelmann
Copy link
Member

This has nothing to do with projectService. It's that you tell ESLint to parse Vue files with typescript-eslint's parser. Instead, you have to use eslint-parser-vue, which in turn you can tell to use typescript-eslint's parser for the JavaScript/TypeScript parts of Vue components. See e.g. https://eslint.vuejs.org/user-guide/#example-configuration-with-typescript-eslint-and-prettier.

@A-kirami
Copy link
Author

A-kirami commented Dec 1, 2024

This has nothing to do with projectService. It's that you tell ESLint to parse Vue files with typescript-eslint's parser. Instead, you have to use eslint-parser-vue, which in turn you can tell to use typescript-eslint's parser for the JavaScript/TypeScript parts of Vue components. See e.g. eslint.vuejs.org/user-guide#example-configuration-with-typescript-eslint-and-prettier.

I need to enable Linting with Type Information for typescript-eslint. According to its documentation, I need to set up the following:

  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },

I updated my ESLint configuration based on the documentation you provided:

// @ts-check

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

export default tseslint.config(
  {
    extends: [
      eslint.configs.recommended,
      ...tseslint.configs.recommended,
      ...pluginVue.configs["flat/recommended"],
    ],
    files: ["**/*.{ts,vue}"],
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module",
      globals: globals.browser,
      parserOptions: {
        parser: tseslint.parser,
        ecmaFeatures: {
          jsx: true,
        },
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
    rules: {
      // your rules
    },
  }
);

However, it resulted in an error:

/project/workspace/src/App.vue
  0:0  error  Parsing error: /project/workspace/src/App.vue was not found by the project service because the extension for the file (`.vue`) is non-standard. You should add `parserOptions.extraFileExtensions` to your config

✖ 1 problem (1 error, 0 warnings)

After configuring parserOptions.extraFileExtensions as suggested by the error message:

/project/workspace/src/App.vue
  2:31  error  Parsing error: ',' expected

✖ 1 problem (1 error, 0 warnings)

The previous issue still persists.

Is there an incorrect configuration somewhere? How should it be set up to work seamlessly with Typed Linting?

@FloEdelmann

This comment was marked as outdated.

@A-kirami
Copy link
Author

A-kirami commented Dec 1, 2024

You need to add "./**/*.vue" to the "include" option in your tsconfig.json.

You can see the reproduction link I submitted in the issue, where the tsconfig.json configuration is as follows:

{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",
    "jsxImportSource": "vue",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

"src/**/*.vue" should already be included.

Even if I add "./**/*.vue" to "include":

/project/workspace/src/App.vue
  0:0  error  Parsing error: /project/workspace/src/App.vue was not found by the project service because the extension for the file (`.vue`) is non-standard. You should add `parserOptions.extraFileExtensions` to your config

✖ 1 problem (1 error, 0 warnings)

@FloEdelmann
Copy link
Member

FloEdelmann commented Dec 1, 2024

"src/**/*.vue" should already be included.

Oh right.

I have a pretty similar setup (but still on ESLint v8 with .eslintrc.js config format, and without JSX) and it works fine with:

  parserOptions: {
    parser: {
      js: '@typescript-eslint/parser',
      ts: '@typescript-eslint/parser',
      '<template>': '@typescript-eslint/parser',
    },
    projectService: {
      allowDefaultProject: ['.eslintrc.js', '*.js'],
    },
    tsconfigRootDir: __dirname,
    extraFileExtensions: ['.vue'],
    ecmaVersion: 2021,
    sourceType: 'module',
  },

Maybe it is the JSX that is throwing either parser off somehow?

@A-kirami
Copy link
Author

A-kirami commented Dec 1, 2024

"src/**/*.vue" should already be included.

Oh right.

I have a pretty similar setup (but still on ESLint v8 with .eslintrc.js config format, and without JSX) and it works fine with:

  parserOptions: {
    parser: {
      js: '@typescript-eslint/parser',
      ts: '@typescript-eslint/parser',
      '<template>': '@typescript-eslint/parser',
    },
    projectService: {
      allowDefaultProject: ['.eslintrc.js', '*.js'],
    },
    tsconfigRootDir: __dirname,
    extraFileExtensions: ['.vue'],
    ecmaVersion: 2021,
    sourceType: 'module',
  },

Maybe it is the JSX that is throwing either parser off somehow?

I haven't encountered this issue on ESLint 8; everything works fine, even with JSX. However, after upgrading to ESLint 9, the problem emerged.

Here is my ESLint 8 configuration, which didn't encounter any issues:

"plugins": ["vue", "@typescript-eslint"],
"parser": "vue-eslint-parser",
"parserOptions": {
    "ecmaVersion": 13,
    "parser": "@typescript-eslint/parser",
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
  }
},

ESLint 9 works fine if I don't configure TypeScript ESLint's Typed Linting. To be honest, I'm not sure where the issue lies.

@FloEdelmann
Copy link
Member

So you don't have typed linting with ESLint 8? Could you try whether that works?

@A-kirami
Copy link
Author

A-kirami commented Dec 1, 2024

So you don't have typed linting with ESLint 8? Could you try whether that works?

No, this is the configuration I'm currently using. I'm in the process of migrating from ESLint 8 to ESLint 9, and with ESLint 8, everything was working fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants