From 0aeaf9ce8e6751634c46cf45233e3711a093338e Mon Sep 17 00:00:00 2001 From: Gokhan Kurt Date: Sun, 17 Oct 2021 21:20:07 +0300 Subject: [PATCH 1/3] add lint command --- packages/react-scripts/bin/react-scripts.js | 9 ++++- packages/react-scripts/config/eslintConfig.js | 31 ++++++++++++++ packages/react-scripts/config/modules.js | 14 +++++++ .../react-scripts/config/webpack.config.js | 34 ++-------------- packages/react-scripts/scripts/init.js | 1 + packages/react-scripts/scripts/lint.js | 40 +++++++++++++++++++ tasks/e2e-simple.sh | 6 +++ 7 files changed, 102 insertions(+), 33 deletions(-) create mode 100644 packages/react-scripts/config/eslintConfig.js create mode 100644 packages/react-scripts/scripts/lint.js diff --git a/packages/react-scripts/bin/react-scripts.js b/packages/react-scripts/bin/react-scripts.js index 09604f6a03f..1b818518f1b 100755 --- a/packages/react-scripts/bin/react-scripts.js +++ b/packages/react-scripts/bin/react-scripts.js @@ -19,12 +19,17 @@ const spawn = require('react-dev-utils/crossSpawn'); const args = process.argv.slice(2); const scriptIndex = args.findIndex( - x => x === 'build' || x === 'eject' || x === 'start' || x === 'test' + x => + x === 'build' || + x === 'eject' || + x === 'start' || + x === 'test' || + x === 'lint' ); const script = scriptIndex === -1 ? args[0] : args[scriptIndex]; const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : []; -if (['build', 'eject', 'start', 'test'].includes(script)) { +if (['build', 'eject', 'start', 'test', 'lint'].includes(script)) { const result = spawn.sync( process.execPath, nodeArgs diff --git a/packages/react-scripts/config/eslintConfig.js b/packages/react-scripts/config/eslintConfig.js new file mode 100644 index 00000000000..971674127c0 --- /dev/null +++ b/packages/react-scripts/config/eslintConfig.js @@ -0,0 +1,31 @@ +// @remove-on-eject-begin +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +// @remove-on-eject-end +'use strict'; + +const path = require('path'); +const paths = require('./paths'); +const modules = require('./modules'); + +const baseConfig = { + extends: [require.resolve('eslint-config-react-app/base')], + rules: { + ...(!modules.hasJsxRuntime && { + 'react/react-in-jsx-scope': 'error', + }), + }, +}; + +module.exports = { + extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'], + cache: true, + cacheLocation: path.resolve(paths.appNodeModules, '.cache/.eslintcache'), + cwd: paths.appPath, + resolvePluginsRelativeTo: __dirname, + baseConfig, +}; diff --git a/packages/react-scripts/config/modules.js b/packages/react-scripts/config/modules.js index 22820993a25..48f53233386 100644 --- a/packages/react-scripts/config/modules.js +++ b/packages/react-scripts/config/modules.js @@ -131,11 +131,25 @@ function getModules() { const additionalModulePaths = getAdditionalModulePaths(options); + const hasJsxRuntime = (() => { + if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') { + return false; + } + + try { + require.resolve('react/jsx-runtime'); + return true; + } catch (e) { + return false; + } + })(); + return { additionalModulePaths: additionalModulePaths, webpackAliases: getWebpackAliases(options), jestAliases: getJestAliases(options), hasTsConfig, + hasJsxRuntime, }; } diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index 7f3b2234dd2..2e2b3610645 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -24,6 +24,7 @@ const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); const ESLintPlugin = require('eslint-webpack-plugin'); +const eslintConfig = require('./eslintConfig'); const paths = require('./paths'); const modules = require('./modules'); const getClientEnvironment = require('./env'); @@ -77,19 +78,6 @@ const cssModuleRegex = /\.module\.css$/; const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; -const hasJsxRuntime = (() => { - if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') { - return false; - } - - try { - require.resolve('react/jsx-runtime'); - return true; - } catch (e) { - return false; - } -})(); - // This is the production and development configuration. // It is focused on developer experience, fast rebuilds, and a minimal bundle. module.exports = function (webpackEnv) { @@ -403,7 +391,7 @@ module.exports = function (webpackEnv) { [ require.resolve('babel-preset-react-app'), { - runtime: hasJsxRuntime ? 'automatic' : 'classic', + runtime: modules.hasJsxRuntime ? 'automatic' : 'classic', }, ], ], @@ -744,27 +732,11 @@ module.exports = function (webpackEnv) { !disableESLintPlugin && new ESLintPlugin({ // Plugin options - extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'], formatter: require.resolve('react-dev-utils/eslintFormatter'), eslintPath: require.resolve('eslint'), failOnError: !(isEnvDevelopment && emitErrorsAsWarnings), context: paths.appSrc, - cache: true, - cacheLocation: path.resolve( - paths.appNodeModules, - '.cache/.eslintcache' - ), - // ESLint class options - cwd: paths.appPath, - resolvePluginsRelativeTo: __dirname, - baseConfig: { - extends: [require.resolve('eslint-config-react-app/base')], - rules: { - ...(!hasJsxRuntime && { - 'react/react-in-jsx-scope': 'error', - }), - }, - }, + ...eslintConfig, }), ].filter(Boolean), // Turn off performance processing because we utilize diff --git a/packages/react-scripts/scripts/init.js b/packages/react-scripts/scripts/init.js index 16822e7a8a2..28ca4295039 100644 --- a/packages/react-scripts/scripts/init.js +++ b/packages/react-scripts/scripts/init.js @@ -188,6 +188,7 @@ module.exports = function ( build: 'react-scripts build', test: 'react-scripts test', eject: 'react-scripts eject', + lint: 'react-scripts lint', }, templateScripts ); diff --git a/packages/react-scripts/scripts/lint.js b/packages/react-scripts/scripts/lint.js new file mode 100644 index 00000000000..cd124ce3312 --- /dev/null +++ b/packages/react-scripts/scripts/lint.js @@ -0,0 +1,40 @@ +// @remove-on-eject-begin +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +// @remove-on-eject-end +'use strict'; + +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = + process.env.BABEL_ENV || process.env.NODE_ENV || 'development'; +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +process.on('unhandledRejection', err => { + throw err; +}); + +// Ensure environment variables are read. +require('../config/env'); + +const paths = require('../config/paths'); +const eslintConfig = require('../config/eslintConfig'); +const formatter = require('react-dev-utils/eslintFormatter'); + +const { ESLint } = require('eslint'); + +(async function main() { + const eslint = new ESLint(eslintConfig); + const results = await eslint.lintFiles([paths.appSrc]); + const resultText = formatter(results); + console.log(resultText); +})().catch(error => { + process.exitCode = 1; + console.error(error); +}); diff --git a/tasks/e2e-simple.sh b/tasks/e2e-simple.sh index 3d01fba6f0c..29c94ea5712 100755 --- a/tasks/e2e-simple.sh +++ b/tasks/e2e-simple.sh @@ -221,6 +221,9 @@ function verify_module_scope { # Enter the app directory cd test-app +# Test linter +npm run lint + # Test the build npm run build # Check for expected output @@ -254,6 +257,9 @@ echo yes | npm run eject # Test ejected files were staged test -n "$(git diff --staged --name-only)" +# Test linter +npm run lint + # Test the build npm run build # Check for expected output From 6d512788c456f115938dfe14c8665888c8d1606a Mon Sep 17 00:00:00 2001 From: Gokhan Kurt Date: Sun, 26 Dec 2021 19:03:04 +0300 Subject: [PATCH 2/3] dont add lint command to package.json by default --- packages/react-scripts/scripts/init.js | 1 - tasks/e2e-simple.sh | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/scripts/init.js b/packages/react-scripts/scripts/init.js index 28ca4295039..16822e7a8a2 100644 --- a/packages/react-scripts/scripts/init.js +++ b/packages/react-scripts/scripts/init.js @@ -188,7 +188,6 @@ module.exports = function ( build: 'react-scripts build', test: 'react-scripts test', eject: 'react-scripts eject', - lint: 'react-scripts lint', }, templateScripts ); diff --git a/tasks/e2e-simple.sh b/tasks/e2e-simple.sh index 96f0949864e..741310d5365 100755 --- a/tasks/e2e-simple.sh +++ b/tasks/e2e-simple.sh @@ -214,7 +214,7 @@ function verify_module_scope { cd test-app # Test linter -npm run lint +npx react-scripts lint # Test the build npm run build @@ -250,7 +250,7 @@ echo yes | npm run eject test -n "$(git diff --staged --name-only)" # Test linter -npm run lint +npx react-scripts lint # Test the build npm run build From e13c83328f935084e67d1d6db825c758f437a178 Mon Sep 17 00:00:00 2001 From: Gokhan Kurt Date: Sun, 26 Dec 2021 22:57:25 +0300 Subject: [PATCH 3/3] fix e2e test script after ejecting --- tasks/e2e-simple.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e-simple.sh b/tasks/e2e-simple.sh index 741310d5365..76377cff9cd 100755 --- a/tasks/e2e-simple.sh +++ b/tasks/e2e-simple.sh @@ -250,7 +250,7 @@ echo yes | npm run eject test -n "$(git diff --staged --name-only)" # Test linter -npx react-scripts lint +node scripts/lint.js # Test the build npm run build