feat(react): add module-federation-ssr-dev-server (#13708)
This commit is contained in:
parent
62fc986609
commit
bb32f024cb
@ -1579,6 +1579,54 @@
|
|||||||
"aliases": [],
|
"aliases": [],
|
||||||
"hidden": false,
|
"hidden": false,
|
||||||
"path": "/packages/react/src/executors/module-federation-dev-server/schema.json"
|
"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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.",
|
"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",
|
"path": "generated/packages/react.json",
|
||||||
"schemas": {
|
"schemas": {
|
||||||
"executors": ["module-federation-dev-server"],
|
"executors": [
|
||||||
|
"module-federation-dev-server",
|
||||||
|
"module-federation-ssr-dev-server"
|
||||||
|
],
|
||||||
"generators": [
|
"generators": [
|
||||||
"init",
|
"init",
|
||||||
"application",
|
"application",
|
||||||
|
|||||||
@ -4,6 +4,11 @@
|
|||||||
"implementation": "./src/executors/module-federation-dev-server/compat",
|
"implementation": "./src/executors/module-federation-dev-server/compat",
|
||||||
"schema": "./src/executors/module-federation-dev-server/schema.json",
|
"schema": "./src/executors/module-federation-dev-server/schema.json",
|
||||||
"description": "Serve a host or remote application."
|
"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": {
|
"executors": {
|
||||||
@ -11,6 +16,11 @@
|
|||||||
"implementation": "./src/executors/module-federation-dev-server/module-federation-dev-server.impl",
|
"implementation": "./src/executors/module-federation-dev-server/module-federation-dev-server.impl",
|
||||||
"schema": "./src/executors/module-federation-dev-server/schema.json",
|
"schema": "./src/executors/module-federation-dev-server/schema.json",
|
||||||
"description": "Serve a host or remote application."
|
"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."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { convertNxExecutor } from '@nrwl/devkit';
|
||||||
|
|
||||||
|
import ssrDevServer from './module-federation-ssr-dev-server.impl';
|
||||||
|
|
||||||
|
export default convertNxExecutor(ssrDevServer);
|
||||||
@ -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
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -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"]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user