From cda00d96874a0c58af75901d443c4dc13d4312c8 Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Fri, 27 Jan 2023 15:50:25 -0500 Subject: [PATCH] fix(webpack): config migrations should account for different configurations (#14672) --- .../webpack-config-setup.spec.ts.snap | 8 + .../webpack-config-setup.spec.ts | 169 ++++++++++-- .../update-15-6-3/webpack-config-setup.ts | 45 +++- .../webpack-config-setup.spec.ts.snap | 8 + .../webpack-config-setup.spec.ts | 241 +++++++++++++----- .../update-15-6-3/webpack-config-setup.ts | 36 ++- 6 files changed, 400 insertions(+), 107 deletions(-) diff --git a/packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap b/packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap index 7f2fa04698..d6b8aafe37 100644 --- a/packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap +++ b/packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap @@ -9,6 +9,8 @@ exports[`15.6.3 migration (setup webpack.config file for React apps) should crea module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { // Update the webpack config as needed here. // e.g. config.plugins.push(new MyPlugin()) + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return config; }); " @@ -23,6 +25,8 @@ exports[`15.6.3 migration (setup webpack.config file for React apps) should crea module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { // Update the webpack config as needed here. // e.g. config.plugins.push(new MyPlugin()) + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return config; }); " @@ -37,6 +41,8 @@ exports[`15.6.3 migration (setup webpack.config file for React apps) should crea module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { // Update the webpack config as needed here. // e.g. config.plugins.push(new MyPlugin()) + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return config; }); " @@ -51,6 +57,8 @@ exports[`15.6.3 migration (setup webpack.config file for React apps) should crea module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { // Note: This was added by an Nx migration. // You should consider inlining the logic into this file. + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return require('./webpack.something.old.ts')(config, context); }); " diff --git a/packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts b/packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts index 3bc6443f1b..1dd67348e6 100644 --- a/packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts +++ b/packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts @@ -11,7 +11,9 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => { beforeEach(async () => { tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + }); + it('should create webpack.config.js for React projects only', async () => { addProjectConfiguration(tree, 'react1', { root: 'apps/react1', targets: { @@ -62,6 +64,28 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => { }); tree.write('apps/react4/webpack.something.ts', 'some content'); + await webpackConfigSetup(tree); + + expect( + tree.read('apps/react1/webpack.config.js', 'utf-8') + ).toMatchSnapshot(); + expect( + tree.read('apps/react2/webpack.config.js', 'utf-8') + ).toMatchSnapshot(); + expect( + tree.read('apps/react3/webpack.config.js', 'utf-8') + ).toMatchSnapshot(); + + expect( + tree.read('apps/react4/webpack.something.ts', 'utf-8') + ).toMatchSnapshot(); + + expect( + tree.read('apps/react4/webpack.something.old.ts', 'utf-8') + ).toMatchInlineSnapshot(`"some content"`); + }); + + it('should ignore non-react projects or isolatedConfig', async () => { addProjectConfiguration(tree, 'app4', { root: 'apps/app4', targets: { @@ -73,7 +97,6 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => { }, }, }); - tree.write('some/random/path/webpack.something.ts', 'some content'); addProjectConfiguration(tree, 'app5', { @@ -101,29 +124,7 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => { }); await webpackConfigSetup(tree); - }); - it('should create webpack.config.js for React projects only', () => { - expect( - tree.read('apps/react1/webpack.config.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('apps/react2/webpack.config.js', 'utf-8') - ).toMatchSnapshot(); - expect( - tree.read('apps/react3/webpack.config.js', 'utf-8') - ).toMatchSnapshot(); - - expect( - tree.read('apps/react4/webpack.something.ts', 'utf-8') - ).toMatchSnapshot(); - - expect( - tree.read('apps/react4/webpack.something.old.ts', 'utf-8') - ).toMatchInlineSnapshot(`"some content"`); - }); - - it('should ignore non-react projects or isolatedConfig', () => { expect( tree.read('some/random/path/webpack.something.ts', 'utf-8') ).toMatchInlineSnapshot(`"some content"`); @@ -134,7 +135,60 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => { expect(tree.exists('apps/app6/webpack.config.js')).toBeFalsy(); }); - it('should update the project configuration - executor options', () => { + it('should update the project configuration - executor options', async () => { + addProjectConfiguration(tree, 'react1', { + root: 'apps/react1', + targets: { + build: { + executor: '@nrwl/webpack:webpack', + options: { + main: 'apps/react1/src/main.tsx', + webpackConfig: '@nrwl/react/plugins/webpack', + }, + }, + }, + }); + + addProjectConfiguration(tree, 'react2', { + root: 'apps/react2', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: { + main: 'apps/react2/src/main.tsx', + }, + }, + }, + }); + + addProjectConfiguration(tree, 'react3', { + root: 'apps/react3', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: { + webpackConfig: '@nrwl/react/plugins/webpack', + }, + }, + }, + }); + + addProjectConfiguration(tree, 'react4', { + root: 'apps/react4', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: { + main: 'apps/react4/src/main.tsx', + webpackConfig: 'apps/react4/webpack.something.ts', + }, + }, + }, + }); + tree.write('apps/react4/webpack.something.ts', 'some content'); + + await webpackConfigSetup(tree); + expect( readProjectConfiguration(tree, 'react1').targets.build.options .webpackConfig @@ -173,4 +227,71 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => { .isolatedConfig ).toBeTruthy(); }); + + it('should migrate configurations (dev, prod, etc.) with webpackConfig but ignore ones without it', async () => { + addProjectConfiguration(tree, 'reactapp', { + root: 'apps/reactapp', + targets: { + build: { + executor: '@nrwl/webpack:webpack', + options: { + main: 'apps/reactapp/src/main.tsx', + webpackConfig: 'apps/reactapp/webpack.config.js', + }, + configurations: { + foo: {}, + bar: { + webpackConfig: 'apps/reactapp/webpack.config.bar.js', + }, + }, + }, + }, + }); + tree.write('apps/reactapp/webpack.config.js', 'default'); + tree.write('apps/reactapp/webpack.config.bar.js', 'bar'); + + addProjectConfiguration(tree, 'alreadymigrated', { + root: 'apps/alreadymigrated', + targets: { + build: { + executor: '@nrwl/webpack:webpack', + options: { + isolatedConfig: true, + main: 'apps/alreadymigrated/src/main.tsx', + webpackConfig: 'apps/alreadymigrated/webpack.config.js', + }, + configurations: { + foo: {}, + bar: { + webpackConfig: 'apps/alreadymigrated/webpack.config.bar.js', + }, + }, + }, + }, + }); + tree.write('apps/alreadymigrated/webpack.config.js', 'default'); + tree.write('apps/alreadymigrated/webpack.config.bar.js', 'bar'); + + await webpackConfigSetup(tree); + + expect(tree.read('apps/reactapp/webpack.config.old.js', 'utf-8')).toContain( + 'default' + ); + expect( + tree.read('apps/reactapp/webpack.config.bar.old.js', 'utf-8') + ).toContain('bar'); + + expect( + tree.read('apps/alreadymigrated/webpack.config.js', 'utf-8') + ).toContain('default'); + expect( + tree.read('apps/alreadymigrated/webpack.config.bar.js', 'utf-8') + ).toContain('bar'); + expect( + tree.exists('apps/alreadymigrated/webpack.config.old.js') + ).toBeFalsy(); + expect( + tree.exists('apps/alreadymigrated/webpack.config.bar.old.js') + ).toBeFalsy(); + }); }); diff --git a/packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts b/packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts index 9a8287249a..399ad06d79 100644 --- a/packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts +++ b/packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts @@ -7,23 +7,40 @@ import { } from '@nrwl/devkit'; import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils'; import { basename } from 'path'; +import type { WebpackExecutorOptions } from '@nrwl/webpack'; export default async function (tree: Tree) { - forEachExecutorOptions( + // Since projects can have multiple configurations, we need to know if the default options + // need to be migrated or not. If so then the subsequent configurations with `webpackConfig` also need to be. + const defaultOptionsUpdated = new Set(); + forEachExecutorOptions( tree, '@nrwl/webpack:webpack', - (options: {}, projectName, targetName, _configurationName) => { + (options, projectName, targetName, configurationName) => { + const projectConfiguration = readProjectConfiguration(tree, projectName); + const defaultOptions = projectConfiguration.targets[targetName].options; + const defaultWasUpdated = defaultOptionsUpdated.has(projectName); + + // If default was not updated (for different configurations), we don't do anything // If isolatedConfig is set, we don't need to do anything // If it is NOT React, we don't need to do anything if ( - options?.['isolatedConfig'] || - !( - options?.['main']?.match(/main\.(t|j)sx$/) || - options?.['webpackConfig'] === '@nrwl/react/plugins/webpack' - ) + !defaultWasUpdated && + (defaultOptions?.['isolatedConfig'] || + !( + defaultOptions?.['main']?.match(/main\.(t|j)sx$/) || + defaultOptions?.['webpackConfig'] === '@nrwl/react/plugins/webpack' + )) ) { return; } + defaultOptionsUpdated.add(projectName); + + // If this is not the default options (e.g. for development, production, or something custom), + // then skip it unless it specifically configures a webpackConfig file + if (configurationName && !options?.webpackConfig) { + return; + } // If webpackConfig is set, update it with the new options // If webpackConfig is not set, we need to create a new @@ -55,6 +72,8 @@ export default async function (tree: Tree) { module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { // Note: This was added by an Nx migration. // You should consider inlining the logic into this file. + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return require('./${justTheFileName}')(config, context); }); ` @@ -62,11 +81,9 @@ export default async function (tree: Tree) { options['isolatedConfig'] = true; - const projectConfiguration = readProjectConfiguration( - tree, - projectName - ); - projectConfiguration.targets[targetName].options = options; + projectConfiguration.targets[targetName][ + configurationName ?? 'options' + ] = options; updateProjectConfiguration(tree, projectName, projectConfiguration); logger.info( @@ -86,7 +103,7 @@ export default async function (tree: Tree) { ); if (!options) { - options = {}; + options = {} as WebpackExecutorOptions; } options[ @@ -104,6 +121,8 @@ export default async function (tree: Tree) { module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { // Update the webpack config as needed here. // e.g. config.plugins.push(new MyPlugin()) + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return config; }); ` diff --git a/packages/webpack/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap b/packages/webpack/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap index 6a7184f06e..a26958896a 100644 --- a/packages/webpack/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap +++ b/packages/webpack/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap @@ -8,6 +8,8 @@ exports[`15.6.3 migration (setup webpack.config file) should create webpack.conf module.exports = composePlugins(withNx(), (config) => { // Update the webpack config as needed here. // e.g. config.plugins.push(new MyPlugin()) + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return config; }); " @@ -21,6 +23,8 @@ exports[`15.6.3 migration (setup webpack.config file) should create webpack.conf module.exports = composePlugins(withNx(), (config) => { // Update the webpack config as needed here. // e.g. config.plugins.push(new MyPlugin()) + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return config; }); " @@ -34,6 +38,8 @@ exports[`15.6.3 migration (setup webpack.config file) should rename existing web module.exports = composePlugins(withNx(), (config, { options, context }) => { // Note: This was added by an Nx migration. // You should consider inlining the logic into this file. + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return require('./webpack.config.old.js')(config, context); }); " @@ -47,6 +53,8 @@ exports[`15.6.3 migration (setup webpack.config file) should rename existing web module.exports = composePlugins(withNx(), (config, { options, context }) => { // Note: This was added by an Nx migration. // You should consider inlining the logic into this file. + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return require('./webpack.something.old.ts')(config, context); }); " diff --git a/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.spec.ts b/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.spec.ts index 2ee0b3d4d2..f06b8561b0 100644 --- a/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.spec.ts +++ b/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.spec.ts @@ -11,7 +11,78 @@ describe('15.6.3 migration (setup webpack.config file)', () => { beforeEach(async () => { tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + }); + it('should create webpack.config.js for projects that do not have one', async () => { + addProjectConfiguration(tree, 'app1', { + root: 'apps/app1', + targets: { + build: { + executor: '@nrwl/webpack:webpack', + options: {}, + }, + }, + }); + addProjectConfiguration(tree, 'app2', { + root: 'apps/app2', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: {}, + }, + }, + }); + + await webpackConfigSetup(tree); + + expect(tree.read('apps/app1/webpack.config.js', 'utf-8')).toMatchSnapshot(); + expect(tree.read('apps/app2/webpack.config.js', 'utf-8')).toMatchSnapshot(); + }); + + it('should rename existing webpack.config file and create new one that requires it', async () => { + addProjectConfiguration(tree, 'app3', { + root: 'apps/app3', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: { + webpackConfig: 'apps/app3/webpack.config.js', + }, + }, + }, + }); + tree.write('apps/app3/webpack.config.js', 'some content'); + + addProjectConfiguration(tree, 'app4', { + root: 'apps/app4', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: { + webpackConfig: 'some/random/path/webpack.something.ts', + }, + }, + }, + }); + tree.write('some/random/path/webpack.something.ts', 'some content'); + + await webpackConfigSetup(tree); + + expect(tree.read('apps/app3/webpack.config.js', 'utf-8')).toMatchSnapshot(); + expect( + tree.read('apps/app3/webpack.config.old.js', 'utf-8') + ).toMatchInlineSnapshot(`"some content"`); + + expect( + tree.read('some/random/path/webpack.something.ts', 'utf-8') + ).toMatchSnapshot(); + + expect( + tree.read('some/random/path/webpack.something.old.ts', 'utf-8') + ).toMatchInlineSnapshot(`"some content"`); + }); + + it('should update the project configuration - executor options', async () => { addProjectConfiguration(tree, 'app1', { root: 'apps/app1', targets: { @@ -56,69 +127,10 @@ describe('15.6.3 migration (setup webpack.config file)', () => { }, }, }); - tree.write('some/random/path/webpack.something.ts', 'some content'); - addProjectConfiguration(tree, 'app5', { - root: 'apps/app5', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - isolatedConfig: true, - }, - }, - }, - }); - - addProjectConfiguration(tree, 'app6', { - root: 'apps/app6', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - webpackConfig: '@nrwl/react/plugins/webpack', - }, - }, - }, - }); - - addProjectConfiguration(tree, 'app7', { - root: 'apps/app7', - targets: { - custom: { - executor: '@nrwl/webpack:webpack', - options: { - main: 'apps/app7/src/main.tsx', - }, - }, - }, - }); - await webpackConfigSetup(tree); - }); - it('should create webpack.config.js for projects that do not have one', () => { - expect(tree.read('apps/app1/webpack.config.js', 'utf-8')).toMatchSnapshot(); - expect(tree.read('apps/app2/webpack.config.js', 'utf-8')).toMatchSnapshot(); - }); - - it('should rename existing webpack.config file and create new one that requires it', () => { - expect(tree.read('apps/app3/webpack.config.js', 'utf-8')).toMatchSnapshot(); - expect( - tree.read('apps/app3/webpack.config.old.js', 'utf-8') - ).toMatchInlineSnapshot(`"some content"`); - - expect( - tree.read('some/random/path/webpack.something.ts', 'utf-8') - ).toMatchSnapshot(); - - expect( - tree.read('some/random/path/webpack.something.old.ts', 'utf-8') - ).toMatchInlineSnapshot(`"some content"`); - }); - - it('should update the project configuration - executor options', () => { expect( readProjectConfiguration(tree, 'app1').targets.build.options.webpackConfig ).toBe('apps/app1/webpack.config.js'); @@ -157,12 +169,119 @@ describe('15.6.3 migration (setup webpack.config file)', () => { ).toBeTruthy(); }); - it('should not do anything if isolatedConfig is true', () => { + it('should not do anything if isolatedConfig is true', async () => { + addProjectConfiguration(tree, 'app5', { + root: 'apps/app5', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: { + isolatedConfig: true, + }, + }, + }, + }); + + await webpackConfigSetup(tree); + expect(tree.exists('apps/app5/webpack.config.js')).toBeFalsy(); }); - it('should not do anything if project is react', () => { + it('should not do anything if project is react', async () => { + addProjectConfiguration(tree, 'app6', { + root: 'apps/app6', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: { + webpackConfig: '@nrwl/react/plugins/webpack', + }, + }, + }, + }); + + addProjectConfiguration(tree, 'app7', { + root: 'apps/app7', + targets: { + custom: { + executor: '@nrwl/webpack:webpack', + options: { + main: 'apps/app7/src/main.tsx', + }, + }, + }, + }); + + await webpackConfigSetup(tree); + expect(tree.exists('apps/app6/webpack.config.js')).toBeFalsy(); expect(tree.exists('apps/app7/webpack.config.js')).toBeFalsy(); }); + + it('should migrate configurations (dev, prod, etc.) with webpackConfig but ignore ones without it', async () => { + addProjectConfiguration(tree, 'myapp', { + root: 'apps/myapp', + targets: { + build: { + executor: '@nrwl/webpack:webpack', + options: { + main: 'apps/myapp/src/main.ts', + webpackConfig: 'apps/myapp/webpack.config.js', + }, + configurations: { + foo: {}, + bar: { + webpackConfig: 'apps/myapp/webpack.config.bar.js', + }, + }, + }, + }, + }); + tree.write('apps/myapp/webpack.config.js', 'default'); + tree.write('apps/myapp/webpack.config.bar.js', 'bar'); + + addProjectConfiguration(tree, 'alreadymigrated', { + root: 'apps/alreadymigrated', + targets: { + build: { + executor: '@nrwl/webpack:webpack', + options: { + isolatedConfig: true, + main: 'apps/alreadymigrated/src/main.ts', + webpackConfig: 'apps/alreadymigrated/webpack.config.js', + }, + configurations: { + foo: {}, + bar: { + webpackConfig: 'apps/alreadymigrated/webpack.config.bar.js', + }, + }, + }, + }, + }); + tree.write('apps/alreadymigrated/webpack.config.js', 'default'); + tree.write('apps/alreadymigrated/webpack.config.bar.js', 'bar'); + + await webpackConfigSetup(tree); + + expect(tree.read('apps/myapp/webpack.config.old.js', 'utf-8')).toContain( + 'default' + ); + expect( + tree.read('apps/myapp/webpack.config.bar.old.js', 'utf-8') + ).toContain('bar'); + + expect( + tree.read('apps/alreadymigrated/webpack.config.js', 'utf-8') + ).toContain('default'); + expect( + tree.read('apps/alreadymigrated/webpack.config.bar.js', 'utf-8') + ).toContain('bar'); + expect( + tree.exists('apps/alreadymigrated/webpack.config.old.js') + ).toBeFalsy(); + expect( + tree.exists('apps/alreadymigrated/webpack.config.bar.old.js') + ).toBeFalsy(); + }); }); diff --git a/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.ts b/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.ts index a29c375648..5475cbbf2b 100644 --- a/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.ts +++ b/packages/webpack/src/migrations/update-15-6-3/webpack-config-setup.ts @@ -10,6 +10,9 @@ import { WebpackExecutorOptions } from '../../executors/webpack/schema'; import { basename } from 'path'; export default async function (tree: Tree) { + // Since projects can have multiple configurations, we need to know if the default options + // need to be migrated or not. If so then the subsequent configurations with `webpackConfig` also need to be. + const defaultOptionsUpdated = new Set(); forEachExecutorOptions( tree, '@nrwl/webpack:webpack', @@ -17,17 +20,30 @@ export default async function (tree: Tree) { options: WebpackExecutorOptions, projectName, targetName, - _configurationName + configurationName ) => { + const projectConfiguration = readProjectConfiguration(tree, projectName); + const defaultOptions = projectConfiguration.targets[targetName].options; + const defaultWasUpdated = defaultOptionsUpdated.has(projectName); + + // If default was not updated (for different configurations), we don't do anything // If isolatedConfig is set, we don't need to do anything // If project is React, we don't need to do anything if ( - options?.isolatedConfig || - options?.main?.match(/main\.(t|j)sx$/) || - options?.webpackConfig === '@nrwl/react/plugins/webpack' + !defaultWasUpdated && + (defaultOptions?.isolatedConfig || + defaultOptions?.main?.match(/main\.(t|j)sx$/) || + defaultOptions?.webpackConfig === '@nrwl/react/plugins/webpack') ) { return; } + defaultOptionsUpdated.add(projectName); + + // If this is not the base options (e.g. for development, production, or something custom), + // then skip it unless it specifically configures a webpackConfig file + if (configurationName && !options?.webpackConfig) { + return; + } // If webpackConfig is set, update it with the new options // If webpackConfig is not set, we need to create a new @@ -55,6 +71,8 @@ export default async function (tree: Tree) { module.exports = composePlugins(withNx(), (config, { options, context }) => { // Note: This was added by an Nx migration. // You should consider inlining the logic into this file. + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return require('./${justTheFileName}')(config, context); }); ` @@ -62,11 +80,9 @@ export default async function (tree: Tree) { options.isolatedConfig = true; - const projectConfiguration = readProjectConfiguration( - tree, - projectName - ); - projectConfiguration.targets[targetName].options = options; + projectConfiguration.targets[targetName][ + configurationName ?? 'options' + ] = options; updateProjectConfiguration(tree, projectName, projectConfiguration); logger.info( @@ -101,6 +117,8 @@ export default async function (tree: Tree) { module.exports = composePlugins(withNx(), (config) => { // Update the webpack config as needed here. // e.g. config.plugins.push(new MyPlugin()) + // For more information on webpack config and Nx see: + // https://nx.dev/packages/webpack/documents/webpack-config-setup return config; }); `