diff --git a/README.md b/README.md
index 32c966ce98..e10cca35ea 100644
--- a/README.md
+++ b/README.md
@@ -346,6 +346,54 @@ Other Style Guides
const nodes = Array.from(foo);
```
+ - [4.5](#4.5) Use return statements in array method callbacks. It's ok to omit the return if the function body consists of a single statement following [8.2](#8.2). eslint: [`array-callback-return`](http://eslint.org/docs/rules/array-callback-return)
+
+ ```javascript
+ // good
+ [1, 2, 3].map((x) => {
+ const y = x + 1;
+ return x * y;
+ });
+
+ // good
+ [1, 2, 3].map(x => x + 1);
+
+ // bad
+ const flat = {};
+ [[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
+ const flatten = memo.concat(item);
+ flat[index] = memo.concat(item);
+ });
+
+ // good
+ const flat = {};
+ [[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
+ const flatten = memo.concat(item);
+ flat[index] = flatten;
+ return flatten;
+ });
+
+ // bad
+ inbox.filter((msg) => {
+ const { subject, author } = msg;
+ if (subject === 'Mockingbird') {
+ return author === 'Harper Lee';
+ } else {
+ return false;
+ }
+ });
+
+ // good
+ inbox.filter((msg) => {
+ const { subject, author } = msg;
+ if (subject === 'Mockingbird') {
+ return author === 'Harper Lee';
+ }
+
+ return false;
+ });
+ ```
+
**[⬆ back to top](#table-of-contents)**
## Destructuring
@@ -447,7 +495,7 @@ Other Style Guides
```
- - [6.4](#6.4) When programmatically building up strings, use template strings instead of concatenation. eslint: [`prefer-template`](http://eslint.org/docs/rules/prefer-template.html) jscs: [`requireTemplateStrings`](http://jscs.info/rule/requireTemplateStrings)
+ - [6.4](#6.4) When programmatically building up strings, use template strings instead of concatenation. eslint: [`prefer-template`](http://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](http://eslint.org/docs/rules/template-curly-spacing) jscs: [`requireTemplateStrings`](http://jscs.info/rule/requireTemplateStrings)
> Why? Template strings give you a readable, concise syntax with proper newlines and string interpolation features.
@@ -462,6 +510,11 @@ Other Style Guides
return ['How are you, ', name, '?'].join();
}
+ // bad
+ function sayHi(name) {
+ return `How are you, ${ name }?`;
+ }
+
// good
function sayHi(name) {
return `How are you, ${name}?`;
@@ -535,7 +588,7 @@ Other Style Guides
```
- - [7.6](#7.6) Never use `arguments`, opt to use rest syntax `...` instead.
+ - [7.6](#7.6) Never use `arguments`, opt to use rest syntax `...` instead. [`prefer-rest-params`](http://eslint.org/docs/rules/prefer-rest-params)
> Why? `...` is explicit about which arguments you want pulled. Plus rest arguments are a real Array and not Array-like like `arguments`.
@@ -771,6 +824,19 @@ Other Style Guides
});
```
+ - [8.5](#8.5) Avoid confusing arrow function syntax (`=>`) with comparison operators (`<=`, `>=`). eslint: [`no-confusing-arrow`](http://eslint.org/docs/rules/no-confusing-arrow)
+
+ ```js
+ // bad
+ const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
+
+ // bad
+ const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
+
+ // good
+ const itemHeight = item => { return item.height > 256 ? item.largeSize : item.smallSize; }
+ ```
+
**[⬆ back to top](#table-of-contents)**
@@ -883,6 +949,34 @@ Other Style Guides
}
```
+ - [9.5](#9.5) Classes have a default constructor if one is not specified. An empty constructor function or one that just delegates to a parent class is unnecessary. [`no-useless-constructor`](http://eslint.org/docs/rules/no-useless-constructor)
+
+ ```javascript
+ // bad
+ class Jedi {
+ constructor() {}
+
+ getName() {
+ return this.name;
+ }
+ }
+
+ // bad
+ class Rey extends Jedi {
+ constructor(...args) {
+ super(args);
+ }
+ }
+
+ // good
+ class Rey extends Jedi {
+ constructor(...args) {
+ super(args);
+ this.name = 'Rey';
+ }
+ }
+ ```
+
**[⬆ back to top](#table-of-contents)**
@@ -1592,8 +1686,8 @@ Other Style Guides
})(this);↵
```
- - [18.6](#18.6) Use indentation when making long method chains. Use a leading dot, which
- emphasizes that the line is a method call, not a new statement.
+ - [18.6](#18.6) Use indentation when making long method chains (more than 2 method chains). Use a leading dot, which
+ emphasizes that the line is a method call, not a new statement. eslint: [`newline-per-chained-call`](http://eslint.org/docs/rules/newline-per-chained-call) [`no-whitespace-before-property`](http://eslint.org/docs/rules/no-whitespace-before-property)
```javascript
// bad
@@ -1630,6 +1724,9 @@ Other Style Guides
.append('svg:g')
.attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
.call(tron.led);
+
+ // good
+ const leds = stage.selectAll('.led').data(data);
```
- [18.7](#18.7) Leave a blank line after blocks and before the next statement. jscs: [`requirePaddingNewLinesAfterBlocks`](http://jscs.info/rule/requirePaddingNewLinesAfterBlocks)
diff --git a/packages/eslint-config-airbnb/CHANGELOG.md b/packages/eslint-config-airbnb/CHANGELOG.md
index 7c47c680f5..fcb16ec26c 100644
--- a/packages/eslint-config-airbnb/CHANGELOG.md
+++ b/packages/eslint-config-airbnb/CHANGELOG.md
@@ -1,3 +1,21 @@
+6.0.0 / 2016-02-21
+==================
+- [breaking] enable `array-callback-return`
+- [breaking] enable `no-confusing-arrow`
+- [breaking] enable `no-new-symbol`
+- [breaking] enable `no-restricted-imports`
+- [breaking] enable `no-useless-constructor`
+- [breaking] enable `prefer-rest-params`
+- [breaking] enable `template-curly-spaces`
+- [breaking] enable `newline-per-chained-call`
+- [breaking] enable `one-var-declaration-per-line`
+- [breaking] enable `no-self-assign`
+- [breaking] enable `no-whitespace-before-property`
+- [breaking] [react] enable `react/jsx-space-before-closing`
+- [breaking] [react] enable `static-methods` at top of `react/sort-comp`
+- [breaking] [react] don't `ignoreTranspilerName` for `react/display-name`
+- [peer+dev deps] update `eslint`, `eslint-plugin-react`
+
5.0.1 / 2016-02-13
==================
- [fix] `eslint` peerDep should not include breaking changes
diff --git a/packages/eslint-config-airbnb/package.json b/packages/eslint-config-airbnb/package.json
index 6b5cad58b5..dd54ae754e 100644
--- a/packages/eslint-config-airbnb/package.json
+++ b/packages/eslint-config-airbnb/package.json
@@ -43,14 +43,14 @@
"homepage": "https://github.com/airbnb/javascript",
"devDependencies": {
"babel-tape-runner": "1.2.0",
- "eslint": "^1.10.3",
- "eslint-plugin-react": "^3.16.1",
+ "eslint": "^2.2.0",
+ "eslint-plugin-react": "^4.0.0",
"react": "^0.14.7",
"tape": "^4.4.0",
"parallelshell": "^2.0.0"
},
"peerDependencies": {
- "eslint": "^1.0.0",
- "eslint-plugin-react": "^3.16.1"
+ "eslint": "^2.2.0",
+ "eslint-plugin-react": "^4.0.0"
}
}
diff --git a/packages/eslint-config-airbnb/rules/best-practices.js b/packages/eslint-config-airbnb/rules/best-practices.js
index a221d4d999..6f66792478 100644
--- a/packages/eslint-config-airbnb/rules/best-practices.js
+++ b/packages/eslint-config-airbnb/rules/best-practices.js
@@ -2,6 +2,9 @@ module.exports = {
'rules': {
// enforces getter/setter pairs in objects
'accessor-pairs': 0,
+ // enforces return statements in callbacks of array's methods
+ // http://eslint.org/docs/rules/array-callback-return
+ 'array-callback-return': 2,
// treat var statements as if they were block scoped
'block-scoped-var': 2,
// specify the maximum cyclomatic complexity allowed in a program
@@ -20,6 +23,9 @@ module.exports = {
'eqeqeq': 2,
// make sure for-in loops have an if statement
'guard-for-in': 2,
+ // Blacklist certain identifiers to prevent them being used
+ // http://eslint.org/docs/rules/id-blacklist
+ 'id-blacklist': 0,
// disallow the use of alert, confirm, and prompt
'no-alert': 1,
// disallow use of arguments.caller or arguments.callee
@@ -31,8 +37,9 @@ module.exports = {
'no-div-regex': 0,
// disallow else after a return in an if
'no-else-return': 2,
- // disallow use of labels for anything other then loops and switches
- 'no-empty-label': 2,
+ // disallow Unnecessary Labels
+ // http://eslint.org/docs/rules/no-extra-label
+ 'no-extra-label': 2,
// disallow comparisons to null without a type-checking operator
'no-eq-null': 0,
// disallow use of eval()
@@ -53,8 +60,8 @@ module.exports = {
'no-invalid-this': 0,
// disallow usage of __iterator__ property
'no-iterator': 2,
- // disallow use of labeled statements
- 'no-labels': 2,
+ // disallow use of labels for anything other then loops and switches
+ 'no-labels': [2, { 'allowLoop': false, 'allowSwitch': false }],
// disallow unnecessary nested blocks
'no-lone-blocks': 2,
// disallow creation of functions within loops
@@ -96,8 +103,14 @@ module.exports = {
'no-sequences': 2,
// restrict what can be thrown as an exception
'no-throw-literal': 2,
+ // disallow unmodified conditions of loops
+ // http://eslint.org/docs/rules/no-unmodified-loop-condition
+ 'no-unmodified-loop-condition': 0,
// disallow usage of expressions in statement position
'no-unused-expressions': 2,
+ // disallow unused labels
+ // http://eslint.org/docs/rules/no-unused-labels
+ 'no-unused-labels': 2,
// disallow unnecessary .call() and .apply()
'no-useless-call': 0,
// disallow use of void operator
diff --git a/packages/eslint-config-airbnb/rules/es6.js b/packages/eslint-config-airbnb/rules/es6.js
index f28a436ba3..e88b2d5059 100644
--- a/packages/eslint-config-airbnb/rules/es6.js
+++ b/packages/eslint-config-airbnb/rules/es6.js
@@ -1,25 +1,15 @@
module.exports = {
'env': {
- 'es6': false
+ 'es6': true
},
- 'ecmaFeatures': {
- 'arrowFunctions': true,
- 'blockBindings': true,
- 'classes': true,
- 'defaultParams': true,
- 'destructuring': true,
- 'forOf': true,
- 'generators': false,
- 'modules': true,
- 'objectLiteralComputedProperties': true,
- 'objectLiteralDuplicateProperties': false,
- 'objectLiteralShorthandMethods': true,
- 'objectLiteralShorthandProperties': true,
- 'restParams': true,
- 'spread': true,
- 'superInFunctions': true,
- 'templateStrings': true,
- 'jsx': true
+ 'parserOptions': {
+ 'ecmaVersion': 6,
+ 'sourceType': 'module',
+ 'ecmaFeatures': {
+ 'jsx': true,
+ 'generators': false,
+ 'objectLiteralDuplicateProperties': false
+ }
},
'rules': {
// enforces no braces where they can be omitted
@@ -38,12 +28,24 @@ module.exports = {
'generator-star-spacing': 0,
// disallow modifying variables of class declarations
'no-class-assign': 0,
+ // disallow arrow functions where they could be confused with comparisons
+ // http://eslint.org/docs/rules/no-confusing-arrow
+ 'no-confusing-arrow': 2,
// disallow modifying variables that are declared using const
'no-const-assign': 2,
+ // disallow symbol constructor
+ // http://eslint.org/docs/rules/no-new-symbol
+ 'no-new-symbol': 2,
+ // disallow specific imports
+ // http://eslint.org/docs/rules/no-restricted-imports
+ 'no-restricted-imports': 0,
// disallow to use this/super before super() calling in constructors.
'no-this-before-super': 0,
// require let or const instead of var
'no-var': 2,
+ // disallow unnecessary constructor
+ // http://eslint.org/docs/rules/no-useless-constructor
+ 'no-useless-constructor': 2,
// require method and property shorthand syntax for object literals
// https://github.com/eslint/eslint/blob/master/docs/rules/object-shorthand.md
'object-shorthand': [2, 'always'],
@@ -55,10 +57,22 @@ module.exports = {
'prefer-spread': 0,
// suggest using Reflect methods where applicable
'prefer-reflect': 0,
+ // use rest parameters instead of arguments
+ // http://eslint.org/docs/rules/prefer-rest-params
+ 'prefer-rest-params': 2,
// suggest using template literals instead of string concatenation
// http://eslint.org/docs/rules/prefer-template
'prefer-template': 2,
// disallow generator functions that do not have yield
- 'require-yield': 0
+ 'require-yield': 0,
+ // import sorting
+ // http://eslint.org/docs/rules/sort-imports
+ 'sort-imports': 0,
+ // enforce usage of spacing in template strings
+ // http://eslint.org/docs/rules/template-curly-spacing
+ 'template-curly-spacing': 2,
+ // enforce spacing around the * in yield* expressions
+ // http://eslint.org/docs/rules/yield-star-spacing
+ 'yield-star-spacing': [2, 'after']
}
};
diff --git a/packages/eslint-config-airbnb/rules/react.js b/packages/eslint-config-airbnb/rules/react.js
index e1e1c25993..b7a9889e69 100644
--- a/packages/eslint-config-airbnb/rules/react.js
+++ b/packages/eslint-config-airbnb/rules/react.js
@@ -10,7 +10,7 @@ module.exports = {
'rules': {
// Prevent missing displayName in a React component definition
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md
- 'react/display-name': [0, { 'acceptTranspilerName': false }],
+ 'react/display-name': [0, { 'ignoreTranspilerName': false }],
// Forbid certain propTypes (any, array, object)
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md
'react/forbid-prop-types': [0, { 'forbid': ['any', 'array', 'object'] }],
@@ -54,8 +54,8 @@ module.exports = {
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md
'react/jsx-pascal-case': 0,
// Enforce propTypes declarations alphabetical sorting
- // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-prop-types.md
- 'react/jsx-sort-prop-types': [0, {
+ // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-prop-types.md
+ 'react/sort-prop-types': [0, {
'ignoreCase': false,
'callbacksLast': false,
}],
@@ -116,10 +116,14 @@ module.exports = {
// Prevent extra closing tags for components without children
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md
'react/self-closing-comp': 2,
+ // Enforce spaces before the closing bracket of self-closing JSX elements
+ // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-space-before-closing.md
+ 'react/jsx-space-before-closing': [2, 'always'],
// Enforce component methods order
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md
'react/sort-comp': [2, {
'order': [
+ 'static-methods',
'lifecycle',
'/^on.+$/',
'/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/',
diff --git a/packages/eslint-config-airbnb/rules/style.js b/packages/eslint-config-airbnb/rules/style.js
index 25c5326857..c147aae8b7 100644
--- a/packages/eslint-config-airbnb/rules/style.js
+++ b/packages/eslint-config-airbnb/rules/style.js
@@ -31,6 +31,16 @@ module.exports = {
'jsx-quotes': [2, 'prefer-double'],
// enforces spacing between keys and values in object literal properties
'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }],
+ // require a space before & after certain keywords
+ 'keyword-spacing': [2, {
+ 'before': true,
+ 'after': true,
+ 'overrides': {
+ 'return': { 'after': true },
+ 'throw': { 'after': true },
+ 'case': { 'after': true }
+ }
+ }],
// enforces empty lines around comments
'lines-around-comment': 0,
// disallow mixed 'LF' and 'CRLF' as linebreaks
@@ -49,6 +59,10 @@ module.exports = {
'new-parens': 0,
// allow/disallow an empty newline after var statement
'newline-after-var': 0,
+ // enforces new line after each method call in the chain to make it
+ // more readable and easy to maintain
+ // http://eslint.org/docs/rules/newline-per-chained-call
+ 'newline-per-chained-call': [2, { 'ignoreChainWithDepth': 3 }],
// disallow use of the Array constructor
'no-array-constructor': 0,
// disallow use of the continue statement
@@ -77,10 +91,16 @@ module.exports = {
// also, prefer `a || b` over `a ? a : b`
// http://eslint.org/docs/rules/no-unneeded-ternary
'no-unneeded-ternary': [2, { 'defaultAssignment': false }],
+ // disallow whitespace before properties
+ // http://eslint.org/docs/rules/no-whitespace-before-property
+ 'no-whitespace-before-property': 2,
// require padding inside curly braces
'object-curly-spacing': [2, 'always'],
// allow just one var statement per function
'one-var': [2, 'never'],
+ // require a newline around variable declaration
+ // http://eslint.org/docs/rules/one-var-declaration-per-line
+ 'one-var-declaration-per-line': [2, 'always'],
// require assignment operator shorthand where possible or prohibit it entirely
'operator-assignment': 0,
// enforce operators to be placed before or after line breaks
@@ -100,10 +120,6 @@ module.exports = {
'semi': [2, 'always'],
// sort variables within the same declaration block
'sort-vars': 0,
- // require a space before certain keywords
- 'space-before-keywords': [2, 'always'],
- // require a space after certain keywords
- 'space-after-keywords': [2, 'always'],
// require or disallow space before blocks
'space-before-blocks': 2,
// require or disallow space before function opening parenthesis
@@ -113,8 +129,6 @@ module.exports = {
'space-in-parens': [2, 'never'],
// require spaces around operators
'space-infix-ops': 2,
- // require a space after return, throw, and case
- 'space-return-throw-case': 2,
// Require or disallow spaces before/after unary operators
'space-unary-ops': 0,
// require or disallow a space immediately following the // or /* in a comment
diff --git a/packages/eslint-config-airbnb/rules/variables.js b/packages/eslint-config-airbnb/rules/variables.js
index 59914313f9..3bfcc83fde 100644
--- a/packages/eslint-config-airbnb/rules/variables.js
+++ b/packages/eslint-config-airbnb/rules/variables.js
@@ -6,8 +6,14 @@ module.exports = {
'no-catch-shadow': 0,
// disallow deletion of variables
'no-delete-var': 2,
+ // disallow var and named functions in global scope
+ // http://eslint.org/docs/rules/no-implicit-globals
+ 'no-implicit-globals': 0,
// disallow labels that share a name with a variable
'no-label-var': 0,
+ // disallow self assignment
+ // http://eslint.org/docs/rules/no-self-assign
+ 'no-self-assign': 2,
// disallow shadowing of names such as arguments
'no-shadow-restricted-names': 2,
// disallow declaration of variables already declared in the outer scope
diff --git a/packages/eslint-config-airbnb/test/test-react-order.js b/packages/eslint-config-airbnb/test/test-react-order.js
index 77448cf86a..f5b2d452fe 100644
--- a/packages/eslint-config-airbnb/test/test-react-order.js
+++ b/packages/eslint-config-airbnb/test/test-react-order.js
@@ -14,7 +14,8 @@ const cli = new CLIEngine({
function lint(text) {
// @see http://eslint.org/docs/developer-guide/nodejs-api.html#executeonfiles
// @see http://eslint.org/docs/developer-guide/nodejs-api.html#executeontext
- return cli.executeOnText(text).results[0];
+ const linter = cli.executeOnText(text);
+ return linter.results[0];
}
function wrapComponent(body) {