From a4b4fe3541c56d976ce8306b859c92df1d820ca0 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Tue, 20 Sep 2016 23:34:55 +0300 Subject: [PATCH 01/13] Move ESLint configuration to a separate package --- .eslintrc | 3 + .eslintrc.js | 7 - package.json | 1 + packages/eslint-config-react-app/index.js | 209 ++++++++++++++++++ packages/eslint-config-react-app/package.json | 21 ++ packages/react-scripts/.eslintrc | 3 + .../config/webpack.config.dev.js | 4 +- packages/react-scripts/package.json | 2 + packages/react-scripts/scripts/eject.js | 7 +- 9 files changed, 243 insertions(+), 14 deletions(-) create mode 100644 .eslintrc delete mode 100644 .eslintrc.js create mode 100644 packages/eslint-config-react-app/index.js create mode 100644 packages/eslint-config-react-app/package.json create mode 100644 packages/react-scripts/.eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000000..9ec94160911 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "./packages/eslint-config-react-app/index.js" +} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 1a0ff4648a0..00000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -const clientESLintConfig = require('./packages/react-scripts/config/eslint'); - -module.exports = Object.assign({}, clientESLintConfig, { - env: Object.assign({}, clientESLintConfig.env, { - node: true, - }) -}); diff --git a/package.json b/package.json index b57e050bd93..b90954c6757 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "test": "node packages/react-scripts/scripts/test.js --env=jsdom" }, "devDependencies": { + "babel-eslint": "6.1.2", "eslint": "3.5.0", "eslint-plugin-flowtype": "2.18.1", "eslint-plugin-import": "1.12.0", diff --git a/packages/eslint-config-react-app/index.js b/packages/eslint-config-react-app/index.js new file mode 100644 index 00000000000..81ad2f3d448 --- /dev/null +++ b/packages/eslint-config-react-app/index.js @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +// Inspired by https://github.com/airbnb/javascript but less opinionated. + +// We use eslint-loader so even warnings are very visibile. +// This is why we only use "WARNING" level for potential errors, +// and we don't use "ERROR" level at all. + +// In the future, we might create a separate list of rules for production. +// It would probably be more strict. + +module.exports = { + root: true, + + parser: 'babel-eslint', + + // import plugin is temporarily disabled, scroll below to see why + plugins: [/*'import', */'flowtype', 'jsx-a11y', 'react'], + + env: { + browser: true, + commonjs: true, + es6: true, + jest: true, + node: true + }, + + parserOptions: { + ecmaVersion: 6, + sourceType: 'module', + ecmaFeatures: { + jsx: true, + generators: true, + experimentalObjectRestSpread: true + } + }, + + settings: { + 'import/ignore': [ + 'node_modules', + '\\.(json|css|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$', + ], + 'import/extensions': ['.js'], + 'import/resolver': { + node: { + extensions: ['.js', '.json'] + } + } + }, + + rules: { + // http://eslint.org/docs/rules/ + 'array-callback-return': 'warn', + 'default-case': ['warn', { commentPattern: '^no default$' }], + 'dot-location': ['warn', 'property'], + eqeqeq: ['warn', 'allow-null'], + 'guard-for-in': 'warn', + 'new-parens': 'warn', + 'no-array-constructor': 'warn', + 'no-caller': 'warn', + 'no-cond-assign': ['warn', 'always'], + 'no-const-assign': 'warn', + 'no-control-regex': 'warn', + 'no-delete-var': 'warn', + 'no-dupe-args': 'warn', + 'no-dupe-class-members': 'warn', + 'no-dupe-keys': 'warn', + 'no-duplicate-case': 'warn', + 'no-empty-character-class': 'warn', + 'no-empty-pattern': 'warn', + 'no-eval': 'warn', + 'no-ex-assign': 'warn', + 'no-extend-native': 'warn', + 'no-extra-bind': 'warn', + 'no-extra-label': 'warn', + 'no-fallthrough': 'warn', + 'no-func-assign': 'warn', + 'no-implied-eval': 'warn', + 'no-invalid-regexp': 'warn', + 'no-iterator': 'warn', + 'no-label-var': 'warn', + 'no-labels': ['warn', { allowLoop: false, allowSwitch: false }], + 'no-lone-blocks': 'warn', + 'no-loop-func': 'warn', + 'no-mixed-operators': ['warn', { + groups: [ + ['&', '|', '^', '~', '<<', '>>', '>>>'], + ['==', '!=', '===', '!==', '>', '>=', '<', '<='], + ['&&', '||'], + ['in', 'instanceof'] + ], + allowSamePrecedence: false + }], + 'no-multi-str': 'warn', + 'no-native-reassign': 'warn', + 'no-negated-in-lhs': 'warn', + 'no-new-func': 'warn', + 'no-new-object': 'warn', + 'no-new-symbol': 'warn', + 'no-new-wrappers': 'warn', + 'no-obj-calls': 'warn', + 'no-octal': 'warn', + 'no-octal-escape': 'warn', + 'no-redeclare': 'warn', + 'no-regex-spaces': 'warn', + 'no-restricted-syntax': [ + 'warn', + 'LabeledStatement', + 'WithStatement', + ], + 'no-script-url': 'warn', + 'no-self-assign': 'warn', + 'no-self-compare': 'warn', + 'no-sequences': 'warn', + 'no-shadow-restricted-names': 'warn', + 'no-sparse-arrays': 'warn', + 'no-template-curly-in-string': 'warn', + 'no-this-before-super': 'warn', + 'no-throw-literal': 'warn', + 'no-undef': 'error', + 'no-unexpected-multiline': 'warn', + 'no-unreachable': 'warn', + 'no-unused-expressions': 'warn', + 'no-unused-labels': 'warn', + 'no-unused-vars': ['warn', { + vars: 'local', + varsIgnorePattern: '^_', + args: 'none' + }], + 'no-use-before-define': ['warn', 'nofunc'], + 'no-useless-computed-key': 'warn', + 'no-useless-concat': 'warn', + 'no-useless-constructor': 'warn', + 'no-useless-escape': 'warn', + 'no-useless-rename': ['warn', { + ignoreDestructuring: false, + ignoreImport: false, + ignoreExport: false, + }], + 'no-with': 'warn', + 'no-whitespace-before-property': 'warn', + 'operator-assignment': ['warn', 'always'], + radix: 'warn', + 'require-yield': 'warn', + 'rest-spread-spacing': ['warn', 'never'], + strict: ['warn', 'never'], + 'unicode-bom': ['warn', 'never'], + 'use-isnan': 'warn', + 'valid-typeof': 'warn', + + // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/ + + // TODO: import rules are temporarily disabled because they don't play well + // with how eslint-loader only checks the file you change. So if module A + // imports module B, and B is missing a default export, the linter will + // record this as an issue in module A. Now if you fix module B, the linter + // will not be aware that it needs to re-lint A as well, so the error + // will stay until the next restart, which is really confusing. + + // This is probably fixable with a patch to eslint-loader. + // When file A is saved, we want to invalidate all files that import it + // *and* that currently have lint errors. This should fix the problem. + + // 'import/default': 'warn', + // 'import/export': 'warn', + // 'import/named': 'warn', + // 'import/namespace': 'warn', + // 'import/no-amd': 'warn', + // 'import/no-duplicates': 'warn', + // 'import/no-extraneous-dependencies': 'warn', + // 'import/no-named-as-default': 'warn', + // 'import/no-named-as-default-member': 'warn', + // 'import/no-unresolved': ['warn', { commonjs: true }], + + // https://github.com/yannickcr/eslint-plugin-react/tree/master/docs/rules + 'react/jsx-equals-spacing': ['warn', 'never'], + 'react/jsx-no-duplicate-props': ['warn', { ignoreCase: true }], + 'react/jsx-no-undef': 'warn', + 'react/jsx-pascal-case': ['warn', { + allowAllCaps: true, + ignore: [], + }], + 'react/jsx-uses-react': 'warn', + 'react/jsx-uses-vars': 'warn', + 'react/no-deprecated': 'warn', + 'react/no-direct-mutation-state': 'warn', + 'react/no-is-mounted': 'warn', + 'react/react-in-jsx-scope': 'warn', + 'react/require-render-return': 'warn', + + // https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules + 'jsx-a11y/aria-role': 'warn', + 'jsx-a11y/img-has-alt': 'warn', + 'jsx-a11y/img-redundant-alt': 'warn', + 'jsx-a11y/no-access-key': 'warn', + + // https://github.com/gajus/eslint-plugin-flowtype + 'flowtype/define-flow-type': 'warn', + 'flowtype/require-valid-file-annotation': 'warn', + 'flowtype/use-flow-type': 'warn' + } +}; diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-config-react-app/package.json new file mode 100644 index 00000000000..c680a28db64 --- /dev/null +++ b/packages/eslint-config-react-app/package.json @@ -0,0 +1,21 @@ +{ + "name": "eslint-config-react-app", + "version": "0.4.3", + "description": "ESLint configuration used by Create React App", + "repository": "facebookincubator/create-react-app", + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/facebookincubator/create-react-app/issues" + }, + "files": [ + "index.js" + ], + "peerDependencies": { + "babel-eslint": "^6.1.2", + "eslint": "^3.5.0", + "eslint-plugin-flowtype": "^2.18.1", + "eslint-plugin-import": "^1.12.0", + "eslint-plugin-jsx-a11y": "^2.2.2", + "eslint-plugin-react": "^5.2.2" + } +} diff --git a/packages/react-scripts/.eslintrc b/packages/react-scripts/.eslintrc new file mode 100644 index 00000000000..5e603ecd193 --- /dev/null +++ b/packages/react-scripts/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "react-app" +} diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index cfc971e609e..8d1de1c327d 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -165,11 +165,13 @@ module.exports = { } ] }, + // @remove-on-eject-begin // Point ESLint to our predefined config. eslint: { - configFile: path.join(__dirname, 'eslint.js'), + configFile: path.join(__dirname, '../.eslintrc'), useEslintrc: false }, + // @remove-on-eject-end // We use PostCSS for autoprefixing only. postcss: function() { return [ diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index ced35306854..480f9d0010a 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -11,6 +11,7 @@ "url": "https://github.com/facebookincubator/create-react-app/issues" }, "files": [ + ".eslintrc", "bin", "config", "scripts", @@ -40,6 +41,7 @@ "css-loader": "0.24.0", "detect-port": "1.0.0", "eslint": "3.5.0", + "eslint-config-react-app": "0.4.3", "eslint-loader": "1.5.0", "eslint-plugin-flowtype": "2.18.1", "eslint-plugin-import": "1.12.0", diff --git a/packages/react-scripts/scripts/eject.js b/packages/react-scripts/scripts/eject.js index 74c5c9ef99b..a36e1d19600 100644 --- a/packages/react-scripts/scripts/eject.js +++ b/packages/react-scripts/scripts/eject.js @@ -29,11 +29,11 @@ prompt( var ownPath = path.join(__dirname, '..'); var appPath = path.join(ownPath, '..', '..'); var files = [ + '.eslintrc', path.join('config', 'babel.dev.js'), path.join('config', 'babel.prod.js'), path.join('config', 'flow', 'css.js.flow'), path.join('config', 'flow', 'file.js.flow'), - path.join('config', 'eslint.js'), path.join('config', 'paths.js'), path.join('config', 'env.js'), path.join('config', 'polyfills.js'), @@ -111,11 +111,6 @@ prompt( filePath => path.join('', filePath) ); - // Explicitly specify ESLint config path for editor plugins - appPackage.eslintConfig = { - extends: './config/eslint.js', - }; - console.log('Writing package.json'); fs.writeFileSync( path.join(appPath, 'package.json'), From 603cff0bce637c6b6dd0b79e2410cd304256a076 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 00:32:08 +0300 Subject: [PATCH 02/13] Remove the ESLint configuration, moved to eslint-config-react-app --- packages/react-scripts/config/eslint.js | 211 ------------------------ 1 file changed, 211 deletions(-) delete mode 100644 packages/react-scripts/config/eslint.js diff --git a/packages/react-scripts/config/eslint.js b/packages/react-scripts/config/eslint.js deleted file mode 100644 index a7c955dbea5..00000000000 --- a/packages/react-scripts/config/eslint.js +++ /dev/null @@ -1,211 +0,0 @@ -// @remove-on-eject-begin -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -// @remove-on-eject-end - -// Inspired by https://github.com/airbnb/javascript but less opinionated. - -// We use eslint-loader so even warnings are very visibile. -// This is why we only use "WARNING" level for potential errors, -// and we don't use "ERROR" level at all. - -// In the future, we might create a separate list of rules for production. -// It would probably be more strict. - -module.exports = { - root: true, - - parser: 'babel-eslint', - - // import plugin is temporarily disabled, scroll below to see why - plugins: [/*'import', */'flowtype', 'jsx-a11y', 'react'], - - env: { - browser: true, - commonjs: true, - es6: true, - jest: true, - node: true - }, - - parserOptions: { - ecmaVersion: 6, - sourceType: 'module', - ecmaFeatures: { - jsx: true, - generators: true, - experimentalObjectRestSpread: true - } - }, - - settings: { - 'import/ignore': [ - 'node_modules', - '\\.(json|css|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$', - ], - 'import/extensions': ['.js'], - 'import/resolver': { - node: { - extensions: ['.js', '.json'] - } - } - }, - - rules: { - // http://eslint.org/docs/rules/ - 'array-callback-return': 'warn', - 'default-case': ['warn', { commentPattern: '^no default$' }], - 'dot-location': ['warn', 'property'], - eqeqeq: ['warn', 'allow-null'], - 'guard-for-in': 'warn', - 'new-parens': 'warn', - 'no-array-constructor': 'warn', - 'no-caller': 'warn', - 'no-cond-assign': ['warn', 'always'], - 'no-const-assign': 'warn', - 'no-control-regex': 'warn', - 'no-delete-var': 'warn', - 'no-dupe-args': 'warn', - 'no-dupe-class-members': 'warn', - 'no-dupe-keys': 'warn', - 'no-duplicate-case': 'warn', - 'no-empty-character-class': 'warn', - 'no-empty-pattern': 'warn', - 'no-eval': 'warn', - 'no-ex-assign': 'warn', - 'no-extend-native': 'warn', - 'no-extra-bind': 'warn', - 'no-extra-label': 'warn', - 'no-fallthrough': 'warn', - 'no-func-assign': 'warn', - 'no-implied-eval': 'warn', - 'no-invalid-regexp': 'warn', - 'no-iterator': 'warn', - 'no-label-var': 'warn', - 'no-labels': ['warn', { allowLoop: false, allowSwitch: false }], - 'no-lone-blocks': 'warn', - 'no-loop-func': 'warn', - 'no-mixed-operators': ['warn', { - groups: [ - ['&', '|', '^', '~', '<<', '>>', '>>>'], - ['==', '!=', '===', '!==', '>', '>=', '<', '<='], - ['&&', '||'], - ['in', 'instanceof'] - ], - allowSamePrecedence: false - }], - 'no-multi-str': 'warn', - 'no-native-reassign': 'warn', - 'no-negated-in-lhs': 'warn', - 'no-new-func': 'warn', - 'no-new-object': 'warn', - 'no-new-symbol': 'warn', - 'no-new-wrappers': 'warn', - 'no-obj-calls': 'warn', - 'no-octal': 'warn', - 'no-octal-escape': 'warn', - 'no-redeclare': 'warn', - 'no-regex-spaces': 'warn', - 'no-restricted-syntax': [ - 'warn', - 'LabeledStatement', - 'WithStatement', - ], - 'no-script-url': 'warn', - 'no-self-assign': 'warn', - 'no-self-compare': 'warn', - 'no-sequences': 'warn', - 'no-shadow-restricted-names': 'warn', - 'no-sparse-arrays': 'warn', - 'no-template-curly-in-string': 'warn', - 'no-this-before-super': 'warn', - 'no-throw-literal': 'warn', - 'no-undef': 'error', - 'no-unexpected-multiline': 'warn', - 'no-unreachable': 'warn', - 'no-unused-expressions': 'warn', - 'no-unused-labels': 'warn', - 'no-unused-vars': ['warn', { - vars: 'local', - varsIgnorePattern: '^_', - args: 'none' - }], - 'no-use-before-define': ['warn', 'nofunc'], - 'no-useless-computed-key': 'warn', - 'no-useless-concat': 'warn', - 'no-useless-constructor': 'warn', - 'no-useless-escape': 'warn', - 'no-useless-rename': ['warn', { - ignoreDestructuring: false, - ignoreImport: false, - ignoreExport: false, - }], - 'no-with': 'warn', - 'no-whitespace-before-property': 'warn', - 'operator-assignment': ['warn', 'always'], - radix: 'warn', - 'require-yield': 'warn', - 'rest-spread-spacing': ['warn', 'never'], - strict: ['warn', 'never'], - 'unicode-bom': ['warn', 'never'], - 'use-isnan': 'warn', - 'valid-typeof': 'warn', - - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/ - - // TODO: import rules are temporarily disabled because they don't play well - // with how eslint-loader only checks the file you change. So if module A - // imports module B, and B is missing a default export, the linter will - // record this as an issue in module A. Now if you fix module B, the linter - // will not be aware that it needs to re-lint A as well, so the error - // will stay until the next restart, which is really confusing. - - // This is probably fixable with a patch to eslint-loader. - // When file A is saved, we want to invalidate all files that import it - // *and* that currently have lint errors. This should fix the problem. - - // 'import/default': 'warn', - // 'import/export': 'warn', - // 'import/named': 'warn', - // 'import/namespace': 'warn', - // 'import/no-amd': 'warn', - // 'import/no-duplicates': 'warn', - // 'import/no-extraneous-dependencies': 'warn', - // 'import/no-named-as-default': 'warn', - // 'import/no-named-as-default-member': 'warn', - // 'import/no-unresolved': ['warn', { commonjs: true }], - - // https://github.com/yannickcr/eslint-plugin-react/tree/master/docs/rules - 'react/jsx-equals-spacing': ['warn', 'never'], - 'react/jsx-no-duplicate-props': ['warn', { ignoreCase: true }], - 'react/jsx-no-undef': 'warn', - 'react/jsx-pascal-case': ['warn', { - allowAllCaps: true, - ignore: [], - }], - 'react/jsx-uses-react': 'warn', - 'react/jsx-uses-vars': 'warn', - 'react/no-deprecated': 'warn', - 'react/no-direct-mutation-state': 'warn', - 'react/no-is-mounted': 'warn', - 'react/react-in-jsx-scope': 'warn', - 'react/require-render-return': 'warn', - - // https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules - 'jsx-a11y/aria-role': 'warn', - 'jsx-a11y/img-has-alt': 'warn', - 'jsx-a11y/img-redundant-alt': 'warn', - 'jsx-a11y/no-access-key': 'warn', - - // https://github.com/gajus/eslint-plugin-flowtype - 'flowtype/define-flow-type': 'warn', - 'flowtype/require-valid-file-annotation': 'warn', - 'flowtype/use-flow-type': 'warn' - } -}; From 2d2e7af70c5a47d41604153e57efeef009b403c2 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 00:33:31 +0300 Subject: [PATCH 03/13] Update ESLint instructions --- packages/react-scripts/template/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 085406077b5..f914a3e2cba 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -163,7 +163,7 @@ Then add this block to the `package.json` file of your project: { // ... "eslintConfig": { - "extends": "./node_modules/react-scripts/config/eslint.js" + "extends": "react-app" } } ``` @@ -171,7 +171,7 @@ Then add this block to the `package.json` file of your project: Finally, you will need to install some packages *globally*: ```sh -npm install -g eslint babel-eslint eslint-plugin-react eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-flowtype +npm install -g eslint-config-react-app eslint babel-eslint eslint-plugin-react eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-flowtype ``` We recognize that this is suboptimal, but it is currently required due to the way we hide the ESLint dependency. The ESLint team is already [working on a solution to this](https://github.com/eslint/eslint/issues/3458) so this may become unnecessary in a couple of months. From 5c9f7acc2f08f89b0765f3f279846813c3109270 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 02:11:55 +0300 Subject: [PATCH 04/13] Pin the package versions in eslint-config-react-app --- packages/eslint-config-react-app/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-config-react-app/package.json index c680a28db64..7fb1563d996 100644 --- a/packages/eslint-config-react-app/package.json +++ b/packages/eslint-config-react-app/package.json @@ -11,11 +11,11 @@ "index.js" ], "peerDependencies": { - "babel-eslint": "^6.1.2", - "eslint": "^3.5.0", - "eslint-plugin-flowtype": "^2.18.1", - "eslint-plugin-import": "^1.12.0", - "eslint-plugin-jsx-a11y": "^2.2.2", - "eslint-plugin-react": "^5.2.2" + "babel-eslint": "6.1.2", + "eslint": "3.5.0", + "eslint-plugin-flowtype": "2.18.1", + "eslint-plugin-import": "1.12.0", + "eslint-plugin-jsx-a11y": "2.2.2", + "eslint-plugin-react": "5.2.2" } } From 8dbfe66c03f7cb54d7d77097fa633389a3bb78a5 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 02:54:05 +0300 Subject: [PATCH 05/13] Add a README for eslint-config-react-app --- packages/eslint-config-react-app/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 packages/eslint-config-react-app/README.md diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md new file mode 100644 index 00000000000..f48467f57ab --- /dev/null +++ b/packages/eslint-config-react-app/README.md @@ -0,0 +1,21 @@ +# eslint-config-react-app + +This package includes the shareable ESLint configuration used by Create React App. + +## Installation + +*The easiest way to use this configuration is with *[Create React App](https://github.com/facebookincubator/create-react-app)*, which includes it by default – you **don't need to install it separately in Create React App projects.*** + +If you want to use this ESLint configuration in a project not built with Create React App, you can install it with following steps. + +1. Install this package, ESLint and the necessary plugins: + ``` + npm install eslint-config-react-app@6.1.2 eslint@3.5.0 eslint-plugin-flowtype2.18.1 eslint-plugin-import@1.12.0 eslint-plugin-jsx-a11y@2.2.2 eslint-plugin-react@5.2.2 --save-dev + ``` +2. Create a file named `.eslintrc` with following contents in the root folder of your project: + ``` + { + "extends": "react-app" + } + ``` + That's it! You can override the settings from `eslint-config-react-app` by editing the `.eslintrc` file. Learn more about [configuring ESLint](http://eslint.org/docs/user-guide/configuring) on the ESLint website. From 7e55f86a85d75c73cceb4c26b1677215161cad42 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 03:00:03 +0300 Subject: [PATCH 06/13] Update README.md --- packages/eslint-config-react-app/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md index f48467f57ab..66082b32475 100644 --- a/packages/eslint-config-react-app/README.md +++ b/packages/eslint-config-react-app/README.md @@ -1,10 +1,10 @@ # eslint-config-react-app -This package includes the shareable ESLint configuration used by Create React App. +This package includes the shareable ESLint configuration used by [Create React App](https://github.com/facebookincubator/create-react-app). ## Installation -*The easiest way to use this configuration is with *[Create React App](https://github.com/facebookincubator/create-react-app)*, which includes it by default – you **don't need to install it separately in Create React App projects.*** +*The easiest way to use this configuration is with [Create React App](https://github.com/facebookincubator/create-react-app), which includes it by default – you* **don't need to install it separately in Create React App projects.** If you want to use this ESLint configuration in a project not built with Create React App, you can install it with following steps. From e2dc36e31111ec9777af2b375527d04fab1d8ed4 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 03:02:24 +0300 Subject: [PATCH 07/13] Update README.md --- packages/eslint-config-react-app/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md index 66082b32475..ac3db837b74 100644 --- a/packages/eslint-config-react-app/README.md +++ b/packages/eslint-config-react-app/README.md @@ -9,13 +9,17 @@ This package includes the shareable ESLint configuration used by [Create React A If you want to use this ESLint configuration in a project not built with Create React App, you can install it with following steps. 1. Install this package, ESLint and the necessary plugins: + ``` npm install eslint-config-react-app@6.1.2 eslint@3.5.0 eslint-plugin-flowtype2.18.1 eslint-plugin-import@1.12.0 eslint-plugin-jsx-a11y@2.2.2 eslint-plugin-react@5.2.2 --save-dev ``` + 2. Create a file named `.eslintrc` with following contents in the root folder of your project: + ``` { "extends": "react-app" } ``` + That's it! You can override the settings from `eslint-config-react-app` by editing the `.eslintrc` file. Learn more about [configuring ESLint](http://eslint.org/docs/user-guide/configuring) on the ESLint website. From cfa6880523e4b000871debcdfe8c1cee8f4b745a Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 03:06:09 +0300 Subject: [PATCH 08/13] Update README.md --- packages/eslint-config-react-app/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md index ac3db837b74..1bb237833e2 100644 --- a/packages/eslint-config-react-app/README.md +++ b/packages/eslint-config-react-app/README.md @@ -11,7 +11,7 @@ If you want to use this ESLint configuration in a project not built with Create 1. Install this package, ESLint and the necessary plugins: ``` - npm install eslint-config-react-app@6.1.2 eslint@3.5.0 eslint-plugin-flowtype2.18.1 eslint-plugin-import@1.12.0 eslint-plugin-jsx-a11y@2.2.2 eslint-plugin-react@5.2.2 --save-dev + npm install eslint-config-react-app babel-eslint@6.1.2 eslint@3.5.0 eslint-plugin-flowtype@2.18.1 eslint-plugin-import@1.12.0 eslint-plugin-jsx-a11y@2.2.2 eslint-plugin-react@5.2.2 --save-dev ``` 2. Create a file named `.eslintrc` with following contents in the root folder of your project: From f2665d8469091275e15f70e83e5450933160bad4 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 21 Sep 2016 13:50:51 +0100 Subject: [PATCH 09/13] Update README.md --- packages/eslint-config-react-app/README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md index 1bb237833e2..7197134a95e 100644 --- a/packages/eslint-config-react-app/README.md +++ b/packages/eslint-config-react-app/README.md @@ -2,21 +2,23 @@ This package includes the shareable ESLint configuration used by [Create React App](https://github.com/facebookincubator/create-react-app). -## Installation +## Usage in Create React App Projects -*The easiest way to use this configuration is with [Create React App](https://github.com/facebookincubator/create-react-app), which includes it by default – you* **don't need to install it separately in Create React App projects.** +The easiest way to use this configuration is with [Create React App](https://github.com/facebookincubator/create-react-app), which includes it by default. **You don’t need to install it separately in Create React App projects.** + +## Usage Outside of Create React App If you want to use this ESLint configuration in a project not built with Create React App, you can install it with following steps. -1. Install this package, ESLint and the necessary plugins: +First, install this package, ESLint and the necessary plugins. - ``` - npm install eslint-config-react-app babel-eslint@6.1.2 eslint@3.5.0 eslint-plugin-flowtype@2.18.1 eslint-plugin-import@1.12.0 eslint-plugin-jsx-a11y@2.2.2 eslint-plugin-react@5.2.2 --save-dev + ```sh + npm install --save-dev eslint-config-react-app babel-eslint@6.1.2 eslint@3.5.0 eslint-plugin-flowtype@2.18.1 eslint-plugin-import@1.12.0 eslint-plugin-jsx-a11y@2.2.2 eslint-plugin-react@5.2.2 ``` -2. Create a file named `.eslintrc` with following contents in the root folder of your project: +Then create a file named `.eslintrc` with following contents in the root folder of your project: - ``` + ```js { "extends": "react-app" } From 2db2ebe766e0447409654f44117c051892797450 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 21 Sep 2016 13:58:59 +0100 Subject: [PATCH 10/13] Update package.json --- packages/eslint-config-react-app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-config-react-app/package.json index 7fb1563d996..948ee24dfee 100644 --- a/packages/eslint-config-react-app/package.json +++ b/packages/eslint-config-react-app/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-react-app", - "version": "0.4.3", + "version": "0.1.0", "description": "ESLint configuration used by Create React App", "repository": "facebookincubator/create-react-app", "license": "BSD-3-Clause", From 0881de1f8bd108663a03724262b01463548b728f Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 21 Sep 2016 14:15:27 +0100 Subject: [PATCH 11/13] Update package.json --- packages/react-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 480f9d0010a..b6c9c12c4f6 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -41,7 +41,7 @@ "css-loader": "0.24.0", "detect-port": "1.0.0", "eslint": "3.5.0", - "eslint-config-react-app": "0.4.3", + "eslint-config-react-app": "0.1.0", "eslint-loader": "1.5.0", "eslint-plugin-flowtype": "2.18.1", "eslint-plugin-import": "1.12.0", From 5c4458c0ea8075bf2dda208c671624cb428e8568 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 16:15:28 +0300 Subject: [PATCH 12/13] Update production eslint-loader config --- packages/react-scripts/config/webpack.config.prod.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index ae5ef218fe5..5790e8e9551 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -175,13 +175,15 @@ module.exports = { } ] }, + // @remove-on-eject-begin // Point ESLint to our predefined config. eslint: { // TODO: consider separate config for production, // e.g. to enable no-console and no-debugger only in production. - configFile: path.join(__dirname, 'eslint.js'), + configFile: path.join(__dirname, '../.eslintrc'), useEslintrc: false }, + // @remove-on-eject-end // We use PostCSS for autoprefixing only. postcss: function() { return [ From 996bf67efc4d4e8ff9f38d2c75b995594e6d472d Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 16:43:09 +0300 Subject: [PATCH 13/13] Add the ESLint config to devDependencies of the repo --- .eslintrc | 2 +- package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index 9ec94160911..5e603ecd193 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,3 +1,3 @@ { - "extends": "./packages/eslint-config-react-app/index.js" + "extends": "react-app" } diff --git a/package.json b/package.json index b90954c6757..d4180851a97 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "devDependencies": { "babel-eslint": "6.1.2", "eslint": "3.5.0", + "eslint-config-react-app": "file:packages/eslint-config-react-app", "eslint-plugin-flowtype": "2.18.1", "eslint-plugin-import": "1.12.0", "eslint-plugin-jsx-a11y": "2.2.2",