Skip to content

Commit 53a0d84

Browse files
yacinehmitoljharb
andcommitted
[New] add no-namespace rule
Co-authored-by: Yacine Hmito <[email protected]> Co-authored-by: Jordan Harband <[email protected]>
1 parent f25a8ec commit 53a0d84

File tree

6 files changed

+214
-0
lines changed

6 files changed

+214
-0
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
55

66
## Unreleased
77

8+
### Added
9+
* add [`no-namespace`] rule ([#2640] @yacinehmito @ljharb)
10+
11+
[#2640]: https://github.com/yannickcr/eslint-plugin-react/pull/2640
12+
813
## [7.25.3] - 2021.09.19
914

1015
### Fixed
@@ -3437,6 +3442,7 @@ If you're still not using React 15 you can keep the old behavior by setting the
34373442
[`no-find-dom-node`]: docs/rules/no-find-dom-node.md
34383443
[`no-is-mounted`]: docs/rules/no-is-mounted.md
34393444
[`no-multi-comp`]: docs/rules/no-multi-comp.md
3445+
[`no-namespace`]: docs/rules/no-namespace.md
34403446
[`no-redundant-should-component-update`]: docs/rules/no-redundant-should-component-update.md
34413447
[`no-render-return-value`]: docs/rules/no-render-return-value.md
34423448
[`no-set-state`]: docs/rules/no-set-state.md

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ Enable the rules that you would like to use.
145145
|| | [react/no-find-dom-node](docs/rules/no-find-dom-node.md) | Prevent usage of findDOMNode |
146146
|| | [react/no-is-mounted](docs/rules/no-is-mounted.md) | Prevent usage of isMounted |
147147
| | | [react/no-multi-comp](docs/rules/no-multi-comp.md) | Prevent multiple component definition per file |
148+
| | | [react/no-namespace](docs/rules/no-namespace.md) | Enforce that namespaces are not used in React elements |
148149
| | | [react/no-redundant-should-component-update](docs/rules/no-redundant-should-component-update.md) | Flag shouldComponentUpdate when extending PureComponent |
149150
|| | [react/no-render-return-value](docs/rules/no-render-return-value.md) | Prevent usage of the return value of React.render |
150151
| | | [react/no-set-state](docs/rules/no-set-state.md) | Prevent usage of setState |

docs/rules/no-namespace.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Enforce that namespaces are not used in React elements (react/no-namespace)
2+
3+
Enforces the absence of a namespace in React elements, such as with `svg:circle`, as they are not supported in React.
4+
5+
## Rule Details
6+
7+
The following patterns are considered warnings:
8+
9+
```jsx
10+
<ns:TestComponent />
11+
```
12+
13+
```jsx
14+
<Ns:TestComponent />
15+
```
16+
17+
The following patterns are **not** considered warnings:
18+
19+
```jsx
20+
<TestComponent />
21+
```
22+
23+
```jsx
24+
<testComponent />
25+
```
26+
27+
## When not to use
28+
29+
If you are not using React.

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ const allRules = {
6767
'no-find-dom-node': require('./lib/rules/no-find-dom-node'),
6868
'no-is-mounted': require('./lib/rules/no-is-mounted'),
6969
'no-multi-comp': require('./lib/rules/no-multi-comp'),
70+
'no-namespace': require('./lib/rules/no-namespace'),
7071
'no-set-state': require('./lib/rules/no-set-state'),
7172
'no-string-refs': require('./lib/rules/no-string-refs'),
7273
'no-redundant-should-component-update': require('./lib/rules/no-redundant-should-component-update'),

lib/rules/no-namespace.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* @fileoverview Enforce that namespaces are not used in React elements
3+
* @author Yacine Hmito
4+
*/
5+
6+
'use strict';
7+
8+
const elementType = require('jsx-ast-utils/elementType');
9+
const docsUrl = require('../util/docsUrl');
10+
const isCreateElement = require('../util/isCreateElement');
11+
12+
// ------------------------------------------------------------------------------
13+
// Rule Definition
14+
// ------------------------------------------------------------------------------
15+
16+
module.exports = {
17+
meta: {
18+
docs: {
19+
description: 'Enforce that namespaces are not used in React elements',
20+
category: 'Possible Errors',
21+
recommended: false,
22+
url: docsUrl('no-namespace')
23+
},
24+
25+
schema: [{
26+
type: 'object',
27+
additionalProperties: false
28+
}]
29+
},
30+
31+
create(context) {
32+
return {
33+
CallExpression(node) {
34+
if (isCreateElement(node, context) && node.arguments.length > 0 && node.arguments[0].type === 'Literal') {
35+
const name = node.arguments[0].value;
36+
if (name.indexOf(':') === -1) return undefined;
37+
const message = `React component ${name} must not be in a namespace as React does not support them`;
38+
context.report({node, message});
39+
}
40+
},
41+
JSXOpeningElement(node) {
42+
const name = elementType(node);
43+
if (name.indexOf(':') === -1) return undefined;
44+
const message = `React component ${name} must not be in a namespace as React does not support them`;
45+
context.report({node, message});
46+
}
47+
};
48+
}
49+
};

tests/lib/rules/no-namespace.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/**
2+
* @fileoverview Tests for jsx-no-namespace
3+
* @author Yacine Hmito
4+
*/
5+
6+
'use strict';
7+
8+
// ------------------------------------------------------------------------------
9+
// Requirements
10+
// ------------------------------------------------------------------------------
11+
12+
const RuleTester = require('eslint').RuleTester;
13+
const rule = require('../../../lib/rules/no-namespace');
14+
15+
const parserOptions = {
16+
ecmaVersion: 2018,
17+
sourceType: 'module',
18+
ecmaFeatures: {
19+
jsx: true
20+
}
21+
};
22+
23+
// ------------------------------------------------------------------------------
24+
// Tests
25+
// ------------------------------------------------------------------------------
26+
27+
const ruleTester = new RuleTester({parserOptions});
28+
ruleTester.run('jsx-no-namespace', rule, {
29+
valid: [{
30+
code: '<testcomponent />'
31+
}, {
32+
code: 'React.createElement("testcomponent")'
33+
}, {
34+
code: '<testComponent />'
35+
}, {
36+
code: 'React.createElement("testComponent")'
37+
}, {
38+
code: '<test_component />'
39+
}, {
40+
code: 'React.createElement("test_component")'
41+
}, {
42+
code: '<TestComponent />'
43+
}, {
44+
code: 'React.createElement("TestComponent")'
45+
}, {
46+
code: '<object.testcomponent />'
47+
}, {
48+
code: 'React.createElement("object.testcomponent")'
49+
}, {
50+
code: '<object.testComponent />'
51+
}, {
52+
code: 'React.createElement("object.testComponent")'
53+
}, {
54+
code: '<object.test_component />'
55+
}, {
56+
code: 'React.createElement("object.test_component")'
57+
}, {
58+
code: '<object.TestComponent />'
59+
}, {
60+
code: 'React.createElement("object.TestComponent")'
61+
}, {
62+
code: '<Object.testcomponent />'
63+
}, {
64+
code: 'React.createElement("Object.testcomponent")'
65+
}, {
66+
code: '<Object.testComponent />'
67+
}, {
68+
code: 'React.createElement("Object.testComponent")'
69+
}, {
70+
code: '<Object.test_component />'
71+
}, {
72+
code: 'React.createElement("Object.test_component")'
73+
}, {
74+
code: '<Object.TestComponent />'
75+
}, {
76+
code: 'React.createElement("Object.TestComponent")'
77+
}],
78+
79+
invalid: [{
80+
code: '<ns:testcomponent />',
81+
errors: [{message: 'React component ns:testcomponent must not be in a namespace as React does not support them'}]
82+
}, {
83+
code: 'React.createElement("ns:testcomponent")',
84+
errors: [{message: 'React component ns:testcomponent must not be in a namespace as React does not support them'}]
85+
}, {
86+
code: '<ns:testComponent />',
87+
errors: [{message: 'React component ns:testComponent must not be in a namespace as React does not support them'}]
88+
}, {
89+
code: 'React.createElement("ns:testComponent")',
90+
errors: [{message: 'React component ns:testComponent must not be in a namespace as React does not support them'}]
91+
}, {
92+
code: '<ns:test_component />',
93+
errors: [{message: 'React component ns:test_component must not be in a namespace as React does not support them'}]
94+
}, {
95+
code: 'React.createElement("ns:test_component")',
96+
errors: [{message: 'React component ns:test_component must not be in a namespace as React does not support them'}]
97+
}, {
98+
code: '<ns:TestComponent />',
99+
errors: [{message: 'React component ns:TestComponent must not be in a namespace as React does not support them'}]
100+
}, {
101+
code: 'React.createElement("ns:TestComponent")',
102+
errors: [{message: 'React component ns:TestComponent must not be in a namespace as React does not support them'}]
103+
}, {
104+
code: '<Ns:testcomponent />',
105+
errors: [{message: 'React component Ns:testcomponent must not be in a namespace as React does not support them'}]
106+
}, {
107+
code: 'React.createElement("Ns:testcomponent")',
108+
errors: [{message: 'React component Ns:testcomponent must not be in a namespace as React does not support them'}]
109+
}, {
110+
code: '<Ns:testComponent />',
111+
errors: [{message: 'React component Ns:testComponent must not be in a namespace as React does not support them'}]
112+
}, {
113+
code: 'React.createElement("Ns:testComponent")',
114+
errors: [{message: 'React component Ns:testComponent must not be in a namespace as React does not support them'}]
115+
}, {
116+
code: '<Ns:test_component />',
117+
errors: [{message: 'React component Ns:test_component must not be in a namespace as React does not support them'}]
118+
}, {
119+
code: 'React.createElement("Ns:test_component")',
120+
errors: [{message: 'React component Ns:test_component must not be in a namespace as React does not support them'}]
121+
}, {
122+
code: '<Ns:TestComponent />',
123+
errors: [{message: 'React component Ns:TestComponent must not be in a namespace as React does not support them'}]
124+
}, {
125+
code: 'React.createElement("Ns:TestComponent")',
126+
errors: [{message: 'React component Ns:TestComponent must not be in a namespace as React does not support them'}]
127+
}]
128+
});

0 commit comments

Comments
 (0)