From ee2b0e54330409df51f9ed2ac78090c77afd8f53 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Wed, 17 Jul 2024 17:08:02 +0100 Subject: [PATCH] cli: add support for forcing use of react development when building Signed-off-by: MT Lewis --- .changeset/little-bulldogs-guess.md | 8 +++++ packages/cli/src/lib/bundler/config.ts | 44 +++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 .changeset/little-bulldogs-guess.md diff --git a/.changeset/little-bulldogs-guess.md b/.changeset/little-bulldogs-guess.md new file mode 100644 index 0000000000..8d247a182b --- /dev/null +++ b/.changeset/little-bulldogs-guess.md @@ -0,0 +1,8 @@ +--- +'@backstage/cli': patch +--- + +Add ability to force use of the development versions of `react` and `react-dom` +by setting the `FORCE_REACT_DEVELOPMENT` environment variable to `true` when +building, for example by using a command like `FORCE_REACT_DEVELOPMENT=true yarn +build:all`. diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 60c8a7be66..44cdc4a475 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -15,7 +15,8 @@ */ import { BackendBundlingOptions, BundlingOptions } from './types'; -import { posix as posixPath, resolve as resolvePath } from 'path'; +import { posix as posixPath, resolve as resolvePath, dirname } from 'path'; +import chalk from 'chalk'; import webpack, { ProvidePlugin } from 'webpack'; import { BackstagePackage } from '@backstage/cli-node'; @@ -33,7 +34,7 @@ import fs from 'fs-extra'; import { getPackages } from '@manypkg/get-packages'; import { isChildPath } from '@backstage/cli-common'; import nodeExternals from 'webpack-node-externals'; -import { optimization } from './optimization'; +import { optimization as optimizationConfig } from './optimization'; import pickBy from 'lodash/pickBy'; import { readEntryPoints } from '../entryPoints'; import { runPlain } from '../run'; @@ -232,12 +233,47 @@ export async function createConfig( require.resolve('react-refresh'), ]; + const mode = isDev ? 'development' : 'production'; + const optimization = optimizationConfig(options); + + if (process.env.FORCE_REACT_DEVELOPMENT === 'true') { + console.log( + chalk.yellow( + `⚠️ WARNING: Forcing react and react-dom into development mode. This build should not be used in production.`, + ), + ); + + const reactPackageDirs = [ + `${dirname(require.resolve('react/package.json'))}/`, + `${dirname(require.resolve('react-dom/package.json'))}/`, + ]; + + // Don't define process.env.NODE_ENV with value matching config.mode. + optimization.nodeEnv = false; + + // Instead, provide a custom definition which always uses "development" if + // the module is part of `react` or `react-dom`, and `config.mode` otherwise. + plugins.push( + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': webpack.DefinePlugin.runtimeValue( + ({ module }) => { + if (reactPackageDirs.some(val => module.resource.startsWith(val))) { + return '"development"'; + } + + return `"${mode}"`; + }, + ), + }), + ); + } + const withCache = yn(process.env[BUILD_CACHE_ENV_VAR], { default: false }); return { - mode: isDev ? 'development' : 'production', + mode, profile: false, - optimization: optimization(options), + optimization, bail: false, performance: { hints: false, // we check the gzip size instead