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

eslint: @typescript-eslint error when add some rules #123

Open
troy351 opened this issue Jul 15, 2022 · 17 comments
Open

eslint: @typescript-eslint error when add some rules #123

troy351 opened this issue Jul 15, 2022 · 17 comments
Labels
documentation Improvements or additions to documentation

Comments

@troy351
Copy link

troy351 commented Jul 15, 2022

  • Create vue 2 project using following config
    QQ截图20220715152725

  • npm install

  • add rules inside .eslintrc.cjs

    rules: {
        "@typescript-eslint/prefer-optional-chain": "error"
    }
  • npm run lint

  • terminal error

    Error: Error while loading rule '@typescript-eslint/prefer-optional-chain': You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser.

FYI.
Adding parserOptions: { project: ["tsconfig.json"] } to .eslintrc.cjs won't help.
Maybe caused by eslint-plugin-vue or @typescript-eslint

@troy351
Copy link
Author

troy351 commented Jul 18, 2022

@haoqunjiang
Copy link
Member

This is kinda complicated…

I've got a working configuration:

.eslintrc.cjs:

/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");

module.exports = {
  root: true,
  extends: [
    "plugin:vue/vue3-essential",
    "eslint:recommended",
    "@vue/eslint-config-typescript/recommended",
    "@vue/eslint-config-prettier",
  ],
  rules: {
    "@typescript-eslint/prefer-optional-chain": "error",
  },
  parserOptions: {
    parser: "@typescript-eslint/parser",
    project: "./tsconfig.json",
  },
  overrides: [
    {
      files: ["vite.config.ts", ".eslintrc.cjs"],
      parserOptions: {
        parser: "@typescript-eslint/parser",
        project: "./tsconfig.config.json",
      },
    },
  ],
};

And add ".eslintrc.cjs" to the "include" array in tsconfig.config.json.


The trick here is that we can only have a single parser when project is used, thus the parser object set in @vue/eslint-config-typescript must be overriden https://github.com/vuejs/eslint-config-typescript/blob/75a6bde42c6aadc805d01f23bed23c0a9f2e4ada/index.js#L9-L17

And since we use solution-style tsconfigs in the project, some files in the project aren't covered by the root tsconfig.json, so we need to configure overrides for them. In this case, it's vite.config.ts and .eslintrc.cjs.

@haoqunjiang haoqunjiang added the documentation Improvements or additions to documentation label Jul 19, 2022
@troy351
Copy link
Author

troy351 commented Jul 19, 2022

It works, thanks!
Should this be in doc or as a built-in?

@troy351
Copy link
Author

troy351 commented Jul 19, 2022

It seems tsx failed to parse

<script lang="tsx">
import { defineComponent } from "vue";

export default defineComponent({
  render() {
    return <div></div>; // Parsing error: Type expected.
  },
});
</script>

@haoqunjiang
Copy link
Member

Yeah, currently it seems not possible to use project with script lang="tsx" in .vue files:

parserOptions.ecmaFeatures.jsx

  • ...
  • For "unknown" extensions (.md, .vue):
    • If parserOptions.project is not provided:
      • The setting will be respected.
    • If parserOptions.project is provided (i.e. you are using rules with type information):
      • always parsed as if this is false

https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/README.md#parseroptionsecmafeaturesjsx

@troy351
Copy link
Author

troy351 commented Jul 20, 2022

So it's impossible to make everything works for now?
I may disable those @typescript-eslint rules that requires project.

@haoqunjiang
Copy link
Member

I'm afraid so 🙁

@troy351
Copy link
Author

troy351 commented Jul 20, 2022

It was the limitation of typescript-eslint or eslint-plugin-vue or eslint itself?
If we can specify project for parserOptions.parser.ts, the problem maybe solved. But we can't as vuejs/vue-eslint-parser#104 (comment) said.

"parserOptions": {
        "parser": {
            "ts": "@typescript-eslint/parser",
            "<template>": "espree"
        }
    }

@haoqunjiang
Copy link
Member

I'm not sure.
But from the description, that it works without project, I guess it's a limitation of TypeScript itself.

Because TypeScript never supports custom file extensions well. For example, to make TypeScript work well with .vue files, we have to use a custom command-line tool: https://github.com/johnsoncodehk/volar/tree/master/packages/vue-tsc

Maybe @typescript-eslint can make it work by using the vue-tsc version of the TypeScript language service instead of the official one. But it's only my guess; I'm not familiar with either tool's actual implementation.

@troy351
Copy link
Author

troy351 commented Jul 20, 2022

What a pity, disable rule @typescript-eslint/prefer-optional-chain could be the most acceptable result.

Should I leave this issue open?

@haoqunjiang
Copy link
Member

Yeah, let's leave it open until I find a better place to document this limitation.

@troy351
Copy link
Author

troy351 commented Jul 21, 2022

Oh I forgot to mention that I used to use the old version @vue/[email protected] with [email protected] and it worked.
Though new features like defineProps are not recognized.

/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')

module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    'plugin:vue/essential',
    'eslint:recommended',
    '@vue/typescript/recommended', // this line was changed
    '@vue/eslint-config-prettier',
  ],
  rules: {
    '@typescript-eslint/prefer-optional-chain': 'error',
  },
}

@haoqunjiang
Copy link
Member

Oh I forgot to mention that I used to use the old version @vue/[email protected] with [email protected] and it worked.

It might be caused by typescript-eslint/typescript-eslint#4430 that triggers an undefined behavior in .vue files typescript-eslint/typescript-eslint#4755 (comment)

@haoqunjiang
Copy link
Member

FYI, I just created a @vue/eslint-config-standard-with-typescript package.
https://github.com/vuejs/eslint-config-standard/tree/main/packages/eslint-config-standard-with-typescript#readme

By default it only supports <script lang="ts"> in .vue, but you can opt-in to use other langs (not encouraged).
You can take that as a reference.

I plan to do similar refactors in @vue/eslint-config-airbnb and @vue/eslint-config-typescript later, but that would require much more time, because there are too many rules.

@troy351
Copy link
Author

troy351 commented Jul 22, 2022

There are many other rules require project to be set, you can search getParserServices usage inside https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin/src/rules to get the full list :)

@wmelton
Copy link

wmelton commented Dec 27, 2022

This isn't an exact solution for vue.js, but for anyone coming here from search looking to solve this problem for ts-node or node based typescript, I was able to solve the "You have used a rule which requires parserServices to be generated" error as follows (local setup: node 18-lts):

Add tsconfig.json and .eslintrc.js to your .eslintignore. If on vscode, you may want to add .vscode/settings.json as well.

Then in your .eslintrc file, add a settings prop and here is the config I am using (you likely do not need all the plugins I am using):

{
  "parser": "@typescript-eslint/parser",
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "plugin:import/recommended",
    "plugin:eslint-comments/recommended",
    "plugin:jsonc/recommended-with-jsonc"],
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["unicorn","@typescript-eslint"],
  "settings": {
    "import/resolver": {
      "node": { "extensions": [".js", ".mjs", ".ts", ".d.ts"] },
      "typescript": {
        "project": "./tsconfig.json"
      }
    }
  },
 "rules" : { ... }
}

This does not follow any instructions or guides I have found via Google, and yet it is the only solution I've found that actually works.

Your mileage may vary, but this worked for me. Also, remember to restart eslint after making this change (cmd+shift+p and then restart eslint)

@hmt
Copy link

hmt commented Jan 23, 2023

just another fyi, if you have this working but the error crops up anyway, make sure that you have a <script></script> part in your sfc, even if it's empty.

ngseke added a commit to ngseke/iphone-price that referenced this issue Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

4 participants