feat(react): add module-federation-ssr-dev-server (#13708)

This commit is contained in:
Colum Ferry 2022-12-08 13:35:42 +00:00 committed by GitHub
parent 62fc986609
commit bb32f024cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 191 additions and 1 deletions

View File

@ -1579,6 +1579,54 @@
"aliases": [],
"hidden": false,
"path": "/packages/react/src/executors/module-federation-dev-server/schema.json"
},
{
"name": "module-federation-ssr-dev-server",
"implementation": "/packages/react/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.ts",
"schema": {
"version": 2,
"outputCapture": "direct-nodejs",
"title": "Module Federation SSR Dev Server",
"description": "Serve a SSR host application along with its known remotes.",
"cli": "nx",
"type": "object",
"properties": {
"browserTarget": {
"type": "string",
"description": "Target which builds the browser application."
},
"serverTarget": {
"type": "string",
"description": "Target which builds the server application."
},
"port": {
"type": "number",
"description": "The port to be set on `process.env.PORT` for use in the server.",
"default": 4200
},
"devRemotes": {
"type": "array",
"items": { "type": "string" },
"description": "List of remote applications to run in development mode (i.e. using serve target)."
},
"skipRemotes": {
"type": "array",
"items": { "type": "string" },
"description": "List of remote applications to not automatically serve, either statically or in development mode. This can be useful for multi-repository module federation setups where the host application uses a remote application from an external repository."
},
"host": {
"type": "string",
"description": "Host to listen on.",
"default": "localhost"
}
},
"required": ["browserTarget", "serverTarget"],
"presets": []
},
"description": "Serve a host application along with it's known remotes.",
"aliases": [],
"hidden": false,
"path": "/packages/react/src/executors/module-federation-ssr-dev-server/schema.json"
}
]
}

View File

@ -289,7 +289,10 @@
"description": "The React plugin for Nx contains executors and generators for managing React applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Generators for applications, libraries, components, hooks, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
"path": "generated/packages/react.json",
"schemas": {
"executors": ["module-federation-dev-server"],
"executors": [
"module-federation-dev-server",
"module-federation-ssr-dev-server"
],
"generators": [
"init",
"application",

View File

@ -4,6 +4,11 @@
"implementation": "./src/executors/module-federation-dev-server/compat",
"schema": "./src/executors/module-federation-dev-server/schema.json",
"description": "Serve a host or remote application."
},
"module-federation-ssr-dev-server": {
"implementation": "./src/executors/module-federation-ssr-dev-server/compat",
"schema": "./src/executors/module-federation-ssr-dev-server/schema.json",
"description": "Serve a host application along with it's known remotes."
}
},
"executors": {
@ -11,6 +16,11 @@
"implementation": "./src/executors/module-federation-dev-server/module-federation-dev-server.impl",
"schema": "./src/executors/module-federation-dev-server/schema.json",
"description": "Serve a host or remote application."
},
"module-federation-ssr-dev-server": {
"implementation": "./src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl",
"schema": "./src/executors/module-federation-ssr-dev-server/schema.json",
"description": "Serve a host application along with it's known remotes."
}
}
}

View File

@ -0,0 +1,5 @@
import { convertNxExecutor } from '@nrwl/devkit';
import ssrDevServer from './module-federation-ssr-dev-server.impl';
export default convertNxExecutor(ssrDevServer);

View File

@ -0,0 +1,81 @@
import { ExecutorContext, logger, runExecutor } 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,
tapAsyncIterable,
} from '@nrwl/devkit/src/utils/async-iterable';
type ModuleFederationDevServerOptions = WebSsrDevServerOptions & {
devRemotes?: string | string[];
skipRemotes?: string[];
host: string;
};
export default async function* moduleFederationSsrDevServer(
options: ModuleFederationDevServerOptions,
context: ExecutorContext
) {
let iter = ssrDevServerExecutor(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-server',
configuration: context.configurationName,
},
{
watch: isDev,
},
context
)
);
}
let numAwaiting = knownRemotes.length + 1; // remotes + host
return yield* tapAsyncIterable(iter, (x) => {
numAwaiting--;
if (numAwaiting === 0) {
logger.info(
`[ ${chalk.green('ready')} ] http://${options.host ?? 'localhost'}:${
options.port ?? 4200
}`
);
}
});
}

View File

@ -0,0 +1,43 @@
{
"version": 2,
"outputCapture": "direct-nodejs",
"title": "Module Federation SSR Dev Server",
"description": "Serve a SSR host application along with its known remotes.",
"cli": "nx",
"type": "object",
"properties": {
"browserTarget": {
"type": "string",
"description": "Target which builds the browser application."
},
"serverTarget": {
"type": "string",
"description": "Target which builds the server application."
},
"port": {
"type": "number",
"description": "The port to be set on `process.env.PORT` for use in the server.",
"default": 4200
},
"devRemotes": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of remote applications to run in development mode (i.e. using serve target)."
},
"skipRemotes": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of remote applications to not automatically serve, either statically or in development mode. This can be useful for multi-repository module federation setups where the host application uses a remote application from an external repository."
},
"host": {
"type": "string",
"description": "Host to listen on.",
"default": "localhost"
}
},
"required": ["browserTarget", "serverTarget"]
}