fix(webpack): add migration for proxy config (#27621)

Webpack-dev-server v5 changed the proxy config to only accept arrays.
This PR adds a migration for JSON proxy config files to automatically do
the conversion for users. If it's not a JSON format, then we log a
warning and point them to the v5 migration page.

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
This commit is contained in:
Jack Hsu 2024-08-23 14:17:01 -04:00 committed by GitHub
parent add4183d0a
commit f9bb3082b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 138 additions and 0 deletions

View File

@ -11,6 +11,12 @@
"version": "17.2.1-beta.0",
"description": "Add webpack.config.js file when webpackConfig is not defined",
"implementation": "./src/migrations/update-17-2-1/webpack-config-setup"
},
"update-19-6-3-proxy-config": {
"cli": "nx",
"version": "19.6.3-beta.0",
"description": "Migrate proxy config files to match new format from webpack-dev-server v5.",
"implementation": "./src/migrations/update-19-6-3/proxy-config"
}
},
"packageJsonUpdates": {

View File

@ -0,0 +1,68 @@
import { readJson, writeJson, addProjectConfiguration, Tree } from '@nx/devkit';
import update from './proxy-config';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
describe('Migration: update proxy config format', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should convert an object to an array', async () => {
addProjectConfiguration(tree, 'app1', {
root: 'apps/app1',
targets: {
serve: {
executor: '@nx/webpack:dev-server',
options: {
proxyConfig: 'apps/app1/proxy.conf.json',
},
configurations: {
production: {
proxyConfig: 'apps/app1/proxy.conf.prod.json',
},
},
},
},
});
writeJson(tree, 'apps/app1/proxy.conf.json', {
'/api': {
target: 'http://localhost:3000',
},
});
writeJson(tree, 'apps/app1/proxy.conf.prod.json', {
'/api': {
target: 'https://example.com',
},
});
addProjectConfiguration(tree, 'app2', {
root: 'apps/app2',
targets: {
serve: {
executor: '@nx/react:module-federation-dev-server',
options: {
proxyConfig: 'apps/app2/proxy.conf.json',
},
},
},
});
writeJson(tree, 'apps/app2/proxy.conf.json', {
'/api': {
target: 'http://localhost:3000',
},
});
await update(tree);
expect(readJson(tree, 'apps/app1/proxy.conf.json')).toEqual([
{ context: ['/api'], target: 'http://localhost:3000' },
]);
expect(readJson(tree, 'apps/app1/proxy.conf.prod.json')).toEqual([
{ context: ['/api'], target: 'https://example.com' },
]);
expect(readJson(tree, 'apps/app2/proxy.conf.json')).toEqual([
{ context: ['/api'], target: 'http://localhost:3000' },
]);
});
});

View File

@ -0,0 +1,64 @@
import { logger, Tree, updateJson } from '@nx/devkit';
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
import { WebDevServerOptions } from '../../executors/dev-server/schema';
export default async function update(tree: Tree): Promise<void> {
const unmigratedConfigs: string[] = [];
const migrate = (options: WebDevServerOptions) => {
if (!options.proxyConfig) return;
if (options.proxyConfig.endsWith('.json')) {
updateJson(tree, options.proxyConfig, (json) => {
if (Array.isArray(json)) return json;
if (typeof json === 'object') {
return Object.keys(json).map((context) => ({
context: [context],
...json[context],
}));
}
return json;
});
} else {
// For non-JSON files, it's not possible to automatically update the proxy config
// since its content can vary greatly.
unmigratedConfigs.push(options.proxyConfig);
}
};
forEachExecutorOptions<WebDevServerOptions>(
tree,
'@nx/webpack:dev-server',
migrate
);
// React dev-server calls Webpack dev-server.
forEachExecutorOptions<WebDevServerOptions>(
tree,
'@nx/react:module-federation-dev-server',
migrate
);
if (unmigratedConfigs.length > 0) {
logger.warn(`Some proxy config files need to be updated manually.
${unmigratedConfigs.join('\n ')}
Webpack-dev-server v5 changed the proxy config schema to accept only an array.
For example, if you had the following:
"proxy": {
"/api": {
"target": "http://localhost:3000"
}
}
It needs to be updated to:
"proxy": [{
"context": ["/api"],
"target": "http://localhost:3000"
}]
More information: https://github.com/webpack/webpack-dev-server/blob/master/migration-v5.md
`);
}
}