vuejs / eslint-plugin-vue

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

`vue/no-undef-components` doesn't work with external scripts #2083

Closed matthew-dean closed 1 year ago

matthew-dean commented 1 year ago

Checklist

Tell us about your environment

Please show your full configuration:

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: ['plugin:vue/vue3-strongly-recommended', 'standard', 'plugin:storybook/recommended'],
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    extraFileExtensions: ['.vue']
  },
  rules: {
    /**
     * Okay tryyyying not to bikeshed here but I've never Standard JS's
     * formatting preference for space before in use before using StandardJS
     */
    'space-before-function-paren': ['error', {
      anonymous: 'never',
      named: 'never',
      asyncArrow: 'always'
    }],
    /** Let's us know if something is there that's undefined */
    'vue/no-undef-components': ['error', {
      ignorePatterns: ['RouterLink', 'RouterView']
    }],
    /**
     * Aligns with the Vue style guide.
     * @see https://v2.vuejs.org/v2/style-guide/?redirect=true#Component-name-casing-in-templates-strongly-recommended
     */
    'vue/component-name-in-template-casing': [
      'error',
      'PascalCase',
      {
        registeredComponentsOnly: false
      }
    ],
    /** Sensible rules for HTML vs custom components */
    'vue/html-self-closing': ['error', {
      html: {
        void: 'any',
        normal: 'never',
        component: 'always'
      }
    }]
  },
  overrides: [
    {
      files: ['*.ts', '.tsx', '.vue'],
      plugins: ['@typescript-eslint'],
      extends: [
        'plugin:vue/vue3-strongly-recommended',
        'standard-with-typescript'
      ],
      parserOptions: {
        parser: '@typescript-eslint/parser',
        project: './tsconfig.json',
        extraFileExtensions: ['.vue']
      },
      rules: {
        '@typescript-eslint/space-before-function-paren': ['error', {
          anonymous: 'never',
          named: 'never',
          asyncArrow: 'always'
        }],
        /**
         * Loosen some rules to not force as much code refactoring
         * See individual rules for what issues these can cause.
         */
        '@typescript-eslint/strict-boolean-expressions': 0,
        '@typescript-eslint/restrict-template-expressions': 0
      }
    },
    /** Storybook eslinting rules */
    {
      files: ['*.stories.ts'],
      rules: {
        '@typescript-eslint/consistent-type-assertions': 0
      }
    }
  ]
}

What did you do?

I have a file called Links.vue. It has a tag like:

<script lang="ts" src="../scripts/components/Links.ts"></script>

That component exports a component setup like:

export default {
  // ... stuff
  components: {
    MetadataTemplate
  }
}

However, when this rule is enabled and I use MetadataTemplate, I get: `The '' component has been used, but not defined.

This is definitely an error, as TypeScript / Volar is able to determine the type of MetadataTemplate in the <template> block.

What did you expect to happen? I expected defined components to be understood as defined, even if the script is referenced externally.

What actually happened?

The '<MetadataTemplate>' component has been used, but not defined.eslint[vue/no-undef-components](https://eslint.vuejs.org/rules/no-undef-components.html)

Repository to reproduce this issue

I spent a while trying to set up CodeSandbox with a working version of ESLint / Vite / TypeScript / Vue3 and an external code source, but CodeSandbox itself didn't seem to want to do this. So, maybe this issue will be auto-closed, but at least it'll be searchable by someone else?

FloEdelmann commented 1 year ago

ESLint does not have access to other file's contents, so this rule cannot work properly when referencing the script from another file. Volar / TypeScript on the other hand do have access to the whole project, but ESLint is separate.

FloEdelmann commented 1 year ago

Since there is nothing we can do, I'll close this issue.