Skip to content

Commit

Permalink
Add jsx-uses-react rule
Browse files Browse the repository at this point in the history
This rule somewhat unusual, in that it modifies the behaviour
of a core eslint rule. The alternative would be to copy-paste
the original rule and modify it. That would require users to
disable the core rule and replace with this one
  • Loading branch information
glenjamin committed Mar 1, 2015
1 parent 9c43de0 commit ca87883
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
29 changes: 29 additions & 0 deletions docs/rules/jsx-uses-react.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Make JSX count towards use of a declared variable (jsx-uses-react)

JSX expands to a call to `React.createElement`, a file which includes `React`
but only uses JSX should still consider the `React` variable used.

This rule has no effect if the `no-unused-vars` rule is not enabled.

## Rule Details

The following patterns are considered warnings:

```js
var React = require('react'); // and other equivalent imports

// nothing to do with React
```

The following patterns are not considered warnings:

```js
var React = require('react');

var elem = <div>Some Stuff</div>;
```

## When Not To Use It

If you are not using JSX, or React is delcared as global variable, this rule
will not be useful.
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

module.exports = {
rules: {
'jsx-uses-react': require('./lib/rules/jsx-uses-react'),
'no-multi-comp': require('./lib/rules/no-multi-comp'),
'prop-types': require('./lib/rules/prop-types'),
'display-name': require('./lib/rules/display-name'),
Expand All @@ -11,6 +12,7 @@ module.exports = {
'no-did-update-set-state': require('./lib/rules/no-did-update-set-state')
},
rulesConfig: {
'jsx-uses-react': 0,
'no-multi-comp': 0,
'prop-types': 0,
'display-name': 0,
Expand Down
44 changes: 44 additions & 0 deletions lib/rules/jsx-uses-react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* @fileoverview Count <Jsx /> as use of the React variable
* @author Glen Mailer
*/
'use strict';

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = function(context) {

function flagReactAsUsedInJSX() {
var scope = context.getScope(),
variables = scope.variables,
i,
len;

while (scope.type !== "global") {
scope = scope.upper;
variables = [].concat.apply(scope.variables, variables);
}

// mark first React found with the same special flag used by no-unused-vars
for (i = 0, len = variables.length; i < len; i++) {
if (variables[i].name === 'React') {
variables[i].eslintJSXUsed = true;
return;
}
}
}

// --------------------------------------------------------------------------
// Public
// --------------------------------------------------------------------------

return {

'JSXOpeningElement': function() {
flagReactAsUsedInJSX();
}
};

};
31 changes: 31 additions & 0 deletions tests/lib/rules/jsx-uses-react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* @fileoverview Tests for jsx-uses-react
* @author Glen Mailer
*/

"use strict";

// -----------------------------------------------------------------------------
// Requirements
// -----------------------------------------------------------------------------

var eslint = require('eslint').linter;
var ESLintTester = require('eslint-tester');

// -----------------------------------------------------------------------------
// Tests
// -----------------------------------------------------------------------------

var eslintTester = new ESLintTester(eslint);
eslint.defineRule('jsx-uses-react', require('../../../lib/rules/jsx-uses-react'));
eslintTester.addRuleTest("node_modules/eslint/lib/rules/no-unused-vars", {
valid: [
{code: "/*eslint jsx-uses-react:1*/ var App, React; <App />;", ecmaFeatures: {jsx: true}},
{code: "/*eslint jsx-uses-react:1*/ var React; <div />;", ecmaFeatures: {jsx: true}},
{code: "/*eslint jsx-uses-react:1*/ var React; (function () { <div /> })();", ecmaFeatures: {jsx: true}}
],
invalid: [
{code: "/*eslint jsx-uses-react:1*/ var React;",
errors: [{message: "React is defined but never used"}], ecmaFeatures: {jsx: true}}
]
});

0 comments on commit ca87883

Please sign in to comment.