From 34bfa9de3d6603357e6d2685bb1f78fcda8e8d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DUNGLER?= Date: Tue, 20 Oct 2020 12:38:32 +0200 Subject: [PATCH] Replace deprecated eslint-loader with eslint-webpack-plugin (#9751) * Replace deprecated eslint-loader by eslint-webpack-plugin * Update eslintFormatter for eslint-webpack-plugin * fix: always enable jsx-uses-react Co-authored-by: Brody McKee --- packages/eslint-config-react-app/base.js | 2 +- packages/react-dev-utils/eslintFormatter.js | 11 ++++++ .../react-scripts/config/webpack.config.js | 37 +++++++------------ packages/react-scripts/package.json | 2 +- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/packages/eslint-config-react-app/base.js b/packages/eslint-config-react-app/base.js index b6acd702ea3..bea4f87b36f 100644 --- a/packages/eslint-config-react-app/base.js +++ b/packages/eslint-config-react-app/base.js @@ -51,8 +51,8 @@ module.exports = { rules: { 'react/jsx-uses-vars': 'warn', + 'react/jsx-uses-react': 'warn', ...(!hasJsxRuntime && { - 'react/jsx-uses-react': 'warn', 'react/react-in-jsx-scope': 'error', }), }, diff --git a/packages/react-dev-utils/eslintFormatter.js b/packages/react-dev-utils/eslintFormatter.js index cdef9c70b43..47b111f7568 100644 --- a/packages/react-dev-utils/eslintFormatter.js +++ b/packages/react-dev-utils/eslintFormatter.js @@ -7,10 +7,13 @@ 'use strict'; +const path = require('path'); const chalk = require('chalk'); const stripAnsi = require('strip-ansi'); const table = require('text-table'); +const cwd = process.cwd(); + function isError(message) { if (message.fatal || message.severity === 2) { return true; @@ -18,6 +21,10 @@ function isError(message) { return false; } +function getRelativePath(filePath) { + return path.relative(cwd, filePath); +} + function formatter(results) { let output = '\n'; let hasErrors = false; @@ -73,6 +80,10 @@ function formatter(results) { }, }); + // print the filename and relative path + output += `${getRelativePath(result.filePath)}\n`; + + // print the errors output += `${outputTable}\n\n`; }); diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 31eec3157da..4075824d794 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -26,6 +26,7 @@ const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); +const ESLintPlugin = require('eslint-webpack-plugin'); const paths = require('./paths'); const modules = require('./modules'); const getClientEnvironment = require('./env'); @@ -349,29 +350,6 @@ module.exports = function (webpackEnv) { rules: [ // Disable require.ensure as it's not a standard language feature. { parser: { requireEnsure: false } }, - - // First, run the linter. - // It's important to do this before Babel processes the JS. - { - test: /\.(js|mjs|jsx|ts|tsx)$/, - enforce: 'pre', - use: [ - { - options: { - cache: true, - cwd: paths.appPath, - formatter: require.resolve('react-dev-utils/eslintFormatter'), - eslintPath: require.resolve('eslint'), - resolvePluginsRelativeTo: __dirname, - baseConfig: { - extends: [require.resolve('eslint-config-react-app/base')], - }, - }, - loader: require.resolve('eslint-loader'), - }, - ], - include: paths.appSrc, - }, { // "oneOf" will traverse all following loaders until one will // match the requirements. When no loader matches it will fall @@ -742,6 +720,19 @@ module.exports = function (webpackEnv) { // The formatter is invoked directly in WebpackDevServerUtils during development formatter: isEnvProduction ? typescriptFormatter : undefined, }), + new ESLintPlugin({ + // Plugin options + extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'], + formatter: require.resolve('react-dev-utils/eslintFormatter'), + eslintPath: require.resolve('eslint'), + context: paths.appSrc, + // ESLint class options + cwd: paths.appPath, + resolvePluginsRelativeTo: __dirname, + baseConfig: { + extends: [require.resolve('eslint-config-react-app/base')], + }, + }), ].filter(Boolean), // Some libraries import Node modules but don't use them in the browser. // Tell webpack to provide empty mocks for them so importing them works. diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 434864e4359..bc26828a12f 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -46,13 +46,13 @@ "dotenv-expand": "5.1.0", "eslint": "^7.9.0", "eslint-config-react-app": "^5.2.1", - "eslint-loader": "^4.0.2", "eslint-plugin-flowtype": "^5.2.0", "eslint-plugin-import": "^2.22.0", "eslint-plugin-jest": "^24.0.1", "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-react": "^7.20.6", "eslint-plugin-react-hooks": "^4.1.2", + "eslint-webpack-plugin": "^2.1.0", "file-loader": "6.1.0", "fs-extra": "^9.0.0", "html-webpack-plugin": "4.4.1",