diff --git a/packages/angular/src/utils/mf/utils.ts b/packages/angular/src/utils/mf/utils.ts index dae5ddd800375..a1c4234ca37e7 100644 --- a/packages/angular/src/utils/mf/utils.ts +++ b/packages/angular/src/utils/mf/utils.ts @@ -15,6 +15,7 @@ import { ProjectGraph, readCachedProjectGraph, } from '@nx/devkit'; +import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph'; export function applyDefaultEagerPackages( sharedConfig: Record @@ -42,10 +43,35 @@ export const DEFAULT_ANGULAR_PACKAGES_TO_SHARE = [ '@angular/common', ]; +export function getFunctionDeterminateRemoteUrl(isServer: boolean = false) { + const target = 'serve'; + const remoteEntry = isServer ? 'server/remoteEntry.js' : 'remoteEntry.mjs'; + + return function (remote: string) { + const remoteConfiguration = readCachedProjectConfiguration(remote); + const serveTarget = remoteConfiguration?.targets?.[target]; + + if (!serveTarget) { + throw new Error( + `Cannot automatically determine URL of remote (${remote}). Looked for property "host" in the project's "serve" target.\n + You can also use the tuple syntax in your webpack config to configure your remotes. e.g. \`remotes: [['remote1', 'http://localhost:4201']]\`` + ); + } + + const host = serveTarget.options?.host ?? 'http://localhost'; + const port = serveTarget.options?.port ?? 4201; + return `${ + host.endsWith('/') ? host.slice(0, -1) : host + }:${port}/${remoteEntry}`; + }; +} + export async function getModuleFederationConfig( mfConfig: ModuleFederationConfig, - determineRemoteUrl: (remote: string) => string, - options: { isServer: boolean } = { isServer: false } + options: { + isServer: boolean; + determineRemoteUrl?: (remote: string) => string; + } = { isServer: false } ) { let projectGraph: ProjectGraph; try { @@ -107,11 +133,14 @@ export async function getModuleFederationConfig( mfConfig.additionalShared, projectGraph ); + const determineRemoteUrlFn = + options.determineRemoteUrl || + getFunctionDeterminateRemoteUrl(options.isServer); const mapRemotesFunction = options.isServer ? mapRemotesForSSR : mapRemotes; const mappedRemotes = !mfConfig.remotes || mfConfig.remotes.length === 0 ? {} - : mapRemotesFunction(mfConfig.remotes, 'mjs', determineRemoteUrl); + : mapRemotesFunction(mfConfig.remotes, 'mjs', determineRemoteUrlFn); return { sharedLibraries, sharedDependencies, mappedRemotes }; } diff --git a/packages/angular/src/utils/mf/with-module-federation-ssr.ts b/packages/angular/src/utils/mf/with-module-federation-ssr.ts index 3cc75f324222f..81d8ced86c65d 100644 --- a/packages/angular/src/utils/mf/with-module-federation-ssr.ts +++ b/packages/angular/src/utils/mf/with-module-federation-ssr.ts @@ -1,28 +1,11 @@ -import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph'; import { ModuleFederationConfig } from '@nx/devkit/src/utils/module-federation'; import { getModuleFederationConfig } from './utils'; -function determineRemoteUrl(remote: string) { - const remoteProjectConfiguration = readCachedProjectConfiguration(remote); - let publicHost = ''; - try { - publicHost = remoteProjectConfiguration.targets.serve.options.publicHost; - } catch (error) { - throw new Error( - `Cannot automatically determine URL of remote (${remote}). Looked for property "publicHost" in the project's "serve" target.\n - You can also use the tuple syntax in your webpack config to configure your remotes. e.g. \`remotes: [['remote1', 'http://localhost:4201']]\`` - ); - } - return `${ - publicHost.endsWith('/') ? publicHost.slice(0, -1) : publicHost - }/server/remoteEntry.js`; -} - export async function withModuleFederationForSSR( options: ModuleFederationConfig ) { const { sharedLibraries, sharedDependencies, mappedRemotes } = - await getModuleFederationConfig(options, determineRemoteUrl, { + await getModuleFederationConfig(options, { isServer: true, }); diff --git a/packages/angular/src/utils/mf/with-module-federation.ts b/packages/angular/src/utils/mf/with-module-federation.ts index f9a61595d9018..71f615118add7 100644 --- a/packages/angular/src/utils/mf/with-module-federation.ts +++ b/packages/angular/src/utils/mf/with-module-federation.ts @@ -1,27 +1,10 @@ import { ModuleFederationConfig } from '@nx/devkit/src/utils/module-federation'; import { getModuleFederationConfig } from './utils'; -import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph'; import ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); -function determineRemoteUrl(remote: string) { - const remoteProjectConfiguration = readCachedProjectConfiguration(remote); - let publicHost = ''; - try { - publicHost = remoteProjectConfiguration.targets.serve.options.publicHost; - } catch (error) { - throw new Error( - `Cannot automatically determine URL of remote (${remote}). Looked for property "publicHost" in the project's "serve" target.\n - You can also use the tuple syntax in your webpack config to configure your remotes. e.g. \`remotes: [['remote1', 'http://localhost:4201']]\`` - ); - } - return `${ - publicHost.endsWith('/') ? publicHost.slice(0, -1) : publicHost - }/remoteEntry.mjs`; -} - export async function withModuleFederation(options: ModuleFederationConfig) { const { sharedLibraries, sharedDependencies, mappedRemotes } = - await getModuleFederationConfig(options, determineRemoteUrl); + await getModuleFederationConfig(options); return (config) => ({ ...(config ?? {}), diff --git a/packages/react/src/module-federation/utils.ts b/packages/react/src/module-federation/utils.ts index e010b54e5805e..ba67d6684ae9f 100644 --- a/packages/react/src/module-federation/utils.ts +++ b/packages/react/src/module-federation/utils.ts @@ -14,11 +14,37 @@ import { ProjectGraph, readCachedProjectGraph, } from '@nx/devkit'; +import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph'; + +export function getFunctionDeterminateRemoteUrl(isServer: boolean = false) { + const target = isServer ? 'serve-server' : 'serve'; + const remoteEntry = isServer ? 'server/remoteEntry.js' : 'remoteEntry.js'; + + return function (remote: string) { + const remoteConfiguration = readCachedProjectConfiguration(remote); + const serveTarget = remoteConfiguration?.targets?.[target]; + + if (!serveTarget) { + throw new Error( + `Cannot automatically determine URL of remote (${remote}). Looked for property "host" in the project's "${serveTarget}" target.\n + You can also use the tuple syntax in your webpack config to configure your remotes. e.g. \`remotes: [['remote1', 'http://localhost:4201']]\`` + ); + } + + const host = serveTarget.options?.host ?? 'http://localhost'; + const port = serveTarget.options?.port ?? 4201; + return `${ + host.endsWith('/') ? host.slice(0, -1) : host + }:${port}/${remoteEntry}`; + }; +} export async function getModuleFederationConfig( mfConfig: ModuleFederationConfig, - determineRemoteUrl: (remote: string) => string, - options: { isServer: boolean } = { isServer: false } + options: { + isServer: boolean; + determineRemoteUrl?: (remote: string) => string; + } = { isServer: false } ) { let projectGraph: ProjectGraph; try { @@ -68,10 +94,13 @@ export async function getModuleFederationConfig( ); const mapRemotesFunction = options.isServer ? mapRemotesForSSR : mapRemotes; + const determineRemoteUrlFn = + options.determineRemoteUrl || + getFunctionDeterminateRemoteUrl(options.isServer); const mappedRemotes = !mfConfig.remotes || mfConfig.remotes.length === 0 ? {} - : mapRemotesFunction(mfConfig.remotes, 'js', determineRemoteUrl); + : mapRemotesFunction(mfConfig.remotes, 'js', determineRemoteUrlFn); return { sharedLibraries, sharedDependencies, mappedRemotes }; } diff --git a/packages/react/src/module-federation/with-module-federation-ssr.ts b/packages/react/src/module-federation/with-module-federation-ssr.ts index e5d96fd122000..3701d3a84750d 100644 --- a/packages/react/src/module-federation/with-module-federation-ssr.ts +++ b/packages/react/src/module-federation/with-module-federation-ssr.ts @@ -1,32 +1,13 @@ import { ModuleFederationConfig } from '@nx/devkit/src/utils/module-federation'; -import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph'; import { getModuleFederationConfig } from './utils'; -function determineRemoteUrl(remote: string) { - const remoteConfiguration = readCachedProjectConfiguration(remote); - const serveTarget = remoteConfiguration?.targets?.['serve-server']; - - if (!serveTarget) { - throw new Error( - `Cannot automatically determine URL of remote (${remote}). Looked for property "host" in the project's "serve-server" target.\n - You can also use the tuple syntax in your webpack config to configure your remotes. e.g. \`remotes: [['remote1', 'http://localhost:4201']]\`` - ); - } - - const host = serveTarget.options?.host ?? 'http://localhost'; - const port = serveTarget.options?.port ?? 4201; - return `${ - host.endsWith('/') ? host.slice(0, -1) : host - }:${port}/server/remoteEntry.js`; -} - export async function withModuleFederationForSSR( options: ModuleFederationConfig ) { const reactWebpackConfig = require('../../plugins/webpack'); const { sharedLibraries, sharedDependencies, mappedRemotes } = - await getModuleFederationConfig(options, determineRemoteUrl, { + await getModuleFederationConfig(options, { isServer: true, }); diff --git a/packages/react/src/module-federation/with-module-federation.ts b/packages/react/src/module-federation/with-module-federation.ts index e629c3fb646de..6fe9530b321d4 100644 --- a/packages/react/src/module-federation/with-module-federation.ts +++ b/packages/react/src/module-federation/with-module-federation.ts @@ -1,27 +1,8 @@ import { ModuleFederationConfig } from '@nx/devkit/src/utils/module-federation'; -import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph'; import { getModuleFederationConfig } from './utils'; import type { AsyncNxWebpackPlugin } from '@nx/webpack'; import ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); -function determineRemoteUrl(remote: string) { - const remoteConfiguration = readCachedProjectConfiguration(remote); - const serveTarget = remoteConfiguration?.targets?.serve; - - if (!serveTarget) { - throw new Error( - `Cannot automatically determine URL of remote (${remote}). Looked for property "host" in the project's "serve" target.\n - You can also use the tuple syntax in your webpack config to configure your remotes. e.g. \`remotes: [['remote1', 'http://localhost:4201']]\`` - ); - } - - const host = serveTarget.options?.host ?? 'http://localhost'; - const port = serveTarget.options?.port ?? 4201; - return `${ - host.endsWith('/') ? host.slice(0, -1) : host - }:${port}/remoteEntry.js`; -} - /** * @param {ModuleFederationConfig} options * @return {Promise} @@ -32,7 +13,7 @@ export async function withModuleFederation( const reactWebpackConfig = require('../../plugins/webpack'); const { sharedDependencies, sharedLibraries, mappedRemotes } = - await getModuleFederationConfig(options, determineRemoteUrl); + await getModuleFederationConfig(options); return (config, ctx) => { config = reactWebpackConfig(config, ctx);