From ee2b0e54330409df51f9ed2ac78090c77afd8f53 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Wed, 17 Jul 2024 17:08:02 +0100 Subject: [PATCH 1/7] 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 From 644d4696c28ca675efc0f240c428b5f43547f734 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Thu, 18 Jul 2024 10:35:40 +0100 Subject: [PATCH 2/7] cli: only allow forcing react development mode when module federation is enabled Signed-off-by: MT Lewis --- .changeset/little-bulldogs-guess.md | 15 ++++++++++++--- packages/cli/src/lib/bundler/config.ts | 5 ++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.changeset/little-bulldogs-guess.md b/.changeset/little-bulldogs-guess.md index 8d247a182b..1f86f0a67f 100644 --- a/.changeset/little-bulldogs-guess.md +++ b/.changeset/little-bulldogs-guess.md @@ -3,6 +3,15 @@ --- 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`. +to allow for detailed error messages and use of fast-refresh. Note that builds +with the development versions of `react` and `react-dom` should not be +deployed in production. + +This feature can be used by setting the `FORCE_REACT_DEVELOPMENT` environment +variable to `true`: + +```bash +EXPERIMENTAL_MODULE_FEDERATION=true \ +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 44cdc4a475..8e3d7eee19 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -236,7 +236,10 @@ export async function createConfig( const mode = isDev ? 'development' : 'production'; const optimization = optimizationConfig(options); - if (process.env.FORCE_REACT_DEVELOPMENT === 'true') { + if ( + process.env.EXPERIMENTAL_MODULE_FEDERATION === 'true' && + 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.`, From de4cd433c15a6cc2ba63448ff31542decedaf2bf Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 19 Jul 2024 13:31:28 +0100 Subject: [PATCH 3/7] cli: simplify changeset Co-authored-by: Patrik Oldsberg Signed-off-by: MT Lewis --- .changeset/little-bulldogs-guess.md | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.changeset/little-bulldogs-guess.md b/.changeset/little-bulldogs-guess.md index 1f86f0a67f..3e646a033f 100644 --- a/.changeset/little-bulldogs-guess.md +++ b/.changeset/little-bulldogs-guess.md @@ -2,16 +2,4 @@ '@backstage/cli': patch --- -Add ability to force use of the development versions of `react` and `react-dom` -to allow for detailed error messages and use of fast-refresh. Note that builds -with the development versions of `react` and `react-dom` should not be -deployed in production. - -This feature can be used by setting the `FORCE_REACT_DEVELOPMENT` environment -variable to `true`: - -```bash -EXPERIMENTAL_MODULE_FEDERATION=true \ -FORCE_REACT_DEVELOPMENT=true \ -yarn build:all -``` +The experimental module federation build now has the ability to force the use of development versions of `react` and `react-dom` by setting the `FORCE_REACT_DEVELOPMENT` flag. From 2e1a7f10e5f29af3e4f253ad62b7d61148c5f995 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 19 Jul 2024 13:48:20 +0100 Subject: [PATCH 4/7] cli: only check for truthiness of environment variables when forcing react mode Signed-off-by: MT Lewis --- packages/cli/src/lib/bundler/config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 8e3d7eee19..3d3be4f485 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -237,8 +237,8 @@ export async function createConfig( const optimization = optimizationConfig(options); if ( - process.env.EXPERIMENTAL_MODULE_FEDERATION === 'true' && - process.env.FORCE_REACT_DEVELOPMENT === 'true' + !!process.env.EXPERIMENTAL_MODULE_FEDERATION && + !!process.env.FORCE_REACT_DEVELOPMENT ) { console.log( chalk.yellow( From 0983429447db996138e90c6168f82e47b405223e Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 19 Jul 2024 14:05:28 +0100 Subject: [PATCH 5/7] cli: expand comment Signed-off-by: MT Lewis --- packages/cli/src/lib/bundler/config.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 3d3be4f485..e10ac0253e 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -251,7 +251,9 @@ export async function createConfig( `${dirname(require.resolve('react-dom/package.json'))}/`, ]; - // Don't define process.env.NODE_ENV with value matching config.mode. + // Don't define process.env.NODE_ENV with value matching config.mode. If we + // don't set this to false, webpack will define the value of + // process.env.NODE_ENV for us, and the definition below will be ignored. optimization.nodeEnv = false; // Instead, provide a custom definition which always uses "development" if From 232b134606d193c262d38892e86e41bc979305fd Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 19 Jul 2024 14:07:35 +0100 Subject: [PATCH 6/7] cli: skip forcing react to development mode if mode is development anyway Signed-off-by: MT Lewis --- packages/cli/src/lib/bundler/config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index e10ac0253e..1f29277676 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -237,6 +237,7 @@ export async function createConfig( const optimization = optimizationConfig(options); if ( + mode === 'production' && !!process.env.EXPERIMENTAL_MODULE_FEDERATION && !!process.env.FORCE_REACT_DEVELOPMENT ) { From 6c94522688dc49b850db6d23c57b1a794c4b0602 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 19 Jul 2024 14:08:54 +0100 Subject: [PATCH 7/7] cli: remove explicit boolean coercions when forcing react mode Signed-off-by: MT Lewis --- packages/cli/src/lib/bundler/config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 1f29277676..9a611a5954 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -238,8 +238,8 @@ export async function createConfig( if ( mode === 'production' && - !!process.env.EXPERIMENTAL_MODULE_FEDERATION && - !!process.env.FORCE_REACT_DEVELOPMENT + process.env.EXPERIMENTAL_MODULE_FEDERATION && + process.env.FORCE_REACT_DEVELOPMENT ) { console.log( chalk.yellow(