Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ad84e0b

Browse files
mysticateamichalsnik
authored andcommitted
New: directive comments (fixes #260) (#320)
* New: directive comments (fixes #260) * Docs: update docs
1 parent 8ea98e7 commit ad84e0b

File tree

10 files changed

+442
-1
lines changed

10 files changed

+442
-1
lines changed

‎README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,20 @@ Vue.component('AsyncComponent', (resolve, reject) => {
7171
})
7272
```
7373

74+
### `eslint-disable` functionality in `<template>`
75+
76+
You can use `<!-- eslint-disable -->`-like HTML comments in `<template>` of `.vue` files. For example:
77+
78+
```html
79+
<template>
80+
<!-- eslint-disable-next-line vue/max-attributes-per-line -->
81+
<div a="1" b="2" c="3" d="4">
82+
</div>
83+
</template>
84+
```
85+
86+
If you want to disallow `eslint-disable` functionality, please disable [vue/comment-directive](./docs/rules/comment-directive.md) rule.
87+
7488
## :gear: Configs
7589

7690
This plugin provides two predefined configs:
@@ -95,6 +109,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
95109

96110
| | Rule ID | Description |
97111
|:---|:--------|:------------|
112+
| | [comment-directive](./docs/rules/comment-directive.md) | support comment-directives in `<template>` |
98113
| | [jsx-uses-vars](./docs/rules/jsx-uses-vars.md) | prevent variables used in JSX to be marked as unused |
99114

100115

‎docs/rules/comment-directive.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# support comment-directives in `<template>` (comment-directive)
2+
3+
Sole purpose of this rule is to provide `eslint-disable` functionality in `<template>`.
4+
It supports usage of the following comments:
5+
6+
- `eslint-disable`
7+
- `eslint-enable`
8+
- `eslint-disable-line`
9+
- `eslint-disable-next-line`
10+
11+
For example:
12+
13+
```html
14+
<template>
15+
<!-- eslint-disable-next-line vue/max-attributes-per-line -->
16+
<div a="1" b="2" c="3" d="4">
17+
</div>
18+
</template>
19+
```
20+
21+
> Note: we can't write HTML comments in tags.
22+
23+
This rule doesn't throw any warning.
24+
25+
## :book: Rule Details
26+
27+
ESLint doesn't provide any API to enhance `eslint-disable` functionality and ESLint rules cannot affect other rules. But ESLint provides [processors API](https://eslint.org/docs/developer-guide/working-with-plugins#processors-in-plugins).
28+
29+
This rule sends all `eslint-disable`-like comments as errors to the post-process of the `.vue` file processor, then the post-process removes all `vue/comment-directive` errors and the reported errors in disabled areas.
30+
31+
## :books: Further reading
32+
33+
- [Disabling rules with inline comments](https://eslint.org/docs/user-guide/configuring#disabling-rules-with-inline-comments)

‎lib/base-rules.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
* in order to update it's content execute "npm run update"
55
*/
66
module.exports = {
7+
"vue/comment-directive": "error",
78
"vue/jsx-uses-vars": "error"
89
}

‎lib/essential-rules.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* in order to update it's content execute "npm run update"
55
*/
66
module.exports = {
7+
"vue/comment-directive": "error",
78
"vue/jsx-uses-vars": "error",
89
"vue/no-async-in-computed-properties": "error",
910
"vue/no-dupe-keys": "error",

‎lib/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ const configs = requireAll({
1111
dirname: resolve(__dirname, 'config'),
1212
filter: /^([\w\-]+)\.js$/
1313
})
14+
const processor = require('./processor')
1415

1516
module.exports = {
1617
rules,
17-
configs
18+
configs,
19+
processors: { '.vue': processor }
1820
}

‎lib/processor.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @author Toru Nagashima <https://github.com/mysticatea>
3+
*/
4+
'use strict'
5+
6+
module.exports = {
7+
preprocess (code) {
8+
return [code]
9+
},
10+
11+
postprocess (messages) {
12+
const state = {
13+
block: {
14+
disableAll: false,
15+
disableRules: new Set()
16+
},
17+
line: {
18+
disableAll: false,
19+
disableRules: new Set()
20+
}
21+
}
22+
23+
// Filter messages which are in disabled area.
24+
return messages[0].filter(message => {
25+
if (message.ruleId === 'vue/comment-directive') {
26+
const rules = message.message.split(' ')
27+
const type = rules.shift()
28+
const group = rules.shift()
29+
switch (type) {
30+
case '--':
31+
state[group].disableAll = true
32+
break
33+
case '++':
34+
state[group].disableAll = false
35+
break
36+
case '-':
37+
for (const rule of rules) {
38+
state[group].disableRules.add(rule)
39+
}
40+
break
41+
case '+':
42+
for (const rule of rules) {
43+
state[group].disableRules.delete(rule)
44+
}
45+
break
46+
}
47+
return false
48+
} else {
49+
return !(
50+
state.block.disableAll ||
51+
state.line.disableAll ||
52+
state.block.disableRules.has(message.ruleId) ||
53+
state.line.disableRules.has(message.ruleId)
54+
)
55+
}
56+
})
57+
},
58+
59+
supportsAutofix: true
60+
}

‎lib/recommended-rules.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
module.exports = {
77
"vue/attribute-hyphenation": "error",
8+
"vue/comment-directive": "error",
89
"vue/html-end-tags": "error",
910
"vue/html-indent": "error",
1011
"vue/html-quotes": "error",

‎lib/rules/comment-directive.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/**
2+
* @author Toru Nagashima <https://github.com/mysticatea>
3+
*/
4+
5+
'use strict'
6+
7+
// -----------------------------------------------------------------------------
8+
// Helpers
9+
// -----------------------------------------------------------------------------
10+
11+
const COMMENT_DIRECTIVE_B = /^\s*(eslint-(?:en|dis)able)\s*(?:(\S|\S[\s\S]*\S)\s*)?$/
12+
const COMMENT_DIRECTIVE_L = /^\s*(eslint-disable(?:-next)?-line)\s*(?:(\S|\S[\s\S]*\S)\s*)?$/
13+
14+
/**
15+
* Parse a given comment.
16+
* @param {RegExp} pattern The RegExp pattern to parse.
17+
* @param {string} comment The comment value to parse.
18+
* @returns {({type:string,rules:string[]})|null} The parsing result.
19+
*/
20+
function parse (pattern, comment) {
21+
const match = pattern.exec(comment)
22+
if (match == null) {
23+
return null
24+
}
25+
26+
const type = match[1]
27+
const rules = (match[2] || '')
28+
.split(',')
29+
.map(s => s.trim())
30+
.filter(Boolean)
31+
32+
return { type, rules }
33+
}
34+
35+
/**
36+
* Enable rules.
37+
* @param {RuleContext} context The rule context.
38+
* @param {{line:number,column:number}} loc The location information to enable.
39+
* @param {string} group The group to enable.
40+
* @param {string[]} rules The rule IDs to enable.
41+
* @returns {void}
42+
*/
43+
function enable (context, loc, group, rules) {
44+
if (rules.length === 0) {
45+
context.report({ loc, message: '++ {{group}}', data: { group }})
46+
} else {
47+
context.report({ loc, message: '+ {{group}} {{rules}}', data: { group, rules: rules.join(' ') }})
48+
}
49+
}
50+
51+
/**
52+
* Disable rules.
53+
* @param {RuleContext} context The rule context.
54+
* @param {{line:number,column:number}} loc The location information to disable.
55+
* @param {string} group The group to disable.
56+
* @param {string[]} rules The rule IDs to disable.
57+
* @returns {void}
58+
*/
59+
function disable (context, loc, group, rules) {
60+
if (rules.length === 0) {
61+
context.report({ loc, message: '-- {{group}}', data: { group }})
62+
} else {
63+
context.report({ loc, message: '- {{group}} {{rules}}', data: { group, rules: rules.join(' ') }})
64+
}
65+
}
66+
67+
/**
68+
* Process a given comment token.
69+
* If the comment is `eslint-disable` or `eslint-enable` then it reports the comment.
70+
* @param {RuleContext} context The rule context.
71+
* @param {Token} comment The comment token to process.
72+
* @returns {void}
73+
*/
74+
function processBlock (context, comment) {
75+
const parsed = parse(COMMENT_DIRECTIVE_B, comment.value)
76+
if (parsed != null) {
77+
if (parsed.type === 'eslint-disable') {
78+
disable(context, comment.loc.start, 'block', parsed.rules)
79+
} else {
80+
enable(context, comment.loc.start, 'block', parsed.rules)
81+
}
82+
}
83+
}
84+
85+
/**
86+
* Process a given comment token.
87+
* If the comment is `eslint-disable-line` or `eslint-disable-next-line` then it reports the comment.
88+
* @param {RuleContext} context The rule context.
89+
* @param {Token} comment The comment token to process.
90+
* @returns {void}
91+
*/
92+
function processLine (context, comment) {
93+
const parsed = parse(COMMENT_DIRECTIVE_L, comment.value)
94+
if (parsed != null && comment.loc.start.line === comment.loc.end.line) {
95+
const line = comment.loc.start.line + (parsed.type === 'eslint-disable-line' ? 0 : 1)
96+
const column = -1
97+
disable(context, { line, column }, 'line', parsed.rules)
98+
enable(context, { line: line + 1, column }, 'line', parsed.rules)
99+
}
100+
}
101+
102+
/**
103+
* The implementation of `vue/comment-directive` rule.
104+
* @param {Program} node The program node to parse.
105+
* @returns {Object} The visitor of this rule.
106+
*/
107+
function create (context) {
108+
return {
109+
Program (node) {
110+
const comments = (node.templateBody && node.templateBody.comments) || []
111+
for (const comment of comments) {
112+
processBlock(context, comment)
113+
processLine(context, comment)
114+
}
115+
}
116+
}
117+
}
118+
119+
// -----------------------------------------------------------------------------
120+
// Rule Definition
121+
// -----------------------------------------------------------------------------
122+
123+
module.exports = {
124+
meta: {
125+
docs: {
126+
description: 'support comment-directives in `<template>`', // eslint-disable-line consistent-docs-description
127+
category: 'base'
128+
},
129+
schema: []
130+
},
131+
create
132+
}

‎lib/strongly-recommended-rules.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
module.exports = {
77
"vue/attribute-hyphenation": "error",
8+
"vue/comment-directive": "error",
89
"vue/html-end-tags": "error",
910
"vue/html-indent": "error",
1011
"vue/html-self-closing": "error",

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /