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

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

Closed
andrewisaburden opened this issue May 4, 2020 · 3 comments
Closed

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

andrewisaburden opened this issue May 4, 2020 · 3 comments

Comments

@andrewisaburden
Copy link

andrewisaburden commented May 4, 2020

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?

@ota-meshi
Copy link
Member

I'm not familiar with typescript parsers. So I can't identify the cause of the slowdown in your environment. It looks like it's working fine in my environment. If you can improve, can you follow #1296.

@fisker
Copy link
Contributor

fisker commented Apr 15, 2021

I'm not going to open an new issue, but just want point out, the parser indeed slow, not only @typescript-eslint/parser but also @babel/eslint-parser, I didn't test espree because I can never use it in my vue projects. Maybe not about the js parser, just too much work to do when parsing Vue SFC.

Rule Time (ms) Relative
vue/eqeqeq 777.585 29.3%
no-unused-vars 265.170 10.0%
no-redeclare 173.047 6.5%
vue/valid-next-tick 94.810 3.6%
no-unmodified-loop-condition 80.609 3.0%
object-shorthand 67.060 2.5%
no-useless-return 54.703 2.1%
vue/no-side-effects-in-computed-properties 52.057 2.0%
vue/padding-line-between-blocks 51.834 2.0%
no-dupe-keys 48.061 1.8%

@yoyo930021
Copy link
Member

yoyo930021 commented Sep 30, 2022

Temp solution: vuejs/vue-eslint-parser#104 (comment)

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

4 participants