eslint-plugin-vue
eslint-plugin-vue copied to clipboard
[vue/no-unused-properties] bug detecting properties defined within setup() and used with template option
Checklist
- [x] I have tried restarting my IDE and the issue persists.
- [x] I have read the FAQ and my problem is not listed.
Tell us about your environment
- ESLint version: 8.8.0
- eslint-plugin-vue version: 8.6.0
- Node version: v14.17.0
- Operating System: macOS Monterey 12.2.1 (M1 processor)
Please show your full configuration:
module.exports = {
root: true,
parserOptions: {
parser: '@babel/eslint-parser',
requireConfigFile: false,
sourceType: 'module',
},
env: {
browser: true,
jest: true
},
extends: [
'airbnb-base',
'plugin:vue/recommended'
],
plugins: [
'vue',
'simple-import-sort'
],
globals: {
ga: true,
cordova: true,
__statics: true,
context: true,
fixture: true
},
settings: {
'import/resolver': {
alias: {
map: [
['src', './src'],
['shared', './shared']
],
extensions: ['.vue', '.js', '.json']
}
}
},
rules: {
// allow async-await
'generator-star-spacing': 'off',
'class-methods-use-this': 'off',
'no-implicit-coercion': ['error', {
'disallowTemplateShorthand': true,
'boolean': true,
'number': true,
'string': true
}],
// variable names must be min 2 characters
'id-length': ['error', {
'min': 2,
'properties': 'never',
'exceptions': ['_', 'h']
}],
'max-len': ['error', {
code: 100,
ignorePattern: '(`|\\$\\{)',
ignoreUrls: true,
ignoreComments: false,
ignoreRegExpLiterals: true,
ignoreStrings: true,
ignoreTemplateLiterals: true,
}],
// force import order of external > shared > src > local modules
'simple-import-sort/imports': ['error', {
groups: [
// Node.js builtins. You could also generate this regex if you use a `.js` config.
// For example: `^(${require("module").builtinModules.join("|")})(/|$)`
[
"^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)",
],
// Packages
["^@?\\w"],
// shared imports
["^(shared)(/.*|$)"],
// src imports
["^(src)(/.*|$)"],
// Internal imports.
// ["^(@|@company|@ui|components|utils|config|vendored-lib)(/.*|$)"],
// Side effect imports.
["^\\u0000"],
// Parent imports. Put `..` last.
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
// Other relative imports. Put same-folder imports and `.` last.
["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"],
// Style imports.
["^.+\\.s?css$"],
],
}],
// allow mutating only certain variables
'no-param-reassign': ['error', {
props: true,
ignorePropertyModificationsFor: [
'acc', // for reduce accumulators
'e', // for e.returnvalue
'ctx', // for Koa routing
'req', // for Express requests
'request', // for Express requests
'res', // for Express responses
'response', // for Express responses
'state', // for vuex mutations
]
}],
// disable using quasar utils -- should be using date-fns and lodash
'no-restricted-imports': ['error', {
'paths': [
{
'name': 'quasar',
'importNames': ['date'],
'message': 'Please use individual date-fns imports instead of quasar\'s date utilities.'
},
{
'name': 'quasar',
'importNames': ['debounce'],
'message': 'Please use lodash/debounce instead of quasar\'s debounce utility.'
},
],
}],
'padding-line-between-statements': [
'error',
{ blankLine: 'always', prev: '*', next: 'block' },
{ blankLine: 'always', prev: 'block', next: '*' },
{ blankLine: 'always', prev: '*', next: 'block-like' },
{ blankLine: 'always', prev: 'block-like', next: '*' },
{ blankLine: 'never', prev: 'case', next: 'case' },
{ blankLine: 'always', prev: '*', next: 'return' },
],
// allow paren-less arrow functions
'arrow-parens': 0,
'one-var': 0,
'import/first': 0,
'import/named': 2,
'import/namespace': 2,
'import/default': 2,
'import/export': 2,
'import/extensions': 0,
'import/no-unresolved': 0,
'import/no-extraneous-dependencies': 0,
'semi': [2, 'always'],
'no-debugger': 2,
// force PascalCase for components
'vue/component-name-in-template-casing': ['error', 'PascalCase', {
'registeredComponentsOnly': false,
}],
// single prop, single line
'vue/first-attribute-linebreak': ['error', {
'singleline': 'beside',
}],
// force ordering of SFC top level tags
'vue/component-tags-order': ['error', {
'order': ['template', 'script', 'style']
}],
// component name must be defined and match filename
'vue/match-component-file-name': ['error', {
'extensions': ['vue'],
'shouldMatchCase': true
}],
// prevent unused props, data, computed, methods in components
'vue/no-unused-properties': ['error', {
'groups': [
// 'props', // TODO: check back if they fix it for props bound with v-bind or used within setup method or passed to composable
// 'data',
'computed',
'methods',
'setup',
],
// 'deepData': true,
'ignorePublicMembers': true,
}],
// no empty script/template/style blocks in SFC
'vue/no-empty-component-block': 2,
// TODO: fix all instances where props are mutated
'vue/no-mutating-props': 0,
// TODO: rename all single word components
'vue/multi-word-component-names': 0,
}
};
What did you do?
This is a very dumbed down version that illustrates the issue. I am basically trying to test a composable with Jest and vue-test-utils (the composable setup code is omitted here as it isn't relevant to the issue itself) but the idea is we create a component to use within the tests that includes the composable and some other setup code like the snippet below.
const mockComponent = defineComponent({
setup() {
const someRef = ref(null);
return {
someRef,
};
},
template: `
<div ref="someRef" />
`,
});
What did you expect to happen?
Eslint reports no error for vue/no-unused-properties when using properties within the template option of a component.
What actually happened?
When defining the template option and using a ref defined within setup, I get the following error:
error 'someRef' of property returned from `setup()` found, but never used vue/no-unused-properties
even though that someRef is definitely used within the template string of the component options.
Repository to reproduce this issue Unfortunately closed source, but seems simple to reproduce.