feat: support create-react-app v5 (#19434)

This commit is contained in:
Zachary Williams
2021-12-21 13:18:03 -06:00
committed by GitHub
parent 7453c1d61d
commit 415a7b149a
3 changed files with 70 additions and 1 deletions
@@ -5,6 +5,7 @@ const { allowModuleSourceInPlace } = require('../utils/webpack-helpers')
const { addCypressToWebpackEslintRulesInPlace } = require('../utils/eslint-helpers')
const { getTranspileFolders } = require('../utils/get-transpile-folders')
const { addFolderToBabelLoaderTranspileInPlace } = require('../utils/babel-helpers')
const { reactScriptsFiveModifications, isReactScripts5 } = require('../../dist/react-scripts/reactScriptsFive')
module.exports = function findReactScriptsWebpackConfig (config, {
webpackConfigPath,
@@ -28,6 +29,12 @@ module.exports = function findReactScriptsWebpackConfig (config, {
addFolderToBabelLoaderTranspileInPlace(cypressFolder, webpackConfig)
})
if (isReactScripts5) {
debug('Modifying configuration for react-scripts@5')
reactScriptsFiveModifications(webpackConfig)
}
debug('resolved webpack config: %o', webpackConfig)
return webpackConfig
@@ -0,0 +1,61 @@
import _debug from 'debug'
import type { Configuration } from 'webpack'
import reactScriptsPackageJson from 'react-scripts/package.json'
const debug = _debug('@cypress/react:react-scripts')
type DefinePlugin =
| { definitions: Record<string, Record<string, any>> }
| undefined;
type ESLintWebpackPlugin =
| { options: { baseConfig?: { globals?: Record<string, any> } } }
| undefined;
export function reactScriptsFiveModifications (webpackConfig: Configuration) {
// React-Scripts sets the webpack target to ["browserslist"] which tells
// webpack to target the browsers found within the browserslist config
// depending on the environment (process.env.NODE_ENV). Since we set
// process.env.NODE_ENV = "test", webpack is unable to find any browsers and errors.
// We set BROWSERSLIST_ENV = "development" to override the default NODE_ENV search of browsers.
if (!process.env.BROWSERSLIST_ENV) {
process.env.BROWSERSLIST_ENV = 'development'
}
// We use the "development" configuration of the react-scripts webpack config.
// There is a conflict when settings process.env.NODE_ENV = "test" since DefinePlugin
// uses the "development" configuration and expects process.env.NODE_ENV = "development".
const definePlugin: DefinePlugin = webpackConfig.plugins?.find(
(plugin) => plugin.constructor.name === 'DefinePlugin'
) as unknown as DefinePlugin
if (definePlugin) {
const processEnv = definePlugin.definitions['process.env']
processEnv.NODE_ENV = JSON.stringify('development')
debug('Found "DefinePlugin", modified "process.env" definition %o', processEnv)
}
// React-Scripts v5 no longers uses a loader to configure eslint, so we add globals
// to the plugin.
const eslintPlugin = webpackConfig.plugins?.find(
(plugin) => plugin.constructor.name === 'ESLintWebpackPlugin'
) as unknown as ESLintWebpackPlugin
if (eslintPlugin) {
const cypressGlobals = ['cy', 'Cypress', 'before', 'after', 'context']
.reduce((acc, global) => ({ ...acc, [global]: 'writable' }), {})
eslintPlugin.options.baseConfig = {
...eslintPlugin.options.baseConfig,
globals: {
...eslintPlugin.options.baseConfig?.globals,
...cypressGlobals,
},
}
debug('Found ESLintWebpackPlugin, modified eslint config %o', eslintPlugin.options.baseConfig)
}
}
export const isReactScripts5 = Number(reactScriptsPackageJson.version[0]) >= 5
+2 -1
View File
@@ -19,7 +19,8 @@
"cypress"
] /* Type declaration files to be included in compilation. */,
"allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
"esModuleInterop": true
"esModuleInterop": true,
"resolveJsonModule": true
},
"include": ["src/**/*.ts"],
}