New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update: add enforceForJSX option to no-unused-expressions rule #14012
Update: add enforceForJSX option to no-unused-expressions rule #14012
Conversation
React's createElement call is side-effect free, as are most JSX pragmas. An unused JSX element indicates a logic error in the same way any unused, side-effect free expression is. This extension the no-unused-expression rule flags unused JSX elements unless the (new) allowJsx configuration option is set
d43a5d2
to
7af0f6b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
allowJsx
that defaults to false
seems like a potential breaking change; it should probably be ignoreJSX
that defaults to false
?
Otherwise, this LGTM!
React's createElement call is side-effect free, as are most JSX pragmas. An unused JSX element indicates a logic error in the same way any unused, side-effect free expression is. This extension the no-unused-expression rule flags unused JSX elements when the (new) ignoreJSX configuration option is set
I've updated this PR, replacing the The naming seems a little weird; I thought |
This used to be reported by default until ESLint v7.5.0. In 6ea3178 we changed the logic of this rule, from reporting all expressions except those for which we know that they have side effects, to reporting only known expressions for which we are sure that they don't have side effects. The goal was to avoid possible false positives with unknown nodes like experimental syntax, but it's possible that we forgot about JSX. That said, it does seem better to have an option for JSX rather than reverting the old behavior, since we can't know whether it is React or something else. |
I changed the The naming reflects the opt-in nature of the API; |
@ljharb in the I ask because I think it makes a difference to end user developers. If ESLint can't assume JSX is side-effect free in all cases, checking for unused JSX would require developers to first be aware of this option and then enable it.
I realize a whole new rule is a lot more implementation than an option on the built-in rule. I'm open to adding this option, but I think doing it this way would help fewer developers avoid the exact footguns that inspired the original rule proposal. |
I agree it could be theoretically side-effecting, but jsx isn’t a standard - it’s react-specific syntax that a few other ecosystems have co-opted, and as you say, all co-opted similarly. Adding a new rule to a config is a breaking change, and i don't plan for one any time soon, but surely it would go there on the next semver-major, should such a rule exist. However, this seems like a reasonable option here, since it wouldn’t be enabled by default, and any ecosystem that chose to make jsx have side effects would likely find “tell users to disable this rule’s option” to be the least of their problems. |
😂 |
TSC Summary: This PR aims to add an option for JSX expressions to the TSC Question: shall we accept this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're on board to add this as an opt-in option, so I've labeled it as accepted!
I feel kind of guilty bikeshedding the option name, but it took me a minute to resolve the double negative, and I'm wondering if it's just me. Once we've settled on the name, can you document it in docs/rules/no-unused-expressions.md
and indicate that it's disabled by default?
lib/rules/no-unused-expressions.js
Outdated
@@ -50,6 +50,10 @@ module.exports = { | |||
allowTaggedTemplates: { | |||
type: "boolean", | |||
default: false | |||
}, | |||
disallowJSX: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see how the name disallowJSX
follows from the implementation, but I'm wondering if the double negative might confuse users. For consistency with the other options, I could go for your original option name allowJSX
but defaulting to true
so it's not a breaking change. I also think checkJSX
defaulting to false
would be clear. Anyone have any preferences?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s always super weird when absence and false aren’t the same - iow, i think a boolean option should never default to true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s a great point. I also wasn’t thrilled about another “allow” option having the opposite default, so checkJSX
seems like the better trade off now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe enforceForJSX
?
I considered adding more explanation to the documentation, but I didn't want to lead readers into the weeds. |
React's createElement call is side-effect free, as are most JSX pragmas.
An unused JSX element indicates a logic error in the same way any unused, side-effect free expression is.
This extension the no-unused-expression rule flags unused JSX elements unless the (new) allowJsx configuration option is set
Prerequisites checklist
What is the purpose of this pull request? (put an "X" next to an item)
What rule do you want to change?
no-unused-expression
Does this change cause the rule to produce more or fewer warnings?
More warnings; Unused JSX expressions are newly flagged
How will the change be implemented? (New option, new default behavior, etc.)?
New default behavior; new option to opt-outNo new default behavior; new option to opt-in
Please provide some example code that this change will affect:
What does the rule currently do for this code?
JSX expressions are currently ignored by
no-unused-expression
What will the rule do after it's changed?
Unused JSX expressions will be flagged
What changes did you make? (Give an overview)
Added recognition for JSXElement in the no-unused-expression rule Checker, following the code patterns already in-place in the rule.
Added tests demonstrating flagged and unflagged code, and how the
allowJsx
option interacts with such code.Is there anything you'd like reviewers to focus on?
This originally came out of this
eslint-plugin-react
PR.The scope of this PR is somewhat smaller and had a couple of key differences.
allowJsx
option) since some JSX pragmas may not be side-effect-freeReact.createElement()
calls; the original PR, focused on React, flagged these unused expressions