Skip to content

Commit

Permalink
fix(angular): generate @nx/angular in devDependencies and move to dep…
Browse files Browse the repository at this point in the history
…endencies when using runtime helpers (#27405)

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- 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 -->

New workspaces are generated with `@nx/angular` as a production
dependency even though the generated code does not use any runtime
helper from it.

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

New workspaces should be generated with `@nx/angular` as a development
dependency. When generating a new MF host or dynamic MF application
(host or remote), the `@nx/angular` package should be moved to the
production dependencies because the generated code uses some runtime
helpers from it.

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

Fixes #27333

(cherry picked from commit 1ae3c2d)
  • Loading branch information
leosvelperez authored and FrozenPandaz committed Aug 19, 2024
1 parent 022754c commit c009c74
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/angular/src/generators/setup-mf/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './change-build-target';
export * from './fix-bootstrap';
export * from './generate-config';
export * from './get-remotes-with-ports';
export * from './move-angular-plugin-to-dependencies';
export * from './normalize-options';
export * from './update-tsconfig';
export * from './setup-host-if-dynamic';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { readJson, writeJson, type Tree } from '@nx/devkit';

export function moveAngularPluginToDependencies(tree: Tree): void {
const packageJson = readJson(tree, 'package.json');
if (packageJson.dependencies?.['@nx/angular']) {
return;
}

packageJson.dependencies ??= {};
packageJson.dependencies['@nx/angular'] =
packageJson.devDependencies['@nx/angular'];
delete packageJson.devDependencies['@nx/angular'];

writeJson(tree, 'package.json', packageJson);
}
41 changes: 39 additions & 2 deletions packages/angular/src/generators/setup-mf/setup-mf.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import 'nx/src/internal-testing-utils/mock-project-graph';
import {
readJson,
readProjectConfiguration,
Tree,
updateJson,
type Tree,
} from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { E2eTestRunner } from '../../utils/test-runners';
import { nxVersion } from '../../utils/versions';
import { generateTestApplication } from '../utils/testing';
import { setupMf } from './setup-mf';
import { E2eTestRunner } from '../../utils/test-runners';

describe('Init MF', () => {
let tree: Tree;
Expand Down Expand Up @@ -760,6 +761,42 @@ describe('Init MF', () => {
`);
});

it('should move the @nx/angular plugin to dependencies when --mfType=host', async () => {
updateJson(tree, 'package.json', (json) => ({
...json,
devDependencies: {
...json.devDependencies,
'@nx/angular': nxVersion,
},
}));

await setupMf(tree, { appName: 'app1', mfType: 'host' });

const { devDependencies, dependencies } = readJson(tree, 'package.json');
expect(devDependencies['@nx/angular']).toBeUndefined();
expect(dependencies['@nx/angular']).toBe(nxVersion);
});

it('should move the @nx/angular plugin to dependencies when --federationType=dynamic', async () => {
updateJson(tree, 'package.json', (json) => ({
...json,
devDependencies: {
...json.devDependencies,
'@nx/angular': nxVersion,
},
}));

await setupMf(tree, {
appName: 'app1',
mfType: 'remote',
federationType: 'dynamic',
});

const { devDependencies, dependencies } = readJson(tree, 'package.json');
expect(devDependencies['@nx/angular']).toBeUndefined();
expect(dependencies['@nx/angular']).toBe(nxVersion);
});

describe('angular compat support', () => {
beforeEach(() => {
updateJson(tree, 'package.json', (json) => ({
Expand Down
25 changes: 17 additions & 8 deletions packages/angular/src/generators/setup-mf/setup-mf.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { Tree } from '@nx/devkit';
import {
addDependenciesToPackageJson,
formatFiles,
readProjectConfiguration,
type Tree,
} from '@nx/devkit';
import type { Schema } from './schema';

import {
moduleFederationEnhancedVersion,
nxVersion,
} from '../../utils/versions';
import {
addCypressOnErrorWorkaround,
addRemoteEntry,
Expand All @@ -14,18 +16,16 @@ import {
fixBootstrap,
generateWebpackConfig,
getRemotesWithPorts,
moveAngularPluginToDependencies,
normalizeOptions,
removeDeadCodeFromRemote,
setupHostIfDynamic,
setupTspathForRemote,
setupServeTarget,
setupTspathForRemote,
updateHostAppRoutes,
updateTsConfig,
} from './lib';
import {
moduleFederationEnhancedVersion,
nxVersion,
} from '../../utils/versions';
import type { Schema } from './schema';

export async function setupMf(tree: Tree, rawOptions: Schema) {
const options = normalizeOptions(tree, rawOptions);
Expand Down Expand Up @@ -88,6 +88,15 @@ export async function setupMf(tree: Tree, rawOptions: Schema) {

fixBootstrap(tree, projectConfig.root, options);

if (options.mfType === 'host' || options.federationType === 'dynamic') {
/**
* Host applications and dynamic federation applications generate runtime
* code that depends on the @nx/angular plugin. Ensure that the plugin is
* in the production dependencies.
*/
moveAngularPluginToDependencies(tree);
}

if (!options.skipE2E) {
addCypressOnErrorWorkaround(tree, options);
}
Expand Down
3 changes: 2 additions & 1 deletion packages/workspace/src/generators/new/generate-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ function getPresetDependencies({
case Preset.AngularMonorepo:
case Preset.AngularStandalone:
return {
dependencies: { '@nx/angular': nxVersion },
dependencies: {},
dev: {
'@angular-devkit/core': angularCliVersion,
'@nx/angular': nxVersion,
typescript: typescriptVersion,
},
};
Expand Down
2 changes: 1 addition & 1 deletion packages/workspace/src/generators/new/new.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ describe('new', () => {
tree,
'my-workspace/package.json'
);
expect(dependencies).toStrictEqual({ '@nx/angular': nxVersion });
expect(devDependencies).toStrictEqual({
'@angular-devkit/core': angularCliVersion,
'@nx/angular': nxVersion,
'@nx/workspace': nxVersion,
nx: nxVersion,
typescript: typescriptVersion,
Expand Down

0 comments on commit c009c74

Please sign in to comment.