Skip to content

Commit b9f894e

Browse files
committed
Merge pull request #6 from glenjamin/jsx-uses-react
Add jsx-uses-react rule
2 parents d2480bc + ca87883 commit b9f894e

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

docs/rules/jsx-uses-react.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Make JSX count towards use of a declared variable (jsx-uses-react)
2+
3+
JSX expands to a call to `React.createElement`, a file which includes `React`
4+
but only uses JSX should still consider the `React` variable used.
5+
6+
This rule has no effect if the `no-unused-vars` rule is not enabled.
7+
8+
## Rule Details
9+
10+
The following patterns are considered warnings:
11+
12+
```js
13+
var React = require('react'); // and other equivalent imports
14+
15+
// nothing to do with React
16+
```
17+
18+
The following patterns are not considered warnings:
19+
20+
```js
21+
var React = require('react');
22+
23+
var elem = <div>Some Stuff</div>;
24+
```
25+
26+
## When Not To Use It
27+
28+
If you are not using JSX, or React is delcared as global variable, this rule
29+
will not be useful.

index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
module.exports = {
44
rules: {
5+
'jsx-uses-react': require('./lib/rules/jsx-uses-react'),
56
'no-multi-comp': require('./lib/rules/no-multi-comp'),
67
'prop-types': require('./lib/rules/prop-types'),
78
'display-name': require('./lib/rules/display-name'),
@@ -12,6 +13,7 @@ module.exports = {
1213
'react-in-jsx-scope': require('./lib/rules/react-in-jsx-scope')
1314
},
1415
rulesConfig: {
16+
'jsx-uses-react': 0,
1517
'no-multi-comp': 0,
1618
'prop-types': 0,
1719
'display-name': 0,

lib/rules/jsx-uses-react.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* @fileoverview Count <Jsx /> as use of the React variable
3+
* @author Glen Mailer
4+
*/
5+
'use strict';
6+
7+
// ------------------------------------------------------------------------------
8+
// Rule Definition
9+
// ------------------------------------------------------------------------------
10+
11+
module.exports = function(context) {
12+
13+
function flagReactAsUsedInJSX() {
14+
var scope = context.getScope(),
15+
variables = scope.variables,
16+
i,
17+
len;
18+
19+
while (scope.type !== "global") {
20+
scope = scope.upper;
21+
variables = [].concat.apply(scope.variables, variables);
22+
}
23+
24+
// mark first React found with the same special flag used by no-unused-vars
25+
for (i = 0, len = variables.length; i < len; i++) {
26+
if (variables[i].name === 'React') {
27+
variables[i].eslintJSXUsed = true;
28+
return;
29+
}
30+
}
31+
}
32+
33+
// --------------------------------------------------------------------------
34+
// Public
35+
// --------------------------------------------------------------------------
36+
37+
return {
38+
39+
'JSXOpeningElement': function() {
40+
flagReactAsUsedInJSX();
41+
}
42+
};
43+
44+
};

tests/lib/rules/jsx-uses-react.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @fileoverview Tests for jsx-uses-react
3+
* @author Glen Mailer
4+
*/
5+
6+
"use strict";
7+
8+
// -----------------------------------------------------------------------------
9+
// Requirements
10+
// -----------------------------------------------------------------------------
11+
12+
var eslint = require('eslint').linter;
13+
var ESLintTester = require('eslint-tester');
14+
15+
// -----------------------------------------------------------------------------
16+
// Tests
17+
// -----------------------------------------------------------------------------
18+
19+
var eslintTester = new ESLintTester(eslint);
20+
eslint.defineRule('jsx-uses-react', require('../../../lib/rules/jsx-uses-react'));
21+
eslintTester.addRuleTest("node_modules/eslint/lib/rules/no-unused-vars", {
22+
valid: [
23+
{code: "/*eslint jsx-uses-react:1*/ var App, React; <App />;", ecmaFeatures: {jsx: true}},
24+
{code: "/*eslint jsx-uses-react:1*/ var React; <div />;", ecmaFeatures: {jsx: true}},
25+
{code: "/*eslint jsx-uses-react:1*/ var React; (function () { <div /> })();", ecmaFeatures: {jsx: true}}
26+
],
27+
invalid: [
28+
{code: "/*eslint jsx-uses-react:1*/ var React;",
29+
errors: [{message: "React is defined but never used"}], ecmaFeatures: {jsx: true}}
30+
]
31+
});

0 commit comments

Comments
 (0)