Skip to content

Commit

Permalink
Merge pull request #250 from hamiltondanielb/master
Browse files Browse the repository at this point in the history
Add prefer-es6-class rule (fixes #247)
  • Loading branch information
yannickcr committed Oct 18, 2015
2 parents 7bbbda7 + 06229ab commit 75ca44e
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 3 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ Finally, enable all of the rules that you would like to use.
"react/require-extension": 1,
"react/self-closing-comp": 1,
"react/sort-comp": 1,
"react/wrap-multilines": 1
"react/wrap-multilines": 1,
"prefer-es6-class": 1,
}
}
```
Expand Down Expand Up @@ -108,6 +109,7 @@ Finally, enable all of the rules that you would like to use.
* [self-closing-comp](docs/rules/self-closing-comp.md): Prevent extra closing tags for components without children
* [sort-comp](docs/rules/sort-comp.md): Enforce component methods order
* [wrap-multilines](docs/rules/wrap-multilines.md): Prevent missing parentheses around multilines JSX
* [prefer-es6-class](docs/rules/prefer-es6-class.md): Prefer es6 class instead of createClass for React Components

## To Do

Expand Down
27 changes: 27 additions & 0 deletions docs/rules/prefer-es6-class.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ES6 class bodies are more terse than traditional object literals. Methods do not require a `function` keyword and no commas are needed to separate them. This refactoring looks as such:

Invalid:

```js
var ExampleComponent = React.createClass({
render: function() {
return <div onClick={this._handleClick}>Hello, world.</div>;
},
_handleClick: function() {
console.log(this);
}
});
```

Valid:

```js
class ExampleComponent extends React.Component {
render() {
return <div onClick={this._handleClick}>Hello, world.</div>;
}
_handleClick() {
console.log(this);
}
}
```
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ module.exports = {
'jsx-indent-props': require('./lib/rules/jsx-indent-props'),
'jsx-closing-bracket-location': require('./lib/rules/jsx-closing-bracket-location'),
'no-direct-mutation-state': require('./lib/rules/no-direct-mutation-state'),
'forbid-prop-types': require('./lib/rules/forbid-prop-types')
'forbid-prop-types': require('./lib/rules/forbid-prop-types'),
'prefer-es6-class': require('./lib/rules/prefer-es6-class')
},
rulesConfig: {
'jsx-uses-react': 0,
Expand Down Expand Up @@ -59,6 +60,7 @@ module.exports = {
'jsx-indent-props': 0,
'jsx-closing-bracket-location': 0,
'no-direct-mutation-state': 0,
'forbid-prop-types': 0
'forbid-prop-types': 0,
'prefer-es6-class': 0
}
};
24 changes: 24 additions & 0 deletions lib/rules/prefer-es6-class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @fileoverview Prefer es6 class instead of createClass for React Component
* @author Dan Hamilton
*/
'use strict';

var componentUtil = require('../util/component');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = function(context) {

return {
ObjectExpression: function(node) {
if (componentUtil.isComponentDefinition(context, node)) {
context.report(node, 'Component should use es6 class instead of createClass');
}
}
};
};

module.exports.schema = [];
65 changes: 65 additions & 0 deletions tests/lib/rules/prefer-es6-class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @fileoverview Prefer es6 class instead of createClass for React Component
* @author Dan Hamilton
*/
'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

var rule = require('../../../lib/rules/prefer-es6-class');
var RuleTester = require('eslint').RuleTester;

require('babel-eslint');

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

var ruleTester = new RuleTester();
ruleTester.run('prefer-es6-class', rule, {

valid: [{
code: [
'class Hello extends React.Component {',
' render() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'}',
'Hello.displayName = \'Hello\''
].join('\n'),
ecmaFeatures: {
classes: true,
jsx: true
}
}, {
code: [
'var Hello = "foo";',
'module.exports = {};'
].join('\n'),
ecmaFeatures: {
jsx: true
}
}

],

invalid: [{
code: [
'var Hello = React.createClass({',
' displayName: \'Hello\',',
' render: function() {',
' return <div>Hello {this.props.name}</div>;',
' }',
'});'
].join('\n'),
ecmaFeatures: {
classes: true,
jsx: true
},
errors: [{
message: 'Component should use es6 class instead of createClass'
}]
}
]});

0 comments on commit 75ca44e

Please sign in to comment.