diff --git a/packages/react/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.ts b/packages/react/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.ts index 87cc9e21e6203..1d8afd9090392 100644 --- a/packages/react/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.ts +++ b/packages/react/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.ts @@ -1,12 +1,20 @@ -import { ExecutorContext, logger, runExecutor } from '@nrwl/devkit'; +import { + ExecutorContext, + logger, + runExecutor, + workspaceRoot, +} from '@nrwl/devkit'; import ssrDevServerExecutor from '@nrwl/webpack/src/executors/ssr-dev-server/ssr-dev-server.impl'; import { WebSsrDevServerOptions } from '@nrwl/webpack/src/executors/ssr-dev-server/schema'; import { join } from 'path'; import * as chalk from 'chalk'; import { combineAsyncIterableIterators, + createAsyncIterable, + mapAsyncIterable, tapAsyncIterable, } from '@nrwl/devkit/src/utils/async-iterable'; +import { execSync, fork } from 'child_process'; type ModuleFederationDevServerOptions = WebSsrDevServerOptions & { devRemotes?: string | string[]; @@ -18,7 +26,7 @@ export default async function* moduleFederationSsrDevServer( options: ModuleFederationDevServerOptions, context: ExecutorContext ) { - let iter = ssrDevServerExecutor(options, context); + let iter: any = ssrDevServerExecutor(options, context); const p = context.workspace.projects[context.projectName]; const moduleFederationConfigPath = join( @@ -51,20 +59,49 @@ export default async function* moduleFederationSsrDevServer( for (const app of knownRemotes) { const [appName] = Array.isArray(app) ? app : [app]; const isDev = devServeApps.includes(appName); - iter = combineAsyncIterableIterators( - iter, - await runExecutor( - { - project: appName, - target: isDev ? 'serve' : 'serve-server', - configuration: context.configurationName, - }, - { - watch: isDev, - }, - context - ) - ); + const remoteServeIter = isDev + ? await runExecutor( + { + project: appName, + target: 'serve', + configuration: context.configurationName, + }, + { + watch: isDev, + }, + context + ) + : mapAsyncIterable( + createAsyncIterable(async ({ next, done }) => { + const remoteProject = context.workspace.projects[appName]; + const remoteServerOutput = join( + workspaceRoot, + remoteProject.targets.server.options.outputPath, + 'main.js' + ); + execSync( + `npx nx run ${appName}:server${ + context.configurationName ? `:${context.configurationName}` : '' + }`, + { stdio: 'inherit' } + ); + const child = fork(remoteServerOutput, { + env: { + PORT: remoteProject.targets['serve-browser'].options.port, + }, + }); + + child.on('message', (msg) => { + if (msg === 'nx.server.ready') { + next(true); + done(); + } + }); + }), + (x) => x + ); + + iter = combineAsyncIterableIterators(iter, remoteServeIter); } let numAwaiting = knownRemotes.length + 1; // remotes + host