-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
[New] jsx-max-depth
: validate a specific depth for JSX
#1260
Conversation
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.
Can we also add test cases for nested inline JSX?
In other words, with a limit of 2, <div>{<div><div><span /></div></div>}</div>
should still error on the inner piece - also, ideally, with a limit of 2, <div>{<div><span /></div>}</div>
should also error because the total is 3, even tho it's never more than 2 in a chunk.
Similarly, const x = <div><span /><div>; <div>{x}</div>
would be nice to fail also.
docs/rules/jsx-max-depth.md
Outdated
|
||
```js | ||
... | ||
"react/jsx-no-depth": [<enabled>, <number>] |
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.
let's make an initial schema that's extensible; in other words, { "max": <number> }
instead of just the number.
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
|
||
var MESSAGE = 'JSX Element are nested too deeply ({{depth}}).'; | ||
|
||
var maxDepth = context.options[0] || 3; |
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.
in new code, let's use const/let over var
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
|
||
create: function(context) { | ||
|
||
var MESSAGE = 'JSX Element are nested too deeply ({{depth}}).'; |
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.
let's also include the current max length in the message, like max-len does.
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.
Done.
tests/lib/rules/jsx-max-depth.js
Outdated
var RuleTester = require('eslint').RuleTester; | ||
|
||
var parserOptions = { | ||
ecmaVersion: 8, |
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.
let's set this to 6
, since we shouldn't need ES2017 for this rule
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.
Done.
tests/lib/rules/jsx-max-depth.js
Outdated
ecmaVersion: 8, | ||
sourceType: 'module', | ||
ecmaFeatures: { | ||
experimentalObjectRestSpread: 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.
similarly, this feature isn't required here
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.
Done.
0132b8a
to
3f91f7a
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.
Thanks, this is looking much better.
lib/rules/jsx-max-depth.js
Outdated
schema: [{ | ||
oneOf: [ | ||
{ | ||
type: 'integer', |
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'd prefer to not even allow this as an option, if possible - meaning, to only have the object schema.
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
} | ||
|
||
function findJSXElement(variables, name) { | ||
let find = function(refs) { |
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.
const
- or a function declaration
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.
Done. Changed to function declaration.
lib/rules/jsx-max-depth.js
Outdated
let i = refs.length; | ||
|
||
while (--i >= 0) { | ||
if ('writeExpr' in refs[i]) { |
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.
please use the has
package rather than in
, to avoid traversing the prototype chain.
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
|
||
while (--i >= 0) { | ||
if ('writeExpr' in refs[i]) { | ||
let writeExpr = refs[i].writeExpr; |
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.
const
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
let writeExpr = refs[i].writeExpr; | ||
|
||
return isJSXElement(writeExpr) | ||
&& writeExpr |
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.
these chained lines should be indented one level further in
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
let element = findJSXElement(variables, node.expression.name); | ||
|
||
if (element) { | ||
let baseDepth = getDepth(node); |
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.
const
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
} | ||
|
||
function isLeaf(node) { | ||
let children = node.children; |
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.
const
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
const DEFAULT_DEPTH = 3; | ||
|
||
let option = context.options[0] || DEFAULT_DEPTH; | ||
let maxDepth = (typeof option === 'number' ? option : option.max) || DEFAULT_DEPTH; |
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.
const
Also, what happens if I pass a value of 0
? This looks like it will always set 0 to 3. Please add some tests for values of 0
- ie, no nesting allowed.
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.
max: {
type: 'integer',
minimum: 1
}
0
is no a valid value 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.
Why isn't zero a valid value? I'd think prohibiting nesting entirely is a totally valid option.
lib/rules/jsx-max-depth.js
Outdated
const MESSAGE = 'Expected the depth of JSX Elements nested should be {{needed}} but found {{gotten}}.'; | ||
const DEFAULT_DEPTH = 3; | ||
|
||
let option = context.options[0] || DEFAULT_DEPTH; |
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.
const
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
}] | ||
}, | ||
create: function(context) { | ||
const MESSAGE = 'Expected the depth of JSX Elements nested should be {{needed}} but found {{gotten}}.'; |
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.
"gotten" seems like an odd word choice; maybe "found"?
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.
Done.
lib/rules/jsx-max-depth.js
Outdated
properties: { | ||
max: { | ||
type: 'integer', | ||
minimum: 1 |
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 think this should be made to work with 0
.
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.
Since this rule is called "max-depth", I think it should detect the "depth" but not "nesting depth" of jsx, a depth of 0 means "no element here" which is absolutely useless
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.
If that's true, then a max
of 1
would permit <div />
but forbid <div><span /><div>
; is that what the current PR's docs and test cases indicate?
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.
Specifically, I want it to be configurable so I can forbid any nesting whatsoever - a depth of 0
means "flat", so in fact <div />
has a depth of zero.
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.
OKey.
Is there anything stopping this rule from moving forward? This seems pretty useful to me! 😄 It probably needs a rebase though, at least one file has a conflict. |
Happy to rereview after a rebase. |
@chriswong any chance you could rebase this? |
@ljharb I rebased this on master. How should I submit the changes? |
Certainly not with a duplicate PR, which I can never delete from my git history :-( Posting a link to the branch would be more than sufficient. |
I've rebased this properly and pushed the changes up to here and to #1676. |
Fixes #1219