Skip to content

Commit 794a05a

Browse files
committed
Add ignoreStateless option to no-multi-comp (fixes #290)
1 parent 2929aaa commit 794a05a

File tree

3 files changed

+122
-2
lines changed

3 files changed

+122
-2
lines changed

docs/rules/no-multi-comp.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,41 @@ var HelloJohn = React.createClass({
3232
});
3333
```
3434

35+
## Rule Options
36+
37+
```js
38+
...
39+
"no-multi-comp": [<enabled>, { "ignoreStateless": <boolean> }]
40+
...
41+
```
42+
43+
### `ignoreStateless`
44+
45+
When `true` the rule will ignore stateless components and will allow you to have multiple stateless components, or one statefull component and some stateless components in the same file.
46+
47+
The following patterns are considered okay and do not cause warnings:
48+
49+
```js
50+
function Hello(props) {
51+
return <div>Hello {props.name}</div>;
52+
}
53+
function HelloAgain(props) {
54+
return <div>Hello again {props.name}</div>;
55+
}
56+
```
57+
58+
```js
59+
function Hello(props) {
60+
return <div>Hello {props.name}</div>;
61+
}
62+
class HelloJohn extends React.Component {
63+
render() {
64+
return <Hello name="John" />;
65+
}
66+
}
67+
module.exports = HelloJohn;
68+
```
69+
3570
## When Not To Use It
3671

3772
If you prefer to declare multiple components per files you can disable this rule.

lib/rules/no-multi-comp.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,20 @@ var Components = require('../util/Components');
1212

1313
module.exports = Components.detect(function(context, components) {
1414

15+
var configuration = context.options[0] || {};
16+
var ignoreStateless = configuration.ignoreStateless || false;
17+
1518
var MULTI_COMP_MESSAGE = 'Declare only one React component per file';
1619

20+
/**
21+
* Checks if the component is ignored
22+
* @param {Object} component The component being checked.
23+
* @returns {Boolean} True if the component is ignored, false if not.
24+
*/
25+
function isIgnored(component) {
26+
return ignoreStateless === true && /Function/.test(component.node.type);
27+
}
28+
1729
// --------------------------------------------------------------------------
1830
// Public
1931
// --------------------------------------------------------------------------
@@ -28,7 +40,7 @@ module.exports = Components.detect(function(context, components) {
2840
var i = 0;
2941

3042
for (var component in list) {
31-
if (!list.hasOwnProperty(component) || ++i === 1) {
43+
if (!list.hasOwnProperty(component) || isIgnored(list[component]) || ++i === 1) {
3244
continue;
3345
}
3446
context.report(list[component].node, MULTI_COMP_MESSAGE);
@@ -37,4 +49,13 @@ module.exports = Components.detect(function(context, components) {
3749
};
3850
});
3951

40-
module.exports.schema = [];
52+
module.exports.schema = [{
53+
type: 'object',
54+
properties: {
55+
ignoreStateless: {
56+
default: false,
57+
type: 'boolean'
58+
}
59+
},
60+
additionalProperties: false
61+
}];

tests/lib/rules/no-multi-comp.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,37 @@ ruleTester.run('no-multi-comp', rule, {
7676
'};'
7777
].join('\n'),
7878
parser: 'babel-eslint'
79+
}, {
80+
code: [
81+
'function Hello(props) {',
82+
' return <div>Hello {props.name}</div>;',
83+
'}',
84+
'function HelloAgain(props) {',
85+
' return <div>Hello again {props.name}</div>;',
86+
'}'
87+
].join('\n'),
88+
parser: 'babel-eslint',
89+
options: [{
90+
ignoreStateless: true
91+
}]
92+
}, {
93+
code: [
94+
'function Hello(props) {',
95+
' return <div>Hello {props.name}</div>;',
96+
'}',
97+
'class HelloJohn extends React.Component {',
98+
' render() {',
99+
' return <Hello name="John" />;',
100+
' }',
101+
'}'
102+
].join('\r'),
103+
ecmaFeatures: {
104+
classes: true,
105+
jsx: true
106+
},
107+
options: [{
108+
ignoreStateless: true
109+
}]
79110
}],
80111

81112
invalid: [{
@@ -127,5 +158,38 @@ ruleTester.run('no-multi-comp', rule, {
127158
message: 'Declare only one React component per file',
128159
line: 11
129160
}]
161+
}, {
162+
code: [
163+
'function Hello(props) {',
164+
' return <div>Hello {props.name}</div>;',
165+
'}',
166+
'function HelloAgain(props) {',
167+
' return <div>Hello again {props.name}</div>;',
168+
'}'
169+
].join('\n'),
170+
parser: 'babel-eslint',
171+
errors: [{
172+
message: 'Declare only one React component per file',
173+
line: 4
174+
}]
175+
}, {
176+
code: [
177+
'function Hello(props) {',
178+
' return <div>Hello {props.name}</div>;',
179+
'}',
180+
'class HelloJohn extends React.Component {',
181+
' render() {',
182+
' return <Hello name="John" />;',
183+
' }',
184+
'}'
185+
].join('\r'),
186+
ecmaFeatures: {
187+
classes: true,
188+
jsx: true
189+
},
190+
errors: [{
191+
message: 'Declare only one React component per file',
192+
line: 4
193+
}]
130194
}]
131195
});

0 commit comments

Comments
 (0)