Skip to content

Commit dc3a643

Browse files
jomastiljharb
authored andcommitted
[breaking] Add allowGlobals option for jsx-no-undef rule
With the `allowGlobals` enabled, the global scope will be ignored when checking for defined components. Without this option enabled, global variables will not be allowed when checking for defined components.
1 parent 6d1485f commit dc3a643

File tree

3 files changed

+101
-2
lines changed

3 files changed

+101
-2
lines changed

docs/rules/jsx-no-undef.md

+35
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ The following patterns are considered warnings:
1010
<Hello name="John" />;
1111
```
1212

13+
```jsx
14+
// will ignore Text in the global scope and warn
15+
var Hello = React.createClass({
16+
render: function() {
17+
return <Text>Hello</Text>;
18+
}
19+
});
20+
module.exports = Hello;
21+
```
22+
23+
1324
The following patterns are not considered warnings:
1425

1526
```jsx
@@ -18,6 +29,30 @@ var Hello = require('./Hello');
1829
<Hello name="John" />;
1930
```
2031

32+
## Rule Options
33+
34+
```js
35+
...
36+
"react/jsx-no-undef": [<enabled>, { "allowGlobals": <boolean> }]
37+
...
38+
```
39+
40+
### `allowGlobals`
41+
42+
When `true` the rule will consider the global scope when checking for defined Components.
43+
44+
The following patterns are considered okay and do not cause warnings:
45+
46+
```jsx
47+
var Text = require('./Text');
48+
var Hello = React.createClass({
49+
render: function() {
50+
return <Text>Hello</Text>;
51+
}
52+
});
53+
module.exports = Hello;
54+
```
55+
2156
## When Not To Use It
2257

2358
If you are not using JSX then you can disable this rule.

lib/rules/jsx-no-undef.js

+20-2
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,33 @@ module.exports = {
2626
category: 'Possible Errors',
2727
recommended: true
2828
},
29-
schema: []
29+
schema: [{
30+
type: 'object',
31+
properties: {
32+
allowGlobals: {
33+
type: 'boolean'
34+
}
35+
},
36+
additionalProperties: false
37+
}]
3038
},
3139

3240
create: function(context) {
3341

42+
var config = context.options[0] || {};
43+
var allowGlobals = config.allowGlobals || false;
44+
3445
/**
3546
* Compare an identifier with the variables declared in the scope
3647
* @param {ASTNode} node - Identifier or JSXIdentifier node
3748
* @returns {void}
3849
*/
3950
function checkIdentifierInJSX(node) {
4051
var scope = context.getScope();
52+
var sourceCode = context.getSourceCode();
53+
var sourceType = sourceCode.ast.sourceType;
4154
var variables = scope.variables;
55+
var scopeType = 'global';
4256
var i;
4357
var len;
4458

@@ -47,7 +61,11 @@ module.exports = {
4761
return;
4862
}
4963

50-
while (scope.type !== 'global') {
64+
if (!allowGlobals && sourceType === 'module') {
65+
scopeType = 'module';
66+
}
67+
68+
while (scope.type !== scopeType) {
5169
scope = scope.upper;
5270
variables = scope.variables.concat(variables);
5371
}

tests/lib/rules/jsx-no-undef.js

+46
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ ruleTester.run('jsx-no-undef', rule, {
5656
'}'
5757
].join('\n'),
5858
parserOptions: parserOptions
59+
}, {
60+
code: 'var React; React.render(<Text />);',
61+
parserOptions: parserOptions,
62+
globals: {
63+
Text: true
64+
}
65+
}, {
66+
code: [
67+
'import Text from "cool-module";',
68+
'const TextWrapper = function (props) {',
69+
' return (',
70+
' <Text />',
71+
' );',
72+
'};'
73+
].join('\n'),
74+
options: [{
75+
allowGlobals: false
76+
}],
77+
parser: 'babel-eslint',
78+
parserOptions: parserOptions
5979
}],
6080
invalid: [{
6181
code: '/*eslint no-undef:1*/ var React; React.render(<App />);',
@@ -87,5 +107,31 @@ ruleTester.run('jsx-no-undef', rule, {
87107
message: '\'appp\' is not defined.'
88108
}],
89109
parserOptions: parserOptions
110+
}, {
111+
code: [
112+
'const TextWrapper = function (props) {',
113+
' return (',
114+
' <Text />',
115+
' );',
116+
'};',
117+
'export default TextWrapper;'
118+
].join('\n'),
119+
errors: [{
120+
message: '\'Text\' is not defined.'
121+
}],
122+
options: [{
123+
allowGlobals: false
124+
}],
125+
parser: 'babel-eslint',
126+
parserOptions: parserOptions,
127+
globals: {
128+
Text: true
129+
}
130+
}, {
131+
code: '/*eslint no-undef:1*/ var React; React.render(<Foo />);',
132+
errors: [{
133+
message: '\'Foo\' is not defined.'
134+
}],
135+
parserOptions: parserOptions
90136
}]
91137
});

0 commit comments

Comments
 (0)