Skip to content

Commit

Permalink
fix(module-federation): ensure target defaults are set correctly #27448
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 committed Aug 16, 2024
1 parent 69c989e commit 196e426
Show file tree
Hide file tree
Showing 8 changed files with 454 additions and 0 deletions.
6 changes: 6 additions & 0 deletions packages/angular/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,12 @@
},
"description": "Update the @angular/cli package version to ~18.2.0.",
"factory": "./src/migrations/update-19-6-0/update-angular-cli"
},
"update-19-6-1-ensure-module-federation-target-defaults": {
"cli": "nx",
"version": "19.6.1-beta.0",
"description": "Ensure Target Defaults are set correctly for Module Federation.",
"factory": "./src/migrations/update-19-6-1/ensure-depends-on-for-mf"
}
},
"packageJsonUpdates": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export function addMfEnvToTargetDefaultInputs(tree: Tree) {
'production',
'^production',
];
nxJson.targetDefaults[webpackExecutor].dependsOn ??= ['^build'];

let mfEnvVarExists = false;
for (const input of nxJson.targetDefaults[webpackExecutor].inputs) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import {
addProjectConfiguration,
readNxJson,
updateNxJson,
type Tree,
} from '@nx/devkit';
import ensureDependsOnForMf from './ensure-depends-on-for-mf';

describe('ensure-depends-on-for-mf', () => {
it('should ensure targetDefault is added correctly if not exists', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const nxJson = readNxJson(tree);
nxJson.targetDefaults ??= {};
nxJson.targetDefaults['@nx/angular:webpack-browser'] = {
inputs: ['production', '^production'],
};
updateNxJson(tree, nxJson);
addProject(tree);

// ACT
await ensureDependsOnForMf(tree);

// ASSERT
expect(readNxJson(tree).targetDefaults['@nx/angular:webpack-browser'])
.toMatchInlineSnapshot(`
{
"dependsOn": [
"^build",
],
"inputs": [
"production",
"^production",
{
"env": "NX_MF_DEV_REMOTES",
},
],
}
`);
});

it('should ensure targetDefault is added correctly if there are no targetDefaults', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const nxJson = readNxJson(tree);
nxJson.targetDefaults = {};
updateNxJson(tree, nxJson);
addProject(tree);

// ACT
await ensureDependsOnForMf(tree);

// ASSERT
expect(readNxJson(tree).targetDefaults['@nx/angular:webpack-browser'])
.toMatchInlineSnapshot(`
{
"cache": true,
"dependsOn": [
"^build",
],
"inputs": [
"production",
"^production",
{
"env": "NX_MF_DEV_REMOTES",
},
],
}
`);
});

it('should ensure targetDefault is updated correctly if missing ^build', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const nxJson = readNxJson(tree);
nxJson.targetDefaults ??= {};
nxJson.targetDefaults['@nx/angular:webpack-browser'] = {
inputs: ['production', '^production'],
dependsOn: ['some-task'],
};
updateNxJson(tree, nxJson);
addProject(tree);

// ACT
await ensureDependsOnForMf(tree);

// ASSERT
expect(readNxJson(tree).targetDefaults['@nx/angular:webpack-browser'])
.toMatchInlineSnapshot(`
{
"dependsOn": [
"some-task",
"^build",
],
"inputs": [
"production",
"^production",
{
"env": "NX_MF_DEV_REMOTES",
},
],
}
`);
});

it('should do nothing if targetDefault is set up correctly', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const nxJson = readNxJson(tree);
nxJson.targetDefaults ??= {};
nxJson.targetDefaults['@nx/angular:webpack-browser'] = {
inputs: ['production', '^production', { env: 'NX_MF_DEV_REMOTES' }],
dependsOn: ['^build'],
};
updateNxJson(tree, nxJson);
addProject(tree);

// ACT
await ensureDependsOnForMf(tree);

// ASSERT
expect(readNxJson(tree).targetDefaults['@nx/angular:webpack-browser'])
.toMatchInlineSnapshot(`
{
"dependsOn": [
"^build",
],
"inputs": [
"production",
"^production",
{
"env": "NX_MF_DEV_REMOTES",
},
],
}
`);
});
});

function addProject(tree: Tree) {
tree.write('app/webpack.config.ts', `withModuleFederation`);
addProjectConfiguration(tree, 'app', {
name: 'app',
root: 'app',
projectType: 'application',
targets: {
build: {
executor: '@nx/angular:webpack-browser',
options: { webpackConfig: 'app/webpack.config.ts' },
},
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { formatFiles, readNxJson, type Tree, updateNxJson } from '@nx/devkit';
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
import type { WebpackExecutorOptions } from '@nx/webpack';

export default async function (tree: Tree) {
let usesModuleFederation = false;
forEachExecutorOptions<WebpackExecutorOptions>(
tree,
'@nx/angular:webpack-browser',
(options, projectName, targetName) => {
const webpackConfig: string = options.webpackConfig;
if (!webpackConfig) {
return;
}

const webpackContents = tree.read(webpackConfig, 'utf-8');
if (
['withModuleFederation', 'withModuleFederationForSSR'].some((p) =>
webpackContents.includes(p)
)
) {
usesModuleFederation = true;
}
}
);

if (!usesModuleFederation) {
return;
}

const nxJson = readNxJson(tree);
const nxMFDevRemotesEnvVar = 'NX_MF_DEV_REMOTES';
if (
!nxJson.targetDefaults ||
!nxJson.targetDefaults?.['@nx/angular:webpack-browser']
) {
nxJson.targetDefaults ??= {};
nxJson.targetDefaults['@nx/angular:webpack-browser'] = {
cache: true,
inputs: ['production', '^production', { env: nxMFDevRemotesEnvVar }],
dependsOn: ['^build'],
};
} else {
nxJson.targetDefaults['@nx/angular:webpack-browser'].dependsOn ??= [];
if (
!nxJson.targetDefaults['@nx/angular:webpack-browser'].dependsOn.includes(
'^build'
)
) {
nxJson.targetDefaults['@nx/angular:webpack-browser'].dependsOn.push(
'^build'
);
}

nxJson.targetDefaults['@nx/angular:webpack-browser'].inputs ??= [];
if (
!nxJson.targetDefaults['@nx/angular:webpack-browser'].inputs.find((i) =>
typeof i === 'string' ? false : i['env'] === nxMFDevRemotesEnvVar
)
) {
nxJson.targetDefaults['@nx/angular:webpack-browser'].inputs.push({
env: nxMFDevRemotesEnvVar,
});
}
}
updateNxJson(tree, nxJson);
await formatFiles(tree);
}
6 changes: 6 additions & 0 deletions packages/react/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@
"version": "19.6.0-beta.4",
"description": "Update the server file for Module Federation SSR port value to be the same as the 'serve' target port value.",
"factory": "./src/migrations/update-19-6-0/update-ssr-server-port"
},
"update-19-6-1-ensure-module-federation-target-defaults": {
"cli": "nx",
"version": "19.6.1-beta.0",
"description": "Ensure Target Defaults are set correctly for Module Federation.",
"factory": "./src/migrations/update-19-6-1/ensure-depends-on-for-mf"
}
},
"packageJsonUpdates": {
Expand Down
Loading

0 comments on commit 196e426

Please sign in to comment.