Bug: Probably wrong fix of ESLint's prefer-template warning
See original GitHub issueEnvironment
Node version: 16.9.1 npm version: 7.24.0 Local ESLint version: 8.0.0.beta.2 Global ESLint version: none Operating System: Windows 10 21H1
What parser are you using?
Other
What did you do?
ESLint raises a warning ESLint: Unexpected string concatenation.(prefer-template)
:
for the given code:
res.setHeader("content-security-policy",
"default-src 'self' https://*.google.com;"
+ "script-src 'self' 'unsafe-eval' 'unsafe-inline' https://*.google.com;"
+ "connect-src 'self' https://*.google.com;"
+ "frame-ancestors 'none';"
+ "report-to " + policyViolationReport
+ ";");
What did you expect to happen?
When I click on ESLint: Fix: prefere-template
in IDE (or eslint --config eslintrc.json --fix app.js
), I expect to get:
res.setHeader("content-security-policy",
`"default-src 'self' https://*.google.com;"`
+ `"script-src 'self' 'unsafe-eval' 'unsafe-inline' https://*.google.com;"`
+ `"connect-src 'self' https://*.google.com;"`
+ `"frame-ancestors 'none';"`
+ `"report-to "${policyViolationReport};`);
What actually happened?
The result in fact:
res.setHeader("content-security-policy",
`${"default-src 'self' https://*.google.com;"
+ "script-src 'self' 'unsafe-eval' 'unsafe-inline' https://*.google.com;"
+ "connect-src 'self' https://*.google.com;"
+ "frame-ancestors 'none';"
+ "report-to "}${ policyViolationReport
};`);
The possible issues are:
- Unwanted space
${ policyViolationReport
- Unwanted line break for the closing clause
};
of the last literal variable:
+ "report-to "}${ policyViolationReport
};`);
-
For some reason,
"default-src 'self' https://*.google.com;"
is represented as a placeholders (${expression}
), while in fact it’s just a text, not a variable in contrast to thepolicyViolationReport
, which really should be represented as a literal placeholder —${policyViolationReport}
. -
BTW, the line break with literals can be implemented without concatenation symbols
+
, e.g.:
`string text line 1
string text line 2`
Participation
- I am willing to submit a pull request for this issue.
Additional comments
File for reproduction: app.js.txt
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (7 by maintainers)
That’s intentional because this rule doesn’t know user’s preferences about spacing in
${}
. This spacing can be automatically fixed in subsequent iterations by template-curly-spacing and/or no-multi-spaces rules.That’s intentional, it is assumed that the line breaks were there for readability.
This looks like a bug.
It wouldn’t be the same string value, because line breaks in template literals contribute to the value.
I looked into it and found that it’s related to the placement of the variable in concatenation instead of multi-line concatenation:
var foo = "Hello" + test + "world"
=> fixed code:var foo =
`Hello ${test} world
`var foo = "Hello " + "world" + test
=> fixed code:var foo =
`${"Hello " + "world"}${test}
`Check fixed code in online demo
The fixed code is not incorrect in any case, just the format used in the cases is not consistent.
I am looking more into it, if I can come up with a fix for this.