eslint-plugin-react-perf
Advanced tools
Comparing version 3.2.4 to 3.3.0
@@ -9,16 +9,50 @@ "use strict"; | ||
category: "", | ||
recommended: true | ||
recommended: true, | ||
}, | ||
schema: [] | ||
schema: [ | ||
{ | ||
additionalProperties: false, | ||
properties: { | ||
nativeAllowList: { | ||
oneOf: [ | ||
{ | ||
enum: ["all"], | ||
}, | ||
{ | ||
type: "array", | ||
items: { | ||
type: "string", | ||
}, | ||
}, | ||
], | ||
}, | ||
}, | ||
type: "object", | ||
}, | ||
], | ||
}, | ||
create: function(context) { | ||
create: function (context) { | ||
const { options } = context; | ||
const { nativeAllowList } = options[0] || {}; | ||
return { | ||
JSXAttribute: function(node) { | ||
JSXAttribute: function (node) { | ||
if (!node.value || node.value.type !== "JSXExpressionContainer") { | ||
return; | ||
} | ||
if ( | ||
isNativeElement(node) && | ||
(nativeAllowList === "all" || | ||
(Array.isArray(nativeAllowList) && | ||
nativeAllowList.find(function (nativeExclude) { | ||
return ( | ||
node.name.name.toLowerCase() === nativeExclude.toLowerCase() | ||
); | ||
}))) | ||
) { | ||
return; | ||
} | ||
var violationFound = false; | ||
findRelevantNodes(context, node.value.expression).forEach(function( | ||
findRelevantNodes(context, node.value.expression).forEach(function ( | ||
node | ||
@@ -32,5 +66,5 @@ ) { | ||
return violationFound; | ||
} | ||
}, | ||
}; | ||
} | ||
}, | ||
}; | ||
@@ -46,7 +80,7 @@ } | ||
if (node.type === "Identifier") { | ||
var variable = context.getScope().variables.find(function(variable) { | ||
var variable = context.getScope().variables.find(function (variable) { | ||
return variable.name === node.name; | ||
}); | ||
if (variable) { | ||
variable.references.forEach(function(reference) { | ||
variable.references.forEach(function (reference) { | ||
if (!reference.identifier.parent) return; | ||
@@ -94,5 +128,14 @@ switch (reference.identifier.parent.type) { | ||
function isNativeElement(node) { | ||
if (node.parent.name.type !== "JSXIdentifier") { | ||
return false; | ||
} | ||
const nodeName = node.parent.name.name; | ||
const firstChar = nodeName.charAt(0); | ||
return firstChar === firstChar.toLowerCase(); | ||
} | ||
module.exports = { | ||
createRule, | ||
checkConstructor | ||
checkConstructor, | ||
}; |
{ | ||
"name": "eslint-plugin-react-perf", | ||
"version": "3.2.4", | ||
"version": "3.3.0", | ||
"description": "Performance-minded React linting rules for ESLint", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -1,3 +0,2 @@ | ||
eslint-plugin-react-perf | ||
======================== | ||
# eslint-plugin-react-perf | ||
@@ -12,10 +11,30 @@ Performance-minded React linting rules for ESLint (motivated by [esamatti](https://twitter.com/esamatti)'s post ["React.js pure render performance anti-pattern"](https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f)). | ||
Add `plugins` section and specify eslint-plugin-react-perf as a plugin. | ||
```json | ||
{ | ||
"plugins": ["react-perf"] | ||
} | ||
``` | ||
# List of supported rules | ||
- [react-perf/jsx-no-new-object-as-prop](docs/rules/jsx-no-new-object-as-prop.md): Prevent `{...}` as JSX prop value | ||
- [react-perf/jsx-no-new-array-as-prop](docs/rules/jsx-no-new-array-as-prop.md): Prevent `[...]` as JSX prop value | ||
- [react-perf/jsx-no-new-function-as-prop](docs/rules/jsx-no-new-function-as-prop.md): Prevent `function` as JSX prop value | ||
- [react-perf/jsx-no-jsx-as-prop](docs/rules/jsx-no-jsx-as-prop.md): Prevent JSX as JSX prop value | ||
# Configuration | ||
Add `plugins` section and specify eslint-plugin-react-perf as a plugin. | ||
As of v3.3.0, each eslint-plugin-react-perf rule supports configuration to control whether native elements (lower case first letter React components) are ignored. | ||
With this configuration, all native elements are ignored for this rule: | ||
```json | ||
{ | ||
"plugins": [ | ||
"react-perf" | ||
"react-perf/jsx-no-new-object-as-prop": [ | ||
"error", | ||
{ | ||
"nativeAllowList": "all" | ||
} | ||
] | ||
@@ -25,8 +44,14 @@ } | ||
# List of supported rules | ||
With this configuration, the "style" attribute is ignored for native elements for this rule: | ||
* [react-perf/jsx-no-new-object-as-prop](docs/rules/jsx-no-new-object-as-prop.md): Prevent `{...}` as JSX prop value | ||
* [react-perf/jsx-no-new-array-as-prop](docs/rules/jsx-no-new-array-as-prop.md): Prevent `[...]` as JSX prop value | ||
* [react-perf/jsx-no-new-function-as-prop](docs/rules/jsx-no-new-function-as-prop.md): Prevent `function` as JSX prop value | ||
* [react-perf/jsx-no-jsx-as-prop](docs/rules/jsx-no-jsx-as-prop.md): Prevent JSX as JSX prop value | ||
```json | ||
{ | ||
"react-perf/jsx-no-new-object-as-prop": [ | ||
"error", | ||
{ | ||
"nativeAllowList": ["style"] | ||
} | ||
] | ||
} | ||
``` | ||
@@ -49,6 +74,6 @@ ## Recommended | ||
* [react-perf/jsx-no-new-object-as-prop](docs/rules/jsx-no-new-object-as-prop.md) | ||
* [react-perf/jsx-no-new-array-as-prop](docs/rules/jsx-no-new-array-as-prop.md) | ||
* [react-perf/jsx-no-new-function-as-prop](docs/rules/jsx-no-new-function-as-prop.md) | ||
* [react-perf/jsx-no-jsx-as-prop](docs/rules/jsx-no-jsx-as-prop.md) | ||
- [react-perf/jsx-no-new-object-as-prop](docs/rules/jsx-no-new-object-as-prop.md) | ||
- [react-perf/jsx-no-new-array-as-prop](docs/rules/jsx-no-new-array-as-prop.md) | ||
- [react-perf/jsx-no-new-function-as-prop](docs/rules/jsx-no-new-function-as-prop.md) | ||
- [react-perf/jsx-no-jsx-as-prop](docs/rules/jsx-no-jsx-as-prop.md) | ||
@@ -69,2 +94,3 @@ ## All | ||
# Test anti-patterns in runtime | ||
Try out [cvazac/test-ref-pattern](https://github.com/cvazac/test-ref-pattern). | ||
@@ -71,0 +97,0 @@ |
"use strict"; | ||
var invalidFunctionExpressions = [ | ||
{ code: "<Item prop={function(){return true}} />", line: 1, column: 13 } | ||
].map(function({ code, line, column }) { | ||
{ code: "<Item prop={function(){return true}} />", line: 1, column: 13 }, | ||
].map(function ({ code, line, column }) { | ||
return { | ||
@@ -12,5 +12,5 @@ code, | ||
column, | ||
type: "FunctionExpression" | ||
} | ||
] | ||
type: "FunctionExpression", | ||
}, | ||
], | ||
}; | ||
@@ -20,4 +20,4 @@ }); | ||
var invalidArrowFunctionExpressions = [ | ||
{ code: "<Item prop={() => true} />", line: 1, column: 13 } | ||
].map(function({ code, line, column }) { | ||
{ code: "<Item prop={() => true} />", line: 1, column: 13 }, | ||
].map(function ({ code, line, column }) { | ||
return { | ||
@@ -29,5 +29,5 @@ code, | ||
column, | ||
type: "ArrowFunctionExpression" | ||
} | ||
] | ||
type: "ArrowFunctionExpression", | ||
}, | ||
], | ||
}; | ||
@@ -37,4 +37,4 @@ }); | ||
var invalidNewExpressions = [ | ||
{ code: "<Item prop={new Function('a', 'alert(a)')}/>", line: 1, column: 13 } | ||
].map(function({ code, line, column }) { | ||
{ code: "<Item prop={new Function('a', 'alert(a)')}/>", line: 1, column: 13 }, | ||
].map(function ({ code, line, column }) { | ||
return { | ||
@@ -46,5 +46,5 @@ code, | ||
column, | ||
type: "NewExpression" | ||
} | ||
] | ||
type: "NewExpression", | ||
}, | ||
], | ||
}; | ||
@@ -57,5 +57,5 @@ }); | ||
line: 1, | ||
column: 16 | ||
} | ||
].map(function({ code, line, column }) { | ||
column: 16, | ||
}, | ||
].map(function ({ code, line, column }) { | ||
return { | ||
@@ -67,9 +67,9 @@ code, | ||
column, | ||
type: "CallExpression" | ||
} | ||
] | ||
type: "CallExpression", | ||
}, | ||
], | ||
}; | ||
}); | ||
var validExpressions = ["<Item onClick={bind(foo)} />"]; | ||
var validExpressions = [{ code: "<Item onClick={bind(foo)} />" }]; | ||
@@ -76,0 +76,0 @@ module.exports = require("../utils/common").testRule( |
@@ -19,7 +19,14 @@ "use strict"; | ||
experimentalObjectRestSpread: true, | ||
jsx: true | ||
} | ||
jsx: true, | ||
}, | ||
}; | ||
invalid = [ | ||
{ code: `<div style={${ruleCode}} />`, line: 1, column: 13 }, | ||
{ | ||
code: `<div style={${ruleCode}} />`, | ||
options: [{ nativeAllowList: ["styleX"] }], | ||
line: 1, | ||
column: 13, | ||
}, | ||
{ code: `<Item prop={${ruleCode}} />`, line: 1, column: 13 }, | ||
@@ -40,3 +47,3 @@ { code: `<Item.tag prop={${ruleCode}} />`, line: 1, column: 17 }, | ||
line: 1, | ||
column: 12 | ||
column: 12, | ||
}, | ||
@@ -46,3 +53,3 @@ { | ||
line: 1, | ||
column: 19 | ||
column: 19, | ||
}, | ||
@@ -55,3 +62,3 @@ { | ||
line: 1, | ||
column: 23 | ||
column: 23, | ||
}, | ||
@@ -64,8 +71,9 @@ { | ||
line: 1, | ||
column: 10 | ||
} | ||
column: 10, | ||
}, | ||
] | ||
.map(function({ code, line, column }) { | ||
.map(function ({ code, options = [], line, column }) { | ||
return { | ||
code, | ||
options, | ||
errors: [ | ||
@@ -75,5 +83,5 @@ { | ||
column, | ||
type: ruleType | ||
} | ||
] | ||
type: ruleType, | ||
}, | ||
], | ||
}; | ||
@@ -84,33 +92,50 @@ }) | ||
valid = [ | ||
"<Item prop={0} />", | ||
"var a;<Item prop={a} />", | ||
"var a;a = 1;<Item prop={a} />", | ||
"var a;a = a;<Item prop={a} />", | ||
"var a;a = b;<Item prop={a} />", | ||
`function foo ({prop1, prop2 = ${ruleCode}}) { | ||
{ | ||
code: `<div style={${ruleCode}} />`, | ||
options: [{ nativeAllowList: "all" }], | ||
}, | ||
{ | ||
code: `<div style={${ruleCode}} />`, | ||
options: [{ nativeAllowList: ["style"] }], | ||
}, | ||
{ code: "<Item prop={0} />" }, | ||
{ code: "var a;<Item prop={a} />" }, | ||
{ code: "var a;a = 1;<Item prop={a} />" }, | ||
{ code: "var a;a = a;<Item prop={a} />" }, | ||
{ code: "var a;a = b;<Item prop={a} />" }, | ||
{ | ||
code: `function foo ({prop1, prop2 = ${ruleCode}}) { | ||
return <Comp prop={prop1} /> | ||
}`, | ||
`function foo ({prop1 = ${ruleCode}, prop2}) { | ||
}, | ||
{ | ||
code: `function foo ({prop1 = ${ruleCode}, prop2}) { | ||
return <Comp prop={prop2} /> | ||
}`, | ||
`({prop1, prop2 = ${ruleCode}}) => { | ||
}, | ||
{ | ||
code: `({prop1, prop2 = ${ruleCode}}) => { | ||
return <Comp prop={prop1} /> | ||
}`, | ||
`({prop1 = ${ruleCode}, prop2}) => { | ||
}, | ||
{ | ||
code: `({prop1 = ${ruleCode}, prop2}) => { | ||
return <Comp prop={prop2} /> | ||
}` | ||
}`, | ||
}, | ||
].concat(valid || []); | ||
new RuleTester().run(ruleName, rule, { | ||
valid: valid.map(code => { | ||
valid: valid.map(({ code, options = [] }) => { | ||
return { | ||
code, | ||
parserOptions | ||
options, | ||
parserOptions, | ||
}; | ||
}), | ||
invalid: invalid.map(e => { | ||
invalid: invalid.map((e) => { | ||
e.parserOptions = parserOptions; | ||
e.errors.message = errorMessage; | ||
return e; | ||
}) | ||
}), | ||
}); | ||
@@ -120,3 +145,3 @@ } | ||
module.exports = { | ||
testRule | ||
testRule, | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22700
599
97