forked from vuejs/eslint-plugin-vue
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
vue/require-macro-variable-name
rule (vuejs#2198)
- Loading branch information
Showing
5 changed files
with
521 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
--- | ||
pageClass: rule-details | ||
sidebarDepth: 0 | ||
title: vue/require-macro-variable-name | ||
description: require a certain macro variable name | ||
--- | ||
# vue/require-macro-variable-name | ||
|
||
> require a certain macro variable name | ||
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge> | ||
- :bulb: Some problems reported by this rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). | ||
|
||
## :book: Rule Details | ||
|
||
This rule reports macro variables not corresponding to the specified name. | ||
|
||
<eslint-code-block :rules="{'vue/require-macro-variable-name': ['error']}"> | ||
|
||
```vue | ||
<!-- ✓ GOOD --> | ||
<script setup> | ||
const props = defineProps({ msg: String }) | ||
const emit = defineEmits(['update:msg']) | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
<eslint-code-block :rules="{'vue/require-macro-variable-name': ['error']}"> | ||
|
||
```vue | ||
<!-- ✗ BAD --> | ||
<script setup> | ||
const propsDefined = defineProps({ msg: String }) | ||
const emitsDefined = defineEmits(['update:msg']) | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :wrench: Options | ||
|
||
```json | ||
{ | ||
"vue/require-macro-variable-name": ["error", { | ||
"defineProps": "props", | ||
"defineEmits": "emit", | ||
"defineSlots": "slots", | ||
"useSlots": "slots", | ||
"useAttrs": "attrs" | ||
}] | ||
} | ||
``` | ||
|
||
- `defineProps` - The name of the macro variable for `defineProps`. default: `props` | ||
- `defineEmits` - The name of the macro variable for `defineEmits`. default: `emit` | ||
- `defineSlots` - The name of the macro variable for `defineSlots`. default: `slots` | ||
- `useSlots` - The name of the macro variable for `useSlots`. default: `slots` | ||
- `useAttrs` - The name of the macro variable for `useAttrs`. default: `attrs` | ||
|
||
### With custom macro variable names | ||
|
||
<eslint-code-block :rules="{'vue/require-macro-variable-name': ['error', { | ||
'defineProps': 'propsCustom', | ||
'defineEmits': 'emitCustom', | ||
'defineSlots': 'slotsCustom', | ||
'useSlots': 'slotsCustom', | ||
'useAttrs': 'attrsCustom' | ||
}]}"> | ||
|
||
```vue | ||
<script setup> | ||
const slotsCustom = defineSlots() | ||
const attrsCustom = useAttrs() | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/require-macro-variable-name.js) | ||
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/require-macro-variable-name.js) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/** | ||
* @author ItMaga | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
const utils = require('../utils') | ||
|
||
const DEFAULT_OPTIONS = { | ||
defineProps: 'props', | ||
defineEmits: 'emit', | ||
defineSlots: 'slots', | ||
useSlots: 'slots', | ||
useAttrs: 'attrs' | ||
} | ||
|
||
module.exports = { | ||
meta: { | ||
hasSuggestions: true, | ||
type: 'suggestion', | ||
docs: { | ||
description: 'require a certain macro variable name', | ||
categories: undefined, | ||
url: 'https://eslint.vuejs.org/rules/require-macro-variable-name.html' | ||
}, | ||
fixable: null, | ||
schema: [ | ||
{ | ||
type: 'object', | ||
properties: { | ||
defineProps: { | ||
type: 'string', | ||
default: DEFAULT_OPTIONS.defineProps | ||
}, | ||
defineEmits: { | ||
type: 'string', | ||
default: DEFAULT_OPTIONS.defineEmits | ||
}, | ||
defineSlots: { | ||
type: 'string', | ||
default: DEFAULT_OPTIONS.defineSlots | ||
}, | ||
useSlots: { | ||
type: 'string', | ||
default: DEFAULT_OPTIONS.useSlots | ||
}, | ||
useAttrs: { | ||
type: 'string', | ||
default: DEFAULT_OPTIONS.useAttrs | ||
} | ||
}, | ||
additionalProperties: false | ||
} | ||
], | ||
messages: { | ||
requireName: | ||
'The variable name of "{{macroName}}" must be "{{variableName}}".', | ||
changeName: 'Change the variable name to "{{variableName}}".' | ||
} | ||
}, | ||
/** @param {RuleContext} context */ | ||
create(context) { | ||
const options = context.options[0] || DEFAULT_OPTIONS | ||
const relevantMacros = new Set([ | ||
...Object.keys(DEFAULT_OPTIONS), | ||
'withDefaults' | ||
]) | ||
|
||
return utils.defineScriptSetupVisitor(context, { | ||
VariableDeclarator(node) { | ||
if ( | ||
node.init && | ||
node.init.type === 'CallExpression' && | ||
node.init.callee.type === 'Identifier' && | ||
relevantMacros.has(node.init.callee.name) | ||
) { | ||
const macroName = | ||
node.init.callee.name === 'withDefaults' | ||
? 'defineProps' | ||
: node.init.callee.name | ||
|
||
if ( | ||
node.id.type === 'Identifier' && | ||
node.id.name !== options[macroName] | ||
) { | ||
context.report({ | ||
node: node.id, | ||
loc: node.id.loc, | ||
messageId: 'requireName', | ||
data: { | ||
macroName, | ||
variableName: options[macroName] | ||
}, | ||
suggest: [ | ||
{ | ||
messageId: 'changeName', | ||
data: { | ||
variableName: options[macroName] | ||
}, | ||
fix(fixer) { | ||
return fixer.replaceText(node.id, options[macroName]) | ||
} | ||
} | ||
] | ||
}) | ||
} | ||
} | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.