vuejs / eslint-plugin-vue

Official ESLint plugin for Vue.js
https://eslint.vuejs.org/
MIT License
4.47k stars 664 forks source link

Add ESLint Processor to differentiate Vue SFC `<script>` `lang`s to apply different rules, parsers, etc. #1910

Open DrJume opened 2 years ago

DrJume commented 2 years ago

Tell us about your environment

The problem you want to solve.

It would be awesome to be able to filter .vue with lang="ts" in ESLint overrides. Currently, it seems to be not possible.

But if there was an ESLint Processor for Vue, it would be possible to filter for the <script> lang (or even <template>?): https://eslint.org/docs/user-guide/configuring/plugins#specifying-processor.

Your take on the correct solution to problem.

Implement an ESLint Processor for Vue SFCs. Something like the following could be possible?

.eslintrc.js

{
    plugin: 'vue',
    processor: 'vue/sfc-processor',
    parser: 'vue-eslint-parser', // why not 'vue/parser'?
    overrides: [
        {
            files: ['*.vue'],
            rules: {
                // ...
            }
        },
        {
            files: ['**/*.vue/*.ts'],
            parser: '@typescript-eslint/parser',
            extends: [
                'plugin:@typescript-eslint/recommended',
                'plugin:@typescript-eslint/recommended-requiring-type-checking',
            ]
        }
    ]
}

Additional context

Addresses:

DrJume commented 11 months ago

Just wanted to ask, if this issue is still relevant. Will this be implemented in v10 or is it too complex? Is there anything I could help with?

ota-meshi commented 11 months ago

Using ESLint's processor gives the code block a virtual filename that doesn't exist, making it impossible to provide TypeScript type information. So for now I don't think using a processor will work.

For now, if you want to configure a rule with only lang="ts", I think the only way is to analyze the file yourself.

e.g.

const glob = require('fast-glob');

const scriptTs = 'lang="ts"';
const vueTsFiles = glob
  .sync(['**/*.vue', '!**/node_modules/**'], {cwd: path.resolve()})
  .filter((filePath) => fs.readFileSync(filePath, 'utf8').includes(scriptTs));

module.exports = {
  overrides: [
    ...
    {
      files: vueTsFiles,
      parser: 'vue-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser',
        ...
      },
      extends: [...],
      rules: {...}
    }
  ]
};
DrJume commented 11 months ago

Thank you very much for your thorough answer 💚

languanghao commented 6 months ago

Using ESLint's processor gives the code block a virtual filename that doesn't exist, making it impossible to provide TypeScript type information. So for now I don't think using a processor will work.

For now, if you want to configure a rule with only lang="ts", I think the only way is to analyze the file yourself.

e.g.

const glob = require('fast-glob');

const scriptTs = 'lang="ts"';
const vueTsFiles = glob
  .sync(['**/*.vue', '!**/node_modules/**'], {cwd: path.resolve()})
  .filter((filePath) => fs.readFileSync(filePath, 'utf8').includes(scriptTs));

module.exports = {
  overrides: [
    ...
    {
      files: vueTsFiles,
      parser: 'vue-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser',
        ...
      },
      extends: [...],
      rules: {...}
    }
  ]
};

Thank you for your answer, it works!