diff --git a/packages/react/src/generators/host/host.spec.ts b/packages/react/src/generators/host/host.spec.ts index 73006a890e2df..ffeda099d94d9 100644 --- a/packages/react/src/generators/host/host.spec.ts +++ b/packages/react/src/generators/host/host.spec.ts @@ -71,4 +71,26 @@ describe('hostGenerator', () => { include: ['src/remotes.d.ts', 'src/main.server.tsx', 'server.ts'], }); }); + + it('should generate a host and remotes in a directory correctly when using --projectNameAndRootFormat=as-provided', async () => { + const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + + await hostGenerator(tree, { + name: 'hostApp', + directory: 'foo/hostApp', + remotes: ['remote1', 'remote2', 'remote3'], + projectNameAndRootFormat: 'as-provided', + e2eTestRunner: 'none', + linter: Linter.None, + style: 'css', + unitTestRunner: 'none', + }); + + expect(tree.exists('foo/remote1/project.json')).toBeTruthy(); + expect(tree.exists('foo/remote2/project.json')).toBeTruthy(); + expect(tree.exists('foo/remote3/project.json')).toBeTruthy(); + expect( + tree.read('foo/host-app/module-federation.config.js', 'utf-8') + ).toContain(`'remote1', 'remote2', 'remote3'`); + }); }); diff --git a/packages/react/src/generators/host/host.ts b/packages/react/src/generators/host/host.ts index 1b2d89564a3a5..10f02db8035dd 100644 --- a/packages/react/src/generators/host/host.ts +++ b/packages/react/src/generators/host/host.ts @@ -7,18 +7,19 @@ import { Tree, updateProjectConfiguration, } from '@nx/devkit'; - +import { updateModuleFederationProject } from '../../rules/update-module-federation-project'; import applicationGenerator from '../application/application'; import { normalizeOptions } from '../application/lib/normalize-options'; -import { updateModuleFederationProject } from '../../rules/update-module-federation-project'; -import { addModuleFederationFiles } from './lib/add-module-federation-files'; -import { updateModuleFederationE2eProject } from './lib/update-module-federation-e2e-project'; - -import { Schema } from './schema'; import remoteGenerator from '../remote/remote'; - import setupSsrGenerator from '../setup-ssr/setup-ssr'; +import { addModuleFederationFiles } from './lib/add-module-federation-files'; +import { + normalizeRemoteDirectory, + normalizeRemoteName, +} from './lib/normalize-remote'; import { setupSsrForHost } from './lib/setup-ssr-for-host'; +import { updateModuleFederationE2eProject } from './lib/update-module-federation-e2e-project'; +import { Schema } from './schema'; export async function hostGenerator(host: Tree, schema: Schema) { return hostGeneratorInternal(host, { @@ -50,10 +51,12 @@ export async function hostGeneratorInternal(host: Tree, schema: Schema) { if (schema.remotes) { let remotePort = options.devServerPort + 1; for (const remote of schema.remotes) { - remotesWithPorts.push({ name: remote, port: remotePort }); + const remoteName = await normalizeRemoteName(host, remote, options); + remotesWithPorts.push({ name: remoteName, port: remotePort }); + await remoteGenerator(host, { name: remote, - directory: options.directory, + directory: normalizeRemoteDirectory(remote, options), style: options.style, unitTestRunner: options.unitTestRunner, e2eTestRunner: options.e2eTestRunner, @@ -61,6 +64,7 @@ export async function hostGeneratorInternal(host: Tree, schema: Schema) { devServerPort: remotePort, ssr: options.ssr, skipFormat: true, + projectNameAndRootFormat: options.projectNameAndRootFormat, }); remotePort++; } diff --git a/packages/react/src/generators/host/lib/add-module-federation-files.ts b/packages/react/src/generators/host/lib/add-module-federation-files.ts index 5b9e2b54c2d52..0e047ca17a1b7 100644 --- a/packages/react/src/generators/host/lib/add-module-federation-files.ts +++ b/packages/react/src/generators/host/lib/add-module-federation-files.ts @@ -1,7 +1,6 @@ import { NormalizedSchema } from '../schema'; import { generateFiles, names } from '@nx/devkit'; import { join } from 'path'; -import { normalizeProjectName } from '../../application/lib/normalize-options'; export function addModuleFederationFiles( host, @@ -13,9 +12,8 @@ export function addModuleFederationFiles( ...options, tmpl: '', remotes: defaultRemoteManifest.map(({ name, port }) => { - const remote = normalizeProjectName({ ...options, name }); return { - ...names(remote), + ...names(name), port, }; }), diff --git a/packages/react/src/generators/host/lib/normalize-remote.ts b/packages/react/src/generators/host/lib/normalize-remote.ts new file mode 100644 index 0000000000000..45085527d3fd4 --- /dev/null +++ b/packages/react/src/generators/host/lib/normalize-remote.ts @@ -0,0 +1,38 @@ +import { Tree, joinPathFragments } from '@nx/devkit'; +import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils'; +import { NormalizedSchema } from '../schema'; + +export async function normalizeRemoteName( + tree: Tree, + remote: string, + options: NormalizedSchema +) { + const { projectName: remoteName } = await determineProjectNameAndRootOptions( + tree, + { + name: remote, + projectType: 'application', + directory: options.directory, + projectNameAndRootFormat: options.projectNameAndRootFormat, + callingGenerator: '@nx/react:host', + } + ); + + return remoteName; +} + +export function normalizeRemoteDirectory( + remote: string, + options: NormalizedSchema +) { + if (options.projectNameAndRootFormat === 'derived' || !options.directory) { + return options.directory; + } + + /** + * With the `as-provided` format, the provided directory would be the root + * of the host application. Append the remote name to the host parent + * directory to get the remote directory. + */ + return joinPathFragments(options.directory, '..', remote); +} diff --git a/packages/react/src/generators/host/lib/setup-ssr-for-host.ts b/packages/react/src/generators/host/lib/setup-ssr-for-host.ts index 536d191c4ce16..4c532558764b5 100644 --- a/packages/react/src/generators/host/lib/setup-ssr-for-host.ts +++ b/packages/react/src/generators/host/lib/setup-ssr-for-host.ts @@ -11,7 +11,6 @@ import { import type { Schema } from '../schema'; import { moduleFederationNodeVersion } from '../../../utils/versions'; -import { normalizeProjectName } from '../../application/lib/normalize-options'; export async function setupSsrForHost( tree: Tree, @@ -31,9 +30,8 @@ export async function setupSsrForHost( { ...options, remotes: defaultRemoteManifest.map(({ name, port }) => { - const remote = normalizeProjectName({ ...options, name }); return { - ...names(remote), + ...names(name), port, }; }),