Skip to content

Commit

Permalink
[Fix] jsx-uses-react: mark fragment variables as used
Browse files Browse the repository at this point in the history
This allows to use the following syntax:

```jsx
import { createElement, Fragment } from 'react';

function Component {
  return <></>;
}
```

Or more common in Preact:

```jsx
import { Fragment, h } from 'preact';

function Component {
  return <></>;
}
```

The `react.fragment` setting already existed for other rules, but it was
undocumented.
  • Loading branch information
remcohaszing authored and ljharb committed Aug 28, 2020
1 parent ee8f771 commit 911f66e
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -39,6 +39,7 @@ You should also specify settings that will be shared across all the plugin rules
"createClass": "createReactClass", // Regex for Component Factory to use,
// default to "createReactClass"
"pragma": "React", // Pragma to use, default to "React"
"fragment": "React.Fragment", // Fragment to use, default to "React.Fragment"
"version": "detect", // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
Expand Down
6 changes: 5 additions & 1 deletion lib/rules/jsx-uses-react.js
Expand Up @@ -25,6 +25,7 @@ module.exports = {

create(context) {
const pragma = pragmaUtil.getFromContext(context);
const fragment = pragmaUtil.getFragmentFromContext(context);

function handleOpeningElement() {
context.markVariableAsUsed(pragma);
Expand All @@ -35,7 +36,10 @@ module.exports = {

return {
JSXOpeningElement: handleOpeningElement,
JSXOpeningFragment: handleOpeningElement
JSXOpeningFragment: handleOpeningElement,
JSXFragment() {
context.markVariableAsUsed(fragment);
}
};
}
};
17 changes: 12 additions & 5 deletions tests/lib/rules/jsx-uses-react.js
Expand Up @@ -39,14 +39,17 @@ const linter = ruleTester.linter || eslint.linter;
linter.defineRule('jsx-uses-react', require('../../../lib/rules/jsx-uses-react'));

ruleTester.run('no-unused-vars', rule, {
valid: [
valid: [].concat(
{code: '/*eslint jsx-uses-react:1*/ var React; <div />;'},
{code: '/*eslint jsx-uses-react:1*/ var React; (function () { <div /> })();'},
{code: '/*eslint jsx-uses-react:1*/ /** @jsx Foo */ var Foo; <div />;'},
{code: '/*eslint jsx-uses-react:1*/ var Foo; <div />;', settings},
{code: '/*eslint jsx-uses-react:1*/ var React; <></>;', parser: parsers.BABEL_ESLINT}
],
invalid: [{
parsers.TS([
{code: '/*eslint jsx-uses-react:1*/ var Frag; <></>;', settings: {react: {fragment: 'Frag'}}},
{code: '/*eslint jsx-uses-react:1*/ var React; <></>;', parser: parsers.BABEL_ESLINT}
])
),
invalid: [].concat({
code: '/*eslint jsx-uses-react:1*/ var React;',
errors: [{message: '\'React\' is defined but never used.'}]
}, {
Expand All @@ -56,10 +59,14 @@ ruleTester.run('no-unused-vars', rule, {
code: '/*eslint jsx-uses-react:1*/ var React; <div />;',
errors: [{message: '\'React\' is defined but never used.'}],
settings
}, parsers.TS([{
code: '/*eslint jsx-uses-react:1*/ var Frag; <></>;',
errors: [{message: '\'Frag\' is defined but never used.'}],
settings: {react: {fragment: 'Fragment'}}
}, {
code: '/*eslint jsx-uses-react:1*/ var React; <></>;',
parser: parsers.BABEL_ESLINT,
errors: [{message: '\'React\' is defined but never used.'}],
settings
}]
}]))
});

0 comments on commit 911f66e

Please sign in to comment.