fix(webpack): config migrations should account for different configurations (#14672)
This commit is contained in:
parent
3cdaacf5d4
commit
cda00d9687
@ -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 }) => {
|
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => {
|
||||||
// Update the webpack config as needed here.
|
// Update the webpack config as needed here.
|
||||||
// e.g. config.plugins.push(new MyPlugin())
|
// 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;
|
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 }) => {
|
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => {
|
||||||
// Update the webpack config as needed here.
|
// Update the webpack config as needed here.
|
||||||
// e.g. config.plugins.push(new MyPlugin())
|
// 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;
|
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 }) => {
|
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => {
|
||||||
// Update the webpack config as needed here.
|
// Update the webpack config as needed here.
|
||||||
// e.g. config.plugins.push(new MyPlugin())
|
// 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;
|
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 }) => {
|
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => {
|
||||||
// Note: This was added by an Nx migration.
|
// Note: This was added by an Nx migration.
|
||||||
// You should consider inlining the logic into this file.
|
// 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);
|
return require('./webpack.something.old.ts')(config, context);
|
||||||
});
|
});
|
||||||
"
|
"
|
||||||
|
|||||||
@ -11,7 +11,9 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => {
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create webpack.config.js for React projects only', async () => {
|
||||||
addProjectConfiguration(tree, 'react1', {
|
addProjectConfiguration(tree, 'react1', {
|
||||||
root: 'apps/react1',
|
root: 'apps/react1',
|
||||||
targets: {
|
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');
|
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', {
|
addProjectConfiguration(tree, 'app4', {
|
||||||
root: 'apps/app4',
|
root: 'apps/app4',
|
||||||
targets: {
|
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');
|
tree.write('some/random/path/webpack.something.ts', 'some content');
|
||||||
|
|
||||||
addProjectConfiguration(tree, 'app5', {
|
addProjectConfiguration(tree, 'app5', {
|
||||||
@ -101,29 +124,7 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await webpackConfigSetup(tree);
|
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(
|
expect(
|
||||||
tree.read('some/random/path/webpack.something.ts', 'utf-8')
|
tree.read('some/random/path/webpack.something.ts', 'utf-8')
|
||||||
).toMatchInlineSnapshot(`"some content"`);
|
).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();
|
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(
|
expect(
|
||||||
readProjectConfiguration(tree, 'react1').targets.build.options
|
readProjectConfiguration(tree, 'react1').targets.build.options
|
||||||
.webpackConfig
|
.webpackConfig
|
||||||
@ -173,4 +227,71 @@ describe('15.6.3 migration (setup webpack.config file for React apps)', () => {
|
|||||||
.isolatedConfig
|
.isolatedConfig
|
||||||
).toBeTruthy();
|
).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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,23 +7,40 @@ import {
|
|||||||
} from '@nrwl/devkit';
|
} from '@nrwl/devkit';
|
||||||
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
|
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
|
||||||
import { basename } from 'path';
|
import { basename } from 'path';
|
||||||
|
import type { WebpackExecutorOptions } from '@nrwl/webpack';
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
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<string>();
|
||||||
|
forEachExecutorOptions<WebpackExecutorOptions>(
|
||||||
tree,
|
tree,
|
||||||
'@nrwl/webpack:webpack',
|
'@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 isolatedConfig is set, we don't need to do anything
|
||||||
// If it is NOT React, we don't need to do anything
|
// If it is NOT React, we don't need to do anything
|
||||||
if (
|
if (
|
||||||
options?.['isolatedConfig'] ||
|
!defaultWasUpdated &&
|
||||||
|
(defaultOptions?.['isolatedConfig'] ||
|
||||||
!(
|
!(
|
||||||
options?.['main']?.match(/main\.(t|j)sx$/) ||
|
defaultOptions?.['main']?.match(/main\.(t|j)sx$/) ||
|
||||||
options?.['webpackConfig'] === '@nrwl/react/plugins/webpack'
|
defaultOptions?.['webpackConfig'] === '@nrwl/react/plugins/webpack'
|
||||||
)
|
))
|
||||||
) {
|
) {
|
||||||
return;
|
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 set, update it with the new options
|
||||||
// If webpackConfig is not set, we need to create a new
|
// 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 }) => {
|
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => {
|
||||||
// Note: This was added by an Nx migration.
|
// Note: This was added by an Nx migration.
|
||||||
// You should consider inlining the logic into this file.
|
// 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);
|
return require('./${justTheFileName}')(config, context);
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
@ -62,11 +81,9 @@ export default async function (tree: Tree) {
|
|||||||
|
|
||||||
options['isolatedConfig'] = true;
|
options['isolatedConfig'] = true;
|
||||||
|
|
||||||
const projectConfiguration = readProjectConfiguration(
|
projectConfiguration.targets[targetName][
|
||||||
tree,
|
configurationName ?? 'options'
|
||||||
projectName
|
] = options;
|
||||||
);
|
|
||||||
projectConfiguration.targets[targetName].options = options;
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfiguration);
|
updateProjectConfiguration(tree, projectName, projectConfiguration);
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
@ -86,7 +103,7 @@ export default async function (tree: Tree) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
options = {};
|
options = {} as WebpackExecutorOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
options[
|
options[
|
||||||
@ -104,6 +121,8 @@ export default async function (tree: Tree) {
|
|||||||
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => {
|
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => {
|
||||||
// Update the webpack config as needed here.
|
// Update the webpack config as needed here.
|
||||||
// e.g. config.plugins.push(new MyPlugin())
|
// 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;
|
return config;
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
|||||||
@ -8,6 +8,8 @@ exports[`15.6.3 migration (setup webpack.config file) should create webpack.conf
|
|||||||
module.exports = composePlugins(withNx(), (config) => {
|
module.exports = composePlugins(withNx(), (config) => {
|
||||||
// Update the webpack config as needed here.
|
// Update the webpack config as needed here.
|
||||||
// e.g. config.plugins.push(new MyPlugin())
|
// 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;
|
return config;
|
||||||
});
|
});
|
||||||
"
|
"
|
||||||
@ -21,6 +23,8 @@ exports[`15.6.3 migration (setup webpack.config file) should create webpack.conf
|
|||||||
module.exports = composePlugins(withNx(), (config) => {
|
module.exports = composePlugins(withNx(), (config) => {
|
||||||
// Update the webpack config as needed here.
|
// Update the webpack config as needed here.
|
||||||
// e.g. config.plugins.push(new MyPlugin())
|
// 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;
|
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 }) => {
|
module.exports = composePlugins(withNx(), (config, { options, context }) => {
|
||||||
// Note: This was added by an Nx migration.
|
// Note: This was added by an Nx migration.
|
||||||
// You should consider inlining the logic into this file.
|
// 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);
|
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 }) => {
|
module.exports = composePlugins(withNx(), (config, { options, context }) => {
|
||||||
// Note: This was added by an Nx migration.
|
// Note: This was added by an Nx migration.
|
||||||
// You should consider inlining the logic into this file.
|
// 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);
|
return require('./webpack.something.old.ts')(config, context);
|
||||||
});
|
});
|
||||||
"
|
"
|
||||||
|
|||||||
@ -11,7 +11,78 @@ describe('15.6.3 migration (setup webpack.config file)', () => {
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
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', {
|
addProjectConfiguration(tree, 'app1', {
|
||||||
root: 'apps/app1',
|
root: 'apps/app1',
|
||||||
targets: {
|
targets: {
|
||||||
@ -56,69 +127,10 @@ describe('15.6.3 migration (setup webpack.config file)', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
tree.write('some/random/path/webpack.something.ts', 'some content');
|
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);
|
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(
|
expect(
|
||||||
readProjectConfiguration(tree, 'app1').targets.build.options.webpackConfig
|
readProjectConfiguration(tree, 'app1').targets.build.options.webpackConfig
|
||||||
).toBe('apps/app1/webpack.config.js');
|
).toBe('apps/app1/webpack.config.js');
|
||||||
@ -157,12 +169,119 @@ describe('15.6.3 migration (setup webpack.config file)', () => {
|
|||||||
).toBeTruthy();
|
).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();
|
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/app6/webpack.config.js')).toBeFalsy();
|
||||||
expect(tree.exists('apps/app7/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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -10,6 +10,9 @@ import { WebpackExecutorOptions } from '../../executors/webpack/schema';
|
|||||||
import { basename } from 'path';
|
import { basename } from 'path';
|
||||||
|
|
||||||
export default async function (tree: Tree) {
|
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<string>();
|
||||||
forEachExecutorOptions<WebpackExecutorOptions>(
|
forEachExecutorOptions<WebpackExecutorOptions>(
|
||||||
tree,
|
tree,
|
||||||
'@nrwl/webpack:webpack',
|
'@nrwl/webpack:webpack',
|
||||||
@ -17,17 +20,30 @@ export default async function (tree: Tree) {
|
|||||||
options: WebpackExecutorOptions,
|
options: WebpackExecutorOptions,
|
||||||
projectName,
|
projectName,
|
||||||
targetName,
|
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 isolatedConfig is set, we don't need to do anything
|
||||||
// If project is React, we don't need to do anything
|
// If project is React, we don't need to do anything
|
||||||
if (
|
if (
|
||||||
options?.isolatedConfig ||
|
!defaultWasUpdated &&
|
||||||
options?.main?.match(/main\.(t|j)sx$/) ||
|
(defaultOptions?.isolatedConfig ||
|
||||||
options?.webpackConfig === '@nrwl/react/plugins/webpack'
|
defaultOptions?.main?.match(/main\.(t|j)sx$/) ||
|
||||||
|
defaultOptions?.webpackConfig === '@nrwl/react/plugins/webpack')
|
||||||
) {
|
) {
|
||||||
return;
|
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 set, update it with the new options
|
||||||
// If webpackConfig is not set, we need to create a new
|
// 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 }) => {
|
module.exports = composePlugins(withNx(), (config, { options, context }) => {
|
||||||
// Note: This was added by an Nx migration.
|
// Note: This was added by an Nx migration.
|
||||||
// You should consider inlining the logic into this file.
|
// 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);
|
return require('./${justTheFileName}')(config, context);
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
@ -62,11 +80,9 @@ export default async function (tree: Tree) {
|
|||||||
|
|
||||||
options.isolatedConfig = true;
|
options.isolatedConfig = true;
|
||||||
|
|
||||||
const projectConfiguration = readProjectConfiguration(
|
projectConfiguration.targets[targetName][
|
||||||
tree,
|
configurationName ?? 'options'
|
||||||
projectName
|
] = options;
|
||||||
);
|
|
||||||
projectConfiguration.targets[targetName].options = options;
|
|
||||||
updateProjectConfiguration(tree, projectName, projectConfiguration);
|
updateProjectConfiguration(tree, projectName, projectConfiguration);
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
@ -101,6 +117,8 @@ export default async function (tree: Tree) {
|
|||||||
module.exports = composePlugins(withNx(), (config) => {
|
module.exports = composePlugins(withNx(), (config) => {
|
||||||
// Update the webpack config as needed here.
|
// Update the webpack config as needed here.
|
||||||
// e.g. config.plugins.push(new MyPlugin())
|
// 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;
|
return config;
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user