vuejs / eslint-plugin-vue

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

Incorrect `prefer-import-from-vue` for values that are not exported by `vue` #2354

Open jods4 opened 9 months ago

jods4 commented 9 months ago

Checklist

Tell us about your environment

Please show your full configuration:

{
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "plugin:vue/vue3-recommended"
  ],
  "parserOptions": {
    "parser": "@typescript-eslint/parser",
    "ecmaVersion": 2020,
    "ecmaFeatures": {
      "jsx": false
    },
    "sourceType": "module"
  },
  "rules": {
    "@typescript-eslint/ban-ts-comment": "off",
    "@typescript-eslint/ban-types": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-empty-function": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/no-inferrable-types": "off",
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "varsIgnorePattern": "^_",
        "argsIgnorePattern": "^_"
      }
    ],
    "prefer-const": [
      "error",
      {
        "destructuring": "all"
      }
    ],
    "vue/html-self-closing": [
      "error",
      {
        "html": {
          "void": "any",
          "normal": "any"
        }
      }
    ],
    "vue/max-attributes-per-line": "off",
    "vue/no-dupe-keys": "off",
    "vue/no-mutating-props": "off",
    "vue/require-default-prop": "off",
    "vue/require-v-for-key": "off",
    "vue/singleline-html-element-content-newline": "off",
    "vue/valid-v-slot": "off",
    "vue/attributes-order": "off",
    "vue/attribute-hyphenation": "off",
    "vue/multi-word-component-names": "off",
    "vue/html-indent": "off"
  }
}

What did you do?

import { trigger, track } from "@vue/reactivity"

What did you expect to happen? Nothing, that's fine code because vue itself does not export trigger nor track.

What actually happened? Error vue/prefer-import-from-vue suggesting to import those members from vue, which is impossible.

Suggested fix It's generally good practice to import from vue directly, so I'd like to keep this rule enabled. The rule should have a list of all vue exports and not trigger when the imported value is not one of them (false positive).

FloEdelmann commented 8 months ago

The rule should have a list of all vue exports and not trigger when the imported value is not one of them (false positive).

It will be quite tedious to update this list manually; maybe even separately per Vue version... Maybe adding an allow option would be easier and more maintainable?

jods4 commented 8 months ago

Managing the list manually would be tedious and error-prone, indeed.

Could this be automated during the build step of eslint-plugin-vue?

// During build:
import * as vue from "vue";
const jsArray = JSON.stringify(Object.keys(vue));
const virtualFile = `export vueExports = new Set(${jsArray})`;

// At runtime only raise error for imports that are found in `vueExports`
FloEdelmann commented 8 months ago

Yes, we already have several such update scripts. If you (or someone else) would like to implement this, feel welcome to do so :blush:

However, we need to think if the latest vue version's exports are always correct, or if we need to do this for every (minor?) version and then during runtime change the logic based on the available Vue version.

FloEdelmann commented 8 months ago

Hah, looks like we already have that list and update script :sweat_smile:

jods4 commented 8 months ago

I think using the latest version as the baseline for the linter is likely to be enough.

This is only a linter, if someone has an older version and gets a false positive or negative, it can be ignored. This should be exceedingly rare as: (1) most people do not import from @vue/* packages; (2) those exports don't vary much from release to another.

IMHO it's an improvement over the current situation which is always incorrect. Maybe it can be revised if a lot of issues are raised by users?

FloEdelmann commented 8 months ago

Sounds good to me :slightly_smiling_face: