From e3171083e52537db615ce97c435c0b97b871edd9 Mon Sep 17 00:00:00 2001 From: Ville Immonen Date: Mon, 31 Oct 2016 02:59:37 +0200 Subject: [PATCH] Move ESLint configuration to an ESLint plugin --- .../README.md | 10 +-- .../config.js} | 67 ++++++++++--------- packages/eslint-plugin-react-app/index.js | 25 +++++++ .../package.json | 11 +-- packages/react-scripts/.eslintrc | 2 +- packages/react-scripts/package.json | 14 +--- tasks/e2e.sh | 2 +- 7 files changed, 75 insertions(+), 56 deletions(-) rename packages/{eslint-config-react-app => eslint-plugin-react-app}/README.md (76%) rename packages/{eslint-config-react-app/index.js => eslint-plugin-react-app/config.js} (77%) create mode 100644 packages/eslint-plugin-react-app/index.js rename packages/{eslint-config-react-app => eslint-plugin-react-app}/package.json (79%) diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-plugin-react-app/README.md similarity index 76% rename from packages/eslint-config-react-app/README.md rename to packages/eslint-plugin-react-app/README.md index 5c20f50ca2e..d743e48183d 100644 --- a/packages/eslint-config-react-app/README.md +++ b/packages/eslint-plugin-react-app/README.md @@ -1,4 +1,4 @@ -# eslint-config-react-app +# eslint-plugin-react-app This package includes the shareable ESLint configuration used by [Create React App](https://github.com/facebookincubator/create-react-app). Please refer to its documentation: @@ -14,18 +14,18 @@ The easiest way to use this configuration is with [Create React App](https://git 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. +First, install this package and ESLint. ```sh - npm install --save-dev eslint-config-react-app babel-eslint@7.0.0 eslint@3.8.1 eslint-plugin-flowtype@2.21.0 eslint-plugin-import@2.0.1 eslint-plugin-jsx-a11y@2.2.3 eslint-plugin-react@6.4.1 + npm install --save-dev --save-exact eslint-plugin-react-app eslint@3.8.1 ``` Then create a file named `.eslintrc` with following contents in the root folder of your project: ```js { - "extends": "react-app" + "extends": "plugin:react-app/recommended" } ``` - 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. + That's it! You can override the settings from `eslint-plugin-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/eslint-config-react-app/index.js b/packages/eslint-plugin-react-app/config.js similarity index 77% rename from packages/eslint-config-react-app/index.js rename to packages/eslint-plugin-react-app/config.js index 6df5bfdd93b..7281871abfc 100644 --- a/packages/eslint-config-react-app/index.js +++ b/packages/eslint-plugin-react-app/config.js @@ -6,6 +6,7 @@ * 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. */ +'use strict'; // Inspired by https://github.com/airbnb/javascript but less opinionated. @@ -19,9 +20,9 @@ module.exports = { root: true, - parser: 'babel-eslint', + parser: require.resolve('babel-eslint'), - plugins: ['import', 'flowtype', 'jsx-a11y', 'react'], + plugins: ['react-app'], env: { browser: true, @@ -173,47 +174,47 @@ module.exports = { // because it doesn't depend on whether the file exists, so this issue // doesn't apply to it.) - // '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 }], + // 'react-app/import/default': 'warn', + // 'react-app/import/export': 'warn', + // 'react-app/import/named': 'warn', + // 'react-app/import/namespace': 'warn', + // 'react-app/import/no-amd': 'warn', + // 'react-app/import/no-duplicates': 'warn', + // 'react-app/import/no-extraneous-dependencies': 'warn', + // 'react-app/import/no-named-as-default': 'warn', + // 'react-app/import/no-named-as-default-member': 'warn', + // 'react-app/import/no-unresolved': ['warn', { commonjs: true }], // We don't support configuring Webpack using import source strings, so this // is always an error. - 'import/no-webpack-loader-syntax': 'error', + 'react-app/import/no-webpack-loader-syntax': 'error', // 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', { + 'react-app/react/jsx-equals-spacing': ['warn', 'never'], + 'react-app/react/jsx-no-duplicate-props': ['warn', { ignoreCase: true }], + 'react-app/react/jsx-no-undef': 'warn', + 'react-app/react/jsx-pascal-case': ['warn', { allowAllCaps: true, ignore: [], }], - 'react/jsx-uses-react': 'warn', - 'react/jsx-uses-vars': 'warn', - 'react/no-danger-with-children': 'warn', - 'react/no-deprecated': 'warn', - 'react/no-direct-mutation-state': 'warn', - 'react/no-is-mounted': 'warn', - 'react/react-in-jsx-scope': 'error', - 'react/require-render-return': 'warn', - 'react/style-prop-object': 'warn', + 'react-app/react/jsx-uses-react': 'warn', + 'react-app/react/jsx-uses-vars': 'warn', + 'react-app/react/no-danger-with-children': 'warn', + 'react-app/react/no-deprecated': 'warn', + 'react-app/react/no-direct-mutation-state': 'warn', + 'react-app/react/no-is-mounted': 'warn', + 'react-app/react/react-in-jsx-scope': 'error', + 'react-app/react/require-render-return': 'warn', + 'react-app/react/style-prop-object': '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', + 'react-app/jsx-a11y/aria-role': 'warn', + 'react-app/jsx-a11y/img-has-alt': 'warn', + 'react-app/jsx-a11y/img-redundant-alt': 'warn', + 'react-app/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' + 'react-app/flowtype/define-flow-type': 'warn', + 'react-app/flowtype/require-valid-file-annotation': 'warn', + 'react-app/flowtype/use-flow-type': 'warn' } }; diff --git a/packages/eslint-plugin-react-app/index.js b/packages/eslint-plugin-react-app/index.js new file mode 100644 index 00000000000..4b194b156aa --- /dev/null +++ b/packages/eslint-plugin-react-app/index.js @@ -0,0 +1,25 @@ +'use strict'; +const config = require('./config'); + +const plugins = [ + 'import', + 'flowtype', + 'jsx-a11y', + 'react' +]; + +const rules = {}; + +plugins.forEach((pluginName) => { + const plugin = require(`eslint-plugin-${pluginName}`); + Object.keys(plugin.rules).forEach((ruleName) => { + rules[`${pluginName}/${ruleName}`] = plugin.rules[ruleName]; + }); +}); + +module.exports = { + configs: { + recommended: config, + }, + rules, +}; diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-plugin-react-app/package.json similarity index 79% rename from packages/eslint-config-react-app/package.json rename to packages/eslint-plugin-react-app/package.json index e0321bd47eb..0161f41f239 100644 --- a/packages/eslint-config-react-app/package.json +++ b/packages/eslint-plugin-react-app/package.json @@ -1,6 +1,6 @@ { - "name": "eslint-config-react-app", - "version": "0.3.0", + "name": "eslint-plugin-react-app", + "version": "0.0.0", "description": "ESLint configuration used by Create React App", "repository": "facebookincubator/create-react-app", "license": "BSD-3-Clause", @@ -8,14 +8,17 @@ "url": "https://github.com/facebookincubator/create-react-app/issues" }, "files": [ + "config.js", "index.js" ], - "peerDependencies": { + "dependencies": { "babel-eslint": "7.0.0", - "eslint": "3.8.1", "eslint-plugin-flowtype": "2.21.0", "eslint-plugin-import": "2.0.1", "eslint-plugin-jsx-a11y": "2.2.3", "eslint-plugin-react": "6.4.1" + }, + "peerDependencies": { + "eslint": "3.8.1" } } diff --git a/packages/react-scripts/.eslintrc b/packages/react-scripts/.eslintrc index 5e603ecd193..3286faa8779 100644 --- a/packages/react-scripts/.eslintrc +++ b/packages/react-scripts/.eslintrc @@ -1,3 +1,3 @@ { - "extends": "react-app" + "extends": "plugin:react-app/recommended" } diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index b4cad963979..c22b240d539 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -25,7 +25,6 @@ "dependencies": { "autoprefixer": "6.5.1", "babel-core": "6.17.0", - "babel-eslint": "7.0.0", "babel-jest": "16.0.0", "babel-loader": "6.2.7", "babel-preset-react-app": "^1.0.0", @@ -37,12 +36,8 @@ "detect-port": "1.0.1", "dotenv": "2.0.0", "eslint": "3.8.1", - "eslint-config-react-app": "^0.3.0", "eslint-loader": "1.6.0", - "eslint-plugin-flowtype": "2.21.0", - "eslint-plugin-import": "2.0.1", - "eslint-plugin-jsx-a11y": "2.2.3", - "eslint-plugin-react": "6.4.1", + "eslint-plugin-react-app": "0.0.0", "extract-text-webpack-plugin": "1.0.1", "file-loader": "0.9.0", "filesize": "3.3.0", @@ -78,7 +73,6 @@ "bundledDependencies": [ "autoprefixer", "babel-core", - "babel-eslint", "babel-jest", "babel-loader", "babel-preset-react-app", @@ -90,12 +84,8 @@ "detect-port", "dotenv", "eslint", - "eslint-config-react-app", "eslint-loader", - "eslint-plugin-flowtype", - "eslint-plugin-import", - "eslint-plugin-jsx-a11y", - "eslint-plugin-react", + "eslint-plugin-react-app", "extract-text-webpack-plugin", "file-loader", "filesize", diff --git a/tasks/e2e.sh b/tasks/e2e.sh index 88e1fdf4e20..a739f6340df 100755 --- a/tasks/e2e.sh +++ b/tasks/e2e.sh @@ -147,7 +147,7 @@ echo yes | npm run eject # ...but still link to the local packages npm link $root_path/packages/babel-preset-react-app -npm link $root_path/packages/eslint-config-react-app +npm link $root_path/packages/eslint-plugin-react-app npm link $root_path/packages/react-dev-utils npm link $root_path/packages/react-scripts