Skip to content

Commit cfc6a6b

Browse files
author
Yannick Croissant
committed
Add display-name rule
1 parent fda9f8f commit cfc6a6b

File tree

5 files changed

+131
-7
lines changed

5 files changed

+131
-7
lines changed

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,23 @@ Finally, enable all of the rules that you would like to use.
4444
{
4545
"rules": {
4646
"react/no-multi-comp": 1,
47-
"react/prop-types": 1
47+
"react/prop-types": 1,
48+
"react/display-name": 1
4849
}
4950
}
5051
```
5152

5253
# List of supported rules
5354

54-
* no-multi-comp: Prevent multiple component definition per file
55-
* prop-types: Prevent missing propTypes in a React component definition
55+
* [no-multi-comp](docs/rules/no-multi-comp.md): Prevent multiple component definition per file
56+
* [prop-types](docs/rules/prop-types.md): Prevent missing propTypes in a React component definition
57+
* [display-name](docs/rules/display-name.md): Prevent missing displayName in a React component definition
5658

57-
## Not supported yet
59+
## To Do
5860

59-
* display-name: Prevent missing displayName in a React component definition
6061
* no-deprecated: Prevent usage of deprecated methods ([React 0.12 Updated API](http://facebook.github.io/react/blog/2014/10/28/react-v0.12.html#new-terminology-amp-updated-apis))
6162
* no-classic: Prevent usage of "classic" methods ([#2700](https://github.com/facebook/react/pull/2700))
63+
* [Implement rules from David Chang's React Style Guide](https://reactjsnews.com/react-style-guide-patterns-i-like)
6264

6365
[Any rule idea is welcome !](https://github.com/yannickcr/eslint-plugin-react/issues)
6466

docs/rules/display-name.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Prevent missing displayName in a React component definition (display-name)
2+
3+
DisplayName allows you to name your component. This name is used by React in debugging messages.
4+
5+
## Rule Details
6+
7+
The following patterns are considered warnings:
8+
9+
```js
10+
var Hello = React.createClass({
11+
render: function() {
12+
return <div>Hello {this.props.name}</div>;
13+
}
14+
});
15+
```
16+
17+
The following patterns are not warnings:
18+
19+
```js
20+
var Hello = React.createClass({
21+
displayName: 'Hello',
22+
render: function() {
23+
return <div>Hello {this.props.name}</div>;
24+
}
25+
});
26+
```
27+
28+
## When Not To Use It
29+
30+
If you are using JSX this value is already automatically set and it is safe for you to disable this rule.

index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
module.exports = {
44
rules: {
55
'no-multi-comp': require('./lib/rules/no-multi-comp'),
6-
'prop-types': require('./lib/rules/prop-types')
6+
'prop-types': require('./lib/rules/prop-types'),
7+
'display-name': require('./lib/rules/display-name')
78
},
89
rulesConfig: {
910
'no-multi-comp': 0,
10-
'prop-types': 0
11+
'prop-types': 0,
12+
'display-name': 0
1113
}
1214
};

lib/rules/display-name.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @fileoverview Prevent missing displayName in a React component definition
3+
* @author Yannick Croissant
4+
*/
5+
'use strict';
6+
7+
// ------------------------------------------------------------------------------
8+
// Rule Definition
9+
// ------------------------------------------------------------------------------
10+
11+
module.exports = function(context) {
12+
13+
var hasDisplayName = false;
14+
15+
// --------------------------------------------------------------------------
16+
// Public
17+
// --------------------------------------------------------------------------
18+
19+
return {
20+
21+
'ObjectExpression': function(node) {
22+
23+
if (!node.parent.callee || node.parent.callee.object.name !== 'React' || node.parent.callee.property.name !== 'createClass') {
24+
return;
25+
}
26+
27+
node.properties.forEach(function(property) {
28+
var keyName = property.key.name || property.key.value;
29+
if (keyName === 'displayName') {
30+
hasDisplayName = true;
31+
}
32+
});
33+
34+
},
35+
36+
'ObjectExpression:exit': function(node) {
37+
if (!node.parent.callee || node.parent.callee.object.name !== 'React' || node.parent.callee.property.name !== 'createClass') {
38+
return;
39+
}
40+
if (!hasDisplayName) {
41+
context.report(node, 'Component definition is missing display name');
42+
}
43+
hasDisplayName = false;
44+
}
45+
};
46+
47+
};

tests/lib/rules/display-name.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @fileoverview Prevent missing displayName in a React component definition
3+
* @author Yannick Croissant
4+
*/
5+
'use strict';
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
var eslint = require('eslint').linter;
12+
var ESLintTester = require('eslint-tester');
13+
14+
// ------------------------------------------------------------------------------
15+
// Tests
16+
// ------------------------------------------------------------------------------
17+
18+
var eslintTester = new ESLintTester(eslint);
19+
eslintTester.addRuleTest('lib/rules/display-name', {
20+
21+
valid: [
22+
{
23+
code: 'var Hello = React.createClass({displayName: \'Hello\',render: function() {return <div>Hello {this.props.name}</div>;}});',
24+
settings: {
25+
ecmascript: 6,
26+
jsx: true
27+
}
28+
}
29+
],
30+
31+
invalid: [
32+
{
33+
code: 'var Hello = React.createClass({render: function() {return <div>Hello {this.props.name}</div>;}});',
34+
settings: {
35+
ecmascript: 6,
36+
jsx: true
37+
},
38+
errors: [{
39+
message: 'Component definition is missing display name'
40+
}]
41+
}
42+
]
43+
});

0 commit comments

Comments
 (0)