Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* New: `template-tag-spacing` rule (fixes #7631) * Check template tags wrapped in parens * Change rule category to "Stylistic Issues" * Rephrase rule documentation intro Rewrote the intro do be more descriptive about tagged template literals. Also includes a "Further Reading" section. * Update docs to better explain the rule concept * Add tests for tags with comments * Documentation nits * Adjust template tag autofixing behaviour when there's comments present
- Loading branch information
1 parent
e544644
commit 09546a4
Showing
4 changed files
with
433 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,78 @@ | ||
# Require or disallow spacing between template tags and their literals (template-tag-spacing) | ||
|
||
(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fix) automatically fixes problems reported by this rule. | ||
|
||
With ES6, it's possible to create functions called [tagged template literals](#further-reading) where the function parameters consist of a template literal's strings and expressions. | ||
|
||
When using tagged template literals, it's possible to insert whitespace between the tag function and the template literal. Since this whitespace is optional, the following lines are equivalent: | ||
|
||
```js | ||
let hello = func`Hello world`; | ||
let hello = func `Hello world`; | ||
``` | ||
|
||
## Rule Details | ||
|
||
This rule aims to maintain consistency around the spacing between template tag functions and their template literals. | ||
|
||
## Options | ||
|
||
```json | ||
{ | ||
"template-tag-spacing": ["error", "never"] | ||
} | ||
``` | ||
|
||
This rule has one option whose value can be set to "never" or "always" | ||
|
||
* `"never"` (default) - Disallows spaces between a tag function and its template literal. | ||
* `"always"` - Requires one or more spaces between a tag function and its template literal. | ||
|
||
## Examples | ||
|
||
### never | ||
|
||
Examples of **incorrect** code for this rule with the default `"never"` option: | ||
|
||
```js | ||
/*eslint template-tag-spacing: "error"*/ | ||
|
||
func `Hello world`; | ||
``` | ||
|
||
Examples of **correct** code for this rule with the default `"never"` option: | ||
|
||
```js | ||
/*eslint template-tag-spacing: "error"*/ | ||
|
||
func`Hello world`; | ||
``` | ||
|
||
### always | ||
|
||
Examples of **incorrect** code for this rule with the `"always"` option: | ||
|
||
```js | ||
/*eslint template-tag-spacing: ["error", "always"]*/ | ||
|
||
func`Hello world`; | ||
``` | ||
|
||
Examples of **correct** code for this rule with the `"always"` option: | ||
|
||
```js | ||
/*eslint template-tag-spacing: ["error", "always"]*/ | ||
|
||
func `Hello world`; | ||
``` | ||
|
||
## When Not To Use It | ||
|
||
If you don't want to be notified about usage of spacing between tag functions and their template literals, then it's safe to disable this rule. | ||
|
||
## Further Reading | ||
|
||
If you want to learn more about tagged template literals, check out the links below: | ||
|
||
* [Template literals (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals) | ||
* [Examples of using tagged template literals (Exploring ES6)](http://exploringjs.com/es6/ch_template-literals.html#_examples-of-using-tagged-template-literals) |
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,77 @@ | ||
/** | ||
* @fileoverview Rule to check spacing between template tags and their literals | ||
* @author Jonathan Wilsson | ||
*/ | ||
|
||
"use strict"; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Rule Definition | ||
//------------------------------------------------------------------------------ | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: "require or disallow spacing between template tags and their literals", | ||
category: "Stylistic Issues", | ||
recommended: false | ||
}, | ||
|
||
fixable: "whitespace", | ||
|
||
schema: [ | ||
{ enum: ["always", "never"] } | ||
] | ||
}, | ||
|
||
create(context) { | ||
const never = context.options[0] !== "always"; | ||
const sourceCode = context.getSourceCode(); | ||
|
||
/** | ||
* Check if a space is present between a template tag and its literal | ||
* @param {ASTNode} node node to evaluate | ||
* @returns {void} | ||
* @private | ||
*/ | ||
function checkSpacing(node) { | ||
const tagToken = sourceCode.getTokenBefore(node.quasi); | ||
const literalToken = sourceCode.getFirstToken(node.quasi); | ||
const hasWhitespace = sourceCode.isSpaceBetweenTokens(tagToken, literalToken); | ||
|
||
if (never && hasWhitespace) { | ||
context.report({ | ||
node, | ||
loc: tagToken.loc.start, | ||
message: "Unexpected space between template tag and template literal.", | ||
fix(fixer) { | ||
const comments = sourceCode.getComments(node.quasi).leading; | ||
|
||
// Don't fix anything if there's a single line comment after the template tag | ||
if (comments.some(comment => comment.type === "Line")) { | ||
return null; | ||
} | ||
|
||
return fixer.replaceTextRange( | ||
[tagToken.range[1], literalToken.range[0]], | ||
comments.reduce((text, comment) => text + sourceCode.getText(comment), "") | ||
); | ||
} | ||
}); | ||
} else if (!never && !hasWhitespace) { | ||
context.report({ | ||
node, | ||
loc: tagToken.loc.start, | ||
message: "Missing space between template tag and template literal.", | ||
fix(fixer) { | ||
return fixer.insertTextAfter(tagToken, " "); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
return { | ||
TaggedTemplateExpression: checkSpacing | ||
}; | ||
} | ||
}; |
Oops, something went wrong.