From a2d0469c3901f75543d168758d3aea365788e05f Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Wed, 21 Sep 2016 17:08:02 +0300 Subject: [PATCH] Create a shareable ESLint configuration package (#689) * Move ESLint configuration to a separate package * Remove the ESLint configuration, moved to eslint-config-react-app * Update ESLint instructions * Pin the package versions in eslint-config-react-app * Add a README for eslint-config-react-app * Update README.md * Update README.md * Update README.md * Update README.md * Update package.json * Update package.json * Update production eslint-loader config * Add the ESLint config to devDependencies of the repo --- .eslintrc | 3 +++ .eslintrc.js | 7 ----- package.json | 2 ++ packages/eslint-config-react-app/README.md | 27 +++++++++++++++++++ .../index.js} | 2 -- packages/eslint-config-react-app/package.json | 21 +++++++++++++++ packages/react-scripts/.eslintrc | 3 +++ .../config/webpack.config.dev.js | 4 ++- .../config/webpack.config.prod.js | 4 ++- packages/react-scripts/package.json | 2 ++ packages/react-scripts/scripts/eject.js | 7 +---- packages/react-scripts/template/README.md | 4 +-- 12 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 .eslintrc delete mode 100644 .eslintrc.js create mode 100644 packages/eslint-config-react-app/README.md rename packages/{react-scripts/config/eslint.js => eslint-config-react-app/index.js} (99%) 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..5e603ecd193 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "react-app" +} 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..d4180851a97 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "test": "node packages/react-scripts/scripts/test.js --env=jsdom" }, "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", diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md new file mode 100644 index 00000000000..7197134a95e --- /dev/null +++ b/packages/eslint-config-react-app/README.md @@ -0,0 +1,27 @@ +# eslint-config-react-app + +This package includes the shareable ESLint configuration used by [Create React App](https://github.com/facebookincubator/create-react-app). + +## 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.** + +## 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. + +First, install this package, ESLint and the necessary plugins. + + ```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 + ``` + +Then create a file named `.eslintrc` with following contents in the root folder of your project: + + ```js + { + "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. diff --git a/packages/react-scripts/config/eslint.js b/packages/eslint-config-react-app/index.js similarity index 99% rename from packages/react-scripts/config/eslint.js rename to packages/eslint-config-react-app/index.js index a7c955dbea5..81ad2f3d448 100644 --- a/packages/react-scripts/config/eslint.js +++ b/packages/eslint-config-react-app/index.js @@ -1,4 +1,3 @@ -// @remove-on-eject-begin /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -7,7 +6,6 @@ * 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. diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-config-react-app/package.json new file mode 100644 index 00000000000..948ee24dfee --- /dev/null +++ b/packages/eslint-config-react-app/package.json @@ -0,0 +1,21 @@ +{ + "name": "eslint-config-react-app", + "version": "0.1.0", + "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/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 [ diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index ced35306854..b6c9c12c4f6 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.1.0", "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'), 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.