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

False positives when using with Vue SFC #883

Closed
IlCallo opened this issue Aug 19, 2019 · 16 comments · Fixed by #1083
Closed

False positives when using with Vue SFC #883

IlCallo opened this issue Aug 19, 2019 · 16 comments · Fixed by #1083
Labels
bug Something isn't working help wanted Extra attention is needed package: parser Issues related to @typescript-eslint/parser

Comments

@IlCallo
Copy link

IlCallo commented Aug 19, 2019

What code were you trying to parse?
I'm using Quasar (Vue based, using SFCs) and there seems to be some kind of incompatibility between typescript-eslint/parser and vue-eslint-parser.

Related
vuejs/eslint-plugin-vue#944
vuejs/vue-eslint-parser#55

What did you expect to happen?
Linting working normally even in .vue files, given that it kind-of worked (with some limitations) pre v2.

What actually happened?
All .vue files show a low level Parsing error: '>' expected error.
Most rules somewhat related to JS/TS into templates linting will also fail.
In my case every v-if, v-on and v-bind usage generate an error corresponding to the usage of that directive.

Es.
image

Versions

package version
@typescript-eslint/parser 2.0.0
vue-eslint-parser 6.0.4
eslint-plugin-vue 5.2.3
TypeScript 3.5.3
ESLint 6.2.0
node 10.15.3
npm 6.4.1
yarn 1.16.0
@IlCallo IlCallo added package: parser Issues related to @typescript-eslint/parser triage Waiting for maintainers to take a look labels Aug 19, 2019
@bradzacher
Copy link
Member

could you please post your tsconfig and eslint config as well?

We've got tests for vue SFC and they're passing, so there might be something you're missing from the config.

@bradzacher bradzacher added awaiting response Issues waiting for a reply from the OP or another party and removed triage Waiting for maintainers to take a look labels Aug 19, 2019
@IlCallo
Copy link
Author

IlCallo commented Aug 19, 2019

.eslintrc.js
module.exports = {
  root: true,

  // Rules order is important, please avoid shuffling them
  extends: [
    // Base ESLint recommended rules
    'eslint:recommended',

    // ESLint typescript rules
    // See https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking',

    // `plugin:vue/essential` by default, consider switching to `plugin:vue/strongly-recommended`
    //  or `plugin:vue/recommended` for stricter rules.
    // See https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
    'plugin:vue/recommended',

    // Usage with Prettier, provided by 'eslint-config-prettier'.
    // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage-with-prettier
    'prettier',
    'prettier/@typescript-eslint',
    'prettier/vue',
  ],

  plugins: [
    // Required to apply rules which need type information
    '@typescript-eslint',
    // Required to lint *.vue files
    // See https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file
    'vue',
    // Prettier has not been included as plugin to avoid performance impact
    // See https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
    // Add it as an extension
  ],

  // Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working
  // See https://eslint.vuejs.org/user-guide/#how-to-use-custom-parser
  // `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
  parserOptions: {
    // Needed to make the parser take into account 'vue' files
    // See https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#configuration
    extraFileExtensions: ['.vue'],
    parser: '@typescript-eslint/parser',
    project: './tsconfig.json',
    sourceType: 'module',
  },

  env: {
    browser: true,
  },

  globals: {
    ga: true, // Google Analytics
    cordova: true,
    __statics: true,
    process: true,
  },

  // add your custom rules here
  rules: {
    'prefer-promise-reject-errors': 'off',
    quotes: ['warn', 'single'],

    // allow console.log during development only
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    // allow debugger during development only
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',

    // Custom
    'vue/component-name-in-template-casing': ['error', 'kebab-case'],
    '@typescript-eslint/explicit-function-return-type': 'off',
  },
};
tsconfig.json
{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": ".",
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "outDir": "./dist",
    "sourceMap": true,
    "strict": true,
    "target": "es6"
  },
  "exclude": ["node_modules", "dist"]
}

Seems to me that I don't have anything "less" to your test config, but I have a lot more.

Quoting from one of the maintainers of eslint-plugin-vue the possible problem:

vue-eslint-parser tries to pass the script part of the vue file to @typescript-eslint/parser, but @typescript-eslint/parser may return the analysis result of another source code.
This is the source code contained in the cache used for parsing other files.
The source code contained in this cache is the result of all the lines in the vue file.
Since the analysis by @typescript-eslint/parser fails, the vue file is reported as a parsing error.

@bradzacher bradzacher mentioned this issue Aug 20, 2019
3 tasks
@renataogarcia
Copy link

@IlCallo Not sure if it's the same issue, but I was getting lot's of Parsing error errors too, and managed to get rid of them by setting parserOptions.ecmaFeatures.jsx = false.

@IlCallo
Copy link
Author

IlCallo commented Aug 29, 2019

Nope, didn't help

@yoyo930021
Copy link
Contributor

I have the same problem.
The problem will only appear when I lint multiple files.

@jaredburkeen
Copy link

I'm having the same issue as well.
Did some testing and I also only have the issue when linting multiple files.
Are there any known workarounds to this issue?

@bradzacher bradzacher added help wanted Extra attention is needed bug Something isn't working labels Sep 30, 2019
@bradzacher
Copy link
Member

I haven't had time to look into it. I'd love it if someone that's familiar with Vue could help look into it.
It's not a framework that I have ever used, so I don't really have enough free time to learn the framework as well as looking into the problem.

As a workaround, you can set parserOptions.createDefaultProgram = false to use the old (unsafe) codepath.

@IlCallo
Copy link
Author

IlCallo commented Oct 7, 2019

vuejs/eslint-plugin-vue#970
Similar to this one.
I'll try to reach out for Vue core devs to bring their attention on this problem.

@Mister-Hope
Copy link

Mister-Hope commented Oct 14, 2019

I got problems too, it seems to caused by the cache files. see here

I am using this plugin for quite a long time. And this error is always appeared.
Maybe you should call the vue-cli teams.

@Djaler
Copy link

Djaler commented Oct 16, 2019

@yyx990803, @sodatea, @Akryum, @LinusBorg, can you help us?

@yyx990803
Copy link

/cc @mysticatea

@yoyo930021
Copy link
Contributor

yoyo930021 commented Oct 18, 2019

The PR #1083 can fix this issue.

@bradzacher
Copy link
Member

It'd be great if people could create a local build of that PR and link it in to see if it covers all of the use cases.
Nothing complicated - checkout the branch at that PR (or use github to download a zip), cd in, yarn install, then grab the dist folder in packages/typescript-estree and dump it into your repo's local node_modules/@typescript-eslint/typescript-estree folder.
Running a lint will use the patched code, and we can verify the fix before merging it in.

@yoyo930021 - I'm just trepidatious because we've had many changes and tests that pass locally that don't work for vue users IRL.

@trebler
Copy link

trebler commented Oct 18, 2019

@bradzacher, I can verify that PR #1083 does resolve eslint issues (very similar to those of @IlCallo) I have experienced when not setting createDefaultProgram: true.

Here is my .eslintrc.js:

const path = require('path');

module.exports = {
  root: true,
  env: {
    commonjs: true
  },
  plugins: [
    '@typescript-eslint',
    'vue'
  ],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking',
    'plugin:vue/recommended',

    "plugin:prettier/recommended",
    'prettier/@typescript-eslint',
    'prettier/vue'
  ],
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/no-inferrable-types': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    '@typescript-eslint/no-unused-vars': ['warn', { 'argsIgnorePattern': '^_' }],
    '@typescript-eslint/no-empty-function': ['warn'],
    eqeqeq: 'warn'
  },
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 2018,
    sourceType: 'module',
    project: path.resolve(__dirname, './tsconfig.json'),
    extraFileExtensions: ['.vue'],
  }
};

@jaredburkeen
Copy link

@bradzacher, I've also verified that PR #1083 resolves my eslint Vue issues.

Here is my .eslintrc.js:

module.exports = {
    "env": {
        "browser": true,
        "es6": true,
        "node": true
    },
    "parser": "vue-eslint-parser",
    "parserOptions": {
        "parser": "@typescript-eslint/parser",
        "project": "tsconfig.json",
        "sourceType": "module",
        "extraFileExtensions": [".vue"]
    },
    "plugins": [
        "@typescript-eslint",
        "vue",
        "security"
    ],
    "extends": ["plugin:vue/base"],
    "rules": {
        // Typescript rules
        "@typescript-eslint/adjacent-overload-signatures": "error",
        "@typescript-eslint/array-type": "error",
        "@typescript-eslint/ban-types": "error",
        "@typescript-eslint/class-name-casing": "error",
        "@typescript-eslint/explicit-member-accessibility": [
            "error",
            {
                "overrides": {
                    "constructors": "off"
                }
            }
        ],
        "@typescript-eslint/indent": [
            "error",
            4,
            {
                "FunctionDeclaration": {
                    "parameters": "first"
                },
                "SwitchCase": 1
            }
        ],
        "@typescript-eslint/interface-name-prefix": "off",
        "@typescript-eslint/consistent-type-assertions": "error",
        "@typescript-eslint/no-empty-interface": "error",
        "@typescript-eslint/no-explicit-any": "off",
        "@typescript-eslint/no-misused-new": "error",
        "@typescript-eslint/no-namespace": "error",
        "@typescript-eslint/no-parameter-properties": "off",
        "@typescript-eslint/triple-slash-reference": "error",
        "@typescript-eslint/no-use-before-declare": "off",
        "@typescript-eslint/no-var-requires": "error",
        "@typescript-eslint/prefer-for-of": "error",
        "@typescript-eslint/prefer-function-type": "error",
        "@typescript-eslint/consistent-type-definitions": "error",
        "@typescript-eslint/prefer-namespace-keyword": "error",
        "@typescript-eslint/type-annotation-spacing": "error",
        "@typescript-eslint/unified-signatures": "error",
        "@typescript-eslint/member-ordering": "error",
        "@typescript-eslint/no-empty-function": "error",

        // Javascript rules
        "arrow-body-style": "error",
        "arrow-parens": [
            "off",
            "as-needed"
        ],
        "complexity": "off",
        "constructor-super": "error",
        "curly": "error",
        "dot-notation": "error",
        "eol-last": "error",
        "guard-for-in": "error",
        "max-classes-per-file": [
            "error",
            1
        ],
        "max-len": ["error", { "code": 120 }],
        "new-parens": "error",
        "no-bitwise": "error",
        "no-caller": "error",
        "no-cond-assign": "error",
        "no-console": "error",
        "no-debugger": "error",
        "no-empty": "error",
        "no-eval": "error",
        "no-fallthrough": "off",
        "no-invalid-this": "off",
        "no-multiple-empty-lines": [
            "error",
            {
                "max": 2
            }
        ],
        "no-new-wrappers": "error",
        "no-throw-literal": "error",
        "no-undef-init": "error",
        "no-unsafe-finally": "error",
        "no-unused-labels": "error",
        "no-var": "error",
        "object-shorthand": "error",
        "prefer-const": "error",
        "quote-props": [
            "error",
            "consistent-as-needed"
        ],
        "radix": "off",
        "space-before-function-paren": [
            "error",
            {
                "anonymous": "never",
                "asyncArrow": "always",
                "named": "never"
            }
        ],
        "use-isnan": "error",
        "valid-typeof": "off",
        "spaced-comment": [
            "error",
            "always",
            {
                "markers": ["/"]
            }
        ],
        "no-shadow": "error",
        "quotes": [
            "error",
            "single",
        ],
        "semi": "error",
        "no-trailing-spaces": "error",
        "comma-dangle": [
            "error",
            "always-multiline"
        ],
        "eqeqeq": [
            "error",
            "always",
            {
                "null": "ignore"
            }
        ],

        // ESLint rules for Node Security
        // https://github.com/nodesecurity/eslint-plugin-security
        "security/detect-buffer-noassert": "warn",
        "security/detect-child-process": "warn",
        "security/detect-disable-mustache-escape": "warn",
        "security/detect-eval-with-expression": "warn",
        "security/detect-new-buffer": "warn",
        "security/detect-no-csrf-before-method-override": "warn",
        "security/detect-non-literal-fs-filename": "warn",
        "security/detect-non-literal-regexp": "warn",
        "security/detect-non-literal-require": "warn",
        // We currently get warnings for the disabled line.
        // We'll investigate the specific issues in the future.
        //"security/detect-object-injection": "warn",
        "security/detect-possible-timing-attacks": "warn",
        "security/detect-pseudoRandomBytes": "warn",
        "security/detect-unsafe-regex": "warn",
    }
};

@IlCallo
Copy link
Author

IlCallo commented Oct 22, 2019

Late to the party (pretty busy on a project), but I confirm too that issues are gone!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working help wanted Extra attention is needed package: parser Issues related to @typescript-eslint/parser
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants