nx/packages/react/src/executors/module-federation-dev-server/module-federation-dev-server.impl.ts

79 lines
2.3 KiB
TypeScript

import { ExecutorContext, logger, runExecutor } from '@nrwl/devkit';
import devServerExecutor from '@nrwl/webpack/src/executors/dev-server/dev-server.impl';
import { WebDevServerOptions } from '@nrwl/webpack/src/executors/dev-server/schema';
import { join } from 'path';
import * as chalk from 'chalk';
import { combineAsyncIterableIterators } from '@nrwl/js/src/utils/async-iterable/combine-async-iteratable-iterators';
import { tapAsyncIterator } from '@nrwl/js/src/utils/async-iterable/tap-async-iteratable';
type ModuleFederationDevServerOptions = WebDevServerOptions & {
devRemotes?: string | string[];
skipRemotes?: string[];
};
export default async function* moduleFederationDevServer(
options: ModuleFederationDevServerOptions,
context: ExecutorContext
) {
let iter = devServerExecutor(options, context);
const p = context.workspace.projects[context.projectName];
const moduleFederationConfigPath = join(
context.root,
p.root,
'module-federation.config.js'
);
let moduleFederationConfig: any;
try {
moduleFederationConfig = require(moduleFederationConfigPath);
} catch {
// TODO(jack): Add a link to guide
throw new Error(
`Could not load ${moduleFederationConfigPath}. Was this project generated with "@nrwl/react:host"?`
);
}
const remotesToSkip = new Set(options.skipRemotes ?? []);
const knownRemotes = (moduleFederationConfig.remotes ?? []).filter(
(r) => !remotesToSkip.has(r)
);
const devServeApps = !options.devRemotes
? []
: Array.isArray(options.devRemotes)
? options.devRemotes
: [options.devRemotes];
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-static',
configuration: context.configurationName,
},
{
watch: isDev,
},
context
)
);
}
let numAwaiting = knownRemotes.length + 1; // remotes + host
return yield* tapAsyncIterator(iter, (x) => {
numAwaiting--;
if (numAwaiting === 0) {
logger.info(
`[ ${chalk.green('ready')} ] http://${options.host ?? 'localhost'}:${
options.port ?? 4200
}`
);
}
});
}