Skip to content

Vue SFCs lint slowly when parserOptions.project is set #1111

@andrewisaburden

Description

@andrewisaburden

Tell us about your environment

  • ESLint version: 6.8.0
  • eslint-plugin-vue version: 6.2.2
  • Node version: 10.15.2

Please show your full configuration:

module.exports = {
  'root': true,
  'env': {
    jest: true,
    node: true,
  },
  'extends': [
    'plugin:vue/recommended',
    '@vue/typescript',
    '@COMPANYNAME/typescript-vue',
    'plugin:import/typescript'
  ],

  'globals': {
    '__dirname': false,
    'process': false,
    'require': false,
  },
  'settings': {
    'import/parsers': {
      '@typescript-eslint/parser': [ '.ts']
    }
  },

  'plugins': [
    'eslint-comments',
    'import',
    'promise',
    '@typescript-eslint',
    'vue',
  ],

  'parser': 'vue-eslint-parser',
  'parserOptions': {
    'emcaFeatures': {
      'impliedStrict': true,
      'jsx': false,
    },
    'sourceType': 'module',
    'ecmaVersion': 2018,
    'extraFileExtensions': ['.vue'],
    'project': './tsconfig.json',
  },

  'rules': {
    '@typescript-eslint/no-unnecessary-qualifier': 'off',
    '@typescript-eslint/no-unnecessary-type-assertion': 'off',
    '@typescript-eslint/promise-function-async': 'off',
    'import/extensions': 'off',
    'import/named': 'off',
    'import/no-unresolved': 'off',
    'import/namespace': 'off',
    'import/no-cycle': 'off',
    'import/no-deprecated': 'off',
    'object-curly-spacing': ['error', 'never'],
    'import/group-exports': 'off',
    'no-use-before-define': 'off',
    '@typescript-eslint/no-use-before-define': 'off',
    'no-undefined': 'off',
    '@typescript-eslint/no-triple-slash-reference': 'off',
    '@typescript-eslint/no-object-literal-type-assertion': 'off',
    'import/no-namespace': 'off',
    'import/no-default-export': 'off',
    '@typescript-eslint/member-ordering': 'off',
    '@typescript-eslint/prefer-interface': 'off',
    'max-len': 'off',
    '@typescript-eslint/camelcase': 'off',
    'max-depth': 'off',
    'prefer-destructuring': 'off',
    'import/no-named-default': 'off',
    '@typescript-eslint/generic-type-naming': 'off',
    'no-bitwise': 'off',
    'func-names': 'off',
    'multiline-ternary': 'off',
    'import/exports-last': 'off',
    'no-return-await': 'off',
    'no-return-assign': 'off',
    'vue/require-v-for-key': 'off',
    'no-mixed-operators': 'off',
    'require-unicode-regexp': 'off',
    'vue/no-parsing-error': 'off',
    'vue/this-in-template': 'off',
    'vue/no-duplicate-attributes': 'off',
    'vue/no-use-v-if-with-v-for': 'off',
    'no-negated-condition': 'off',
    'max-statements-per-line': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    'eqeqeq': 'warn',
    '@typescript-eslint/ban-ts-ignore': 'warn',
    'consistent-return': 'warn',
    'vue/no-v-html': 'off',
    'promise/prefer-await-to-then': 'off',
    '@typescript-eslint/no-unused-vars': 'off',
    'vue/valid-v-else': 'off',
    'import/no-named-as-default-member': 'off',
    '@typescript-eslint/restrict-plus-operands': 'off',
    'import/no-commonjs': 'off',
    'no-underscore-dangle': 'off',
    'lines-between-class-members': 'off',
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
  },
};

tsconfig.json:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": false,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "allowJs": false,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "jest"
    ],
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ],
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.vue",
  ],
  "exclude": [
    "node_modules"
  ]
}

What did you do?

Any vue SFC file

What did you expect to happen?
I expect the lint time to be quicker.

What actually happened?
The lint time was slow.

When I run cross-env TIMING=1 DEBUG=eslint:cli-engine vue-cli-service lint --no-fix with the above .eslintrc.json, the amount of time it takes to lint the full project is around 65 seconds.

When I set parserOptions.project to null in the above .eslintrc.json, the amount of time it takes to lint the full project is around 20 seconds.

In the first run, the debug info shows ~3seconds for the first Vue file. Thereafter, .vue files are typically around 300-500ms, and .ts files are around 10-50ms.

In the second run, the debug info shows ~3 seconds for the first Vue file still. Thereafter, .vue files are typically around 50-100ms, and .ts files are around 10-50ms.

The rule % split and time from TIMING=1 looks approximately the same:

Run 1:

Rule                              | Time (ms) | Relative
:---------------------------------|----------:|--------:
vue/attribute-hyphenation         |  1629.467 |    20.5%
import/no-self-import             |   757.896 |     9.5%
@typescript-eslint/indent         |   725.273 |     9.1%
vue/script-indent                 |   495.819 |     6.2%
import/default                    |   446.477 |     5.6%
import/no-useless-path-segments   |   333.298 |     4.2%
no-redeclare                      |   264.812 |     3.3%
import/no-extraneous-dependencies |   202.248 |     2.5%
import/order                      |   173.132 |     2.2%
import/no-nodejs-modules          |   149.286 |     1.9%

Run 2:

Rule                              | Time (ms) | Relative
:---------------------------------|----------:|--------:
vue/attribute-hyphenation         |  1551.624 |    20.3%
import/no-self-import             |   808.449 |    10.6%
@typescript-eslint/indent         |   695.213 |     9.1%
import/default                    |   485.125 |     6.4%
vue/script-indent                 |   360.806 |     4.7%
import/no-useless-path-segments   |   343.282 |     4.5%
no-redeclare                      |   236.580 |     3.1%
import/no-extraneous-dependencies |   218.869 |     2.9%
import/order                      |   180.786 |     2.4%
import/no-nodejs-modules          |   157.692 |     2.1%

If this was all it took to speed up the project, then I wouldn't bother mentioning this issue. However, there are now three new errors caught by the linter, which appear to all be false positives.

error: Parsing error: Identifier expected at src/components/admin/members/edit/components/MemberProfile.vue:173:88:
> 173 |     @memberStore.Getter(memberGetters.ISSUES) issues: Record<string, string[]>;
      |                                                              ^
error: Parsing error: '}' expected at src/components/admin/synchronisation/synchronisation_errors/components/ListSynchronisationErrors.vue:229:46:
  227 | 
  228 |     async fetchSynchronisationErrors() {
> 229 |       synchronisationErrorsStore.setBusy(true);
      |                                              ^
error: Parsing error: Expression expected at src/components/auth/PasswordReset.vue:125:6:
  123 | 
  124 |     get token() {
> 125 |       if (!this.$route.query || !this.$route.query.token) return '';
      |      ^

Is it necessary for parserOptions.project to be passed to the parser? If so, is it possible to speed up the time spent parsing each .vue SFC file?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions