@nx/rspack 20.2.0-beta.5 → 20.2.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/executors/module-federation-dev-server/lib/index.d.ts +2 -0
- package/src/executors/module-federation-dev-server/lib/index.js +5 -0
- package/src/executors/module-federation-dev-server/lib/normalize-options.d.ts +4 -0
- package/src/executors/module-federation-dev-server/lib/normalize-options.js +19 -0
- package/src/executors/module-federation-dev-server/lib/start-remotes.d.ts +5 -0
- package/src/executors/module-federation-dev-server/lib/start-remotes.js +33 -0
- package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.d.ts +1 -1
- package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.js +6 -108
- package/src/executors/module-federation-dev-server/schema.d.ts +7 -0
- package/src/executors/module-federation-ssr-dev-server/lib/index.d.ts +2 -0
- package/src/executors/module-federation-ssr-dev-server/lib/index.js +5 -0
- package/src/executors/module-federation-ssr-dev-server/lib/normalize-options.d.ts +4 -0
- package/src/executors/module-federation-ssr-dev-server/lib/normalize-options.js +23 -0
- package/src/executors/module-federation-ssr-dev-server/lib/start-remotes.d.ts +5 -0
- package/src/executors/module-federation-ssr-dev-server/lib/start-remotes.js +34 -0
- package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.d.ts +1 -17
- package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.js +5 -154
- package/src/executors/module-federation-ssr-dev-server/schema.d.ts +29 -0
- package/src/executors/module-federation-static-server/module-federation-static-server.impl.js +2 -2
- package/src/utils/module-federation/build-static.remotes.d.ts +0 -4
- package/src/utils/module-federation/build-static.remotes.js +0 -69
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/rspack",
|
|
3
3
|
"description": "The Nx Plugin for Rspack contains executors and generators that support building applications using Rspack.",
|
|
4
|
-
"version": "20.2.0-beta.
|
|
4
|
+
"version": "20.2.0-beta.7",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"generators": "./generators.json",
|
|
25
25
|
"executors": "./executors.json",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@nx/js": "20.2.0-beta.
|
|
28
|
-
"@nx/devkit": "20.2.0-beta.
|
|
29
|
-
"@nx/web": "20.2.0-beta.
|
|
30
|
-
"@nx/module-federation": "20.2.0-beta.
|
|
27
|
+
"@nx/js": "20.2.0-beta.7",
|
|
28
|
+
"@nx/devkit": "20.2.0-beta.7",
|
|
29
|
+
"@nx/web": "20.2.0-beta.7",
|
|
30
|
+
"@nx/module-federation": "20.2.0-beta.7",
|
|
31
31
|
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
32
32
|
"@rspack/core": "^1.1.2",
|
|
33
33
|
"@rspack/dev-server": "^1.0.9",
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ExecutorContext } from '@nx/devkit';
|
|
2
|
+
import { ModuleFederationDevServerOptions, NormalizedModuleFederationDevServerOptions } from '../schema';
|
|
3
|
+
export declare function getBuildOptions(buildTarget: string, context: ExecutorContext): any;
|
|
4
|
+
export declare function normalizeOptions(options: ModuleFederationDevServerOptions): NormalizedModuleFederationDevServerOptions;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBuildOptions = getBuildOptions;
|
|
4
|
+
exports.normalizeOptions = normalizeOptions;
|
|
5
|
+
const devkit_1 = require("@nx/devkit");
|
|
6
|
+
function getBuildOptions(buildTarget, context) {
|
|
7
|
+
const target = (0, devkit_1.parseTargetString)(buildTarget, context);
|
|
8
|
+
const buildOptions = (0, devkit_1.readTargetOptions)(target, context);
|
|
9
|
+
return {
|
|
10
|
+
...buildOptions,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function normalizeOptions(options) {
|
|
14
|
+
return {
|
|
15
|
+
...options,
|
|
16
|
+
devRemotes: options.devRemotes ?? [],
|
|
17
|
+
verbose: options.verbose ?? false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ModuleFederationDevServerOptions } from '../schema';
|
|
2
|
+
import { ProjectConfiguration, ExecutorContext } from '@nx/devkit';
|
|
3
|
+
export declare function startRemotes(remotes: string[], workspaceProjects: Record<string, ProjectConfiguration>, options: Partial<Pick<ModuleFederationDevServerOptions, 'devRemotes' | 'host' | 'ssl' | 'sslCert' | 'sslKey' | 'verbose'>>, context: ExecutorContext, target?: 'serve' | 'serve-static'): Promise<AsyncIterable<{
|
|
4
|
+
success: boolean;
|
|
5
|
+
}>[]>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startRemotes = startRemotes;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
async function startRemotes(remotes, workspaceProjects, options, context, target = 'serve') {
|
|
6
|
+
const remoteIters = [];
|
|
7
|
+
for (const app of remotes) {
|
|
8
|
+
const remoteProjectServeTarget = workspaceProjects[app].targets[target];
|
|
9
|
+
const isUsingModuleFederationDevServerExecutor = remoteProjectServeTarget.executor.includes('module-federation-dev-server');
|
|
10
|
+
const configurationOverride = options.devRemotes?.find((r) => typeof r !== 'string' && r.remoteName === app)?.configuration;
|
|
11
|
+
const defaultOverrides = {
|
|
12
|
+
...(options.host ? { host: options.host } : {}),
|
|
13
|
+
...(options.ssl ? { ssl: options.ssl } : {}),
|
|
14
|
+
...(options.sslCert ? { sslCert: options.sslCert } : {}),
|
|
15
|
+
...(options.sslKey ? { sslKey: options.sslKey } : {}),
|
|
16
|
+
};
|
|
17
|
+
const overrides = target === 'serve'
|
|
18
|
+
? {
|
|
19
|
+
watch: true,
|
|
20
|
+
...(isUsingModuleFederationDevServerExecutor
|
|
21
|
+
? { isInitialHost: false }
|
|
22
|
+
: {}),
|
|
23
|
+
...defaultOverrides,
|
|
24
|
+
}
|
|
25
|
+
: { ...defaultOverrides };
|
|
26
|
+
remoteIters.push(await (0, devkit_1.runExecutor)({
|
|
27
|
+
project: app,
|
|
28
|
+
target,
|
|
29
|
+
configuration: configurationOverride ?? context.configurationName,
|
|
30
|
+
}, overrides, context));
|
|
31
|
+
}
|
|
32
|
+
return remoteIters;
|
|
33
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ExecutorContext } from '@nx/devkit';
|
|
2
2
|
import { ModuleFederationDevServerOptions } from './schema';
|
|
3
|
-
export default function moduleFederationDevServer(
|
|
3
|
+
export default function moduleFederationDevServer(schema: ModuleFederationDevServerOptions, context: ExecutorContext): AsyncIterableIterator<{
|
|
4
4
|
success: boolean;
|
|
5
5
|
baseUrl?: string;
|
|
6
6
|
}>;
|
|
@@ -8,91 +8,11 @@ const file_server_impl_1 = tslib_1.__importDefault(require("@nx/web/src/executor
|
|
|
8
8
|
const wait_for_port_open_1 = require("@nx/web/src/utils/wait-for-port-open");
|
|
9
9
|
const fs_1 = require("fs");
|
|
10
10
|
const path_1 = require("path");
|
|
11
|
-
const utils_1 = require("@nx/module-federation/src/utils");
|
|
12
|
-
const build_static_remotes_1 = require("../../utils/module-federation/build-static.remotes");
|
|
11
|
+
const utils_1 = require("@nx/module-federation/src/executors/utils");
|
|
13
12
|
const dev_server_impl_1 = tslib_1.__importDefault(require("../dev-server/dev-server.impl"));
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
return {
|
|
18
|
-
...buildOptions,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
function startStaticRemotesFileServer(staticRemotesConfig, context, options) {
|
|
22
|
-
if (!staticRemotesConfig.remotes ||
|
|
23
|
-
staticRemotesConfig.remotes.length === 0) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
let shouldMoveToCommonLocation = false;
|
|
27
|
-
let commonOutputDirectory;
|
|
28
|
-
for (const app of staticRemotesConfig.remotes) {
|
|
29
|
-
const remoteBasePath = staticRemotesConfig.config[app].basePath;
|
|
30
|
-
if (!commonOutputDirectory) {
|
|
31
|
-
commonOutputDirectory = remoteBasePath;
|
|
32
|
-
}
|
|
33
|
-
else if (commonOutputDirectory !== remoteBasePath) {
|
|
34
|
-
shouldMoveToCommonLocation = true;
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (shouldMoveToCommonLocation) {
|
|
39
|
-
commonOutputDirectory = (0, path_1.join)(devkit_1.workspaceRoot, 'tmp/static-remotes');
|
|
40
|
-
for (const app of staticRemotesConfig.remotes) {
|
|
41
|
-
const remoteConfig = staticRemotesConfig.config[app];
|
|
42
|
-
(0, fs_1.cpSync)(remoteConfig.outputPath, (0, path_1.join)(commonOutputDirectory, remoteConfig.urlSegment), {
|
|
43
|
-
force: true,
|
|
44
|
-
recursive: true,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
const staticRemotesIter = (0, file_server_impl_1.default)({
|
|
49
|
-
cors: true,
|
|
50
|
-
watch: false,
|
|
51
|
-
staticFilePath: commonOutputDirectory,
|
|
52
|
-
parallel: false,
|
|
53
|
-
spa: false,
|
|
54
|
-
withDeps: false,
|
|
55
|
-
host: options.host,
|
|
56
|
-
port: options.staticRemotesPort,
|
|
57
|
-
ssl: options.ssl,
|
|
58
|
-
sslCert: options.sslCert,
|
|
59
|
-
sslKey: options.sslKey,
|
|
60
|
-
cacheSeconds: -1,
|
|
61
|
-
}, context);
|
|
62
|
-
return staticRemotesIter;
|
|
63
|
-
}
|
|
64
|
-
async function startRemotes(remotes, context, options, target = 'serve') {
|
|
65
|
-
const remoteIters = [];
|
|
66
|
-
for (const app of remotes) {
|
|
67
|
-
const remoteProjectServeTarget = context.projectGraph.nodes[app].data.targets[target];
|
|
68
|
-
const isUsingModuleFederationDevServerExecutor = remoteProjectServeTarget.executor.includes('module-federation-dev-server');
|
|
69
|
-
const configurationOverride = options.devRemotes?.find((r) => typeof r !== 'string' && r.remoteName === app)?.configuration;
|
|
70
|
-
const defaultOverrides = {
|
|
71
|
-
...(options.host ? { host: options.host } : {}),
|
|
72
|
-
...(options.ssl ? { ssl: options.ssl } : {}),
|
|
73
|
-
...(options.sslCert ? { sslCert: options.sslCert } : {}),
|
|
74
|
-
...(options.sslKey ? { sslKey: options.sslKey } : {}),
|
|
75
|
-
};
|
|
76
|
-
const overrides = target === 'serve'
|
|
77
|
-
? {
|
|
78
|
-
watch: true,
|
|
79
|
-
...(isUsingModuleFederationDevServerExecutor
|
|
80
|
-
? { isInitialHost: false }
|
|
81
|
-
: {}),
|
|
82
|
-
...defaultOverrides,
|
|
83
|
-
}
|
|
84
|
-
: { ...defaultOverrides };
|
|
85
|
-
remoteIters.push(await (0, devkit_1.runExecutor)({
|
|
86
|
-
project: app,
|
|
87
|
-
target,
|
|
88
|
-
configuration: configurationOverride ?? context.configurationName,
|
|
89
|
-
}, overrides, context));
|
|
90
|
-
}
|
|
91
|
-
return remoteIters;
|
|
92
|
-
}
|
|
93
|
-
async function* moduleFederationDevServer(options, context) {
|
|
94
|
-
// Force Node to resolve to look for the nx binary that is inside node_modules
|
|
95
|
-
const nxBin = require.resolve('nx/bin/nx');
|
|
13
|
+
const lib_1 = require("./lib");
|
|
14
|
+
async function* moduleFederationDevServer(schema, context) {
|
|
15
|
+
const options = (0, lib_1.normalizeOptions)(schema);
|
|
96
16
|
const currIter = options.static
|
|
97
17
|
? (0, file_server_impl_1.default)({
|
|
98
18
|
...options,
|
|
@@ -104,7 +24,7 @@ async function* moduleFederationDevServer(options, context) {
|
|
|
104
24
|
}, context)
|
|
105
25
|
: (0, dev_server_impl_1.default)(options, context);
|
|
106
26
|
const p = context.projectsConfigurations.projects[context.projectName];
|
|
107
|
-
const buildOptions = getBuildOptions(options.buildTarget, context);
|
|
27
|
+
const buildOptions = (0, lib_1.getBuildOptions)(options.buildTarget, context);
|
|
108
28
|
let pathToManifestFile = (0, path_1.join)(context.root, p.sourceRoot, 'assets/module-federation.manifest.json');
|
|
109
29
|
if (options.pathToManifestFile) {
|
|
110
30
|
const userPathToManifestFile = (0, path_1.join)(context.root, options.pathToManifestFile);
|
|
@@ -119,29 +39,7 @@ async function* moduleFederationDevServer(options, context) {
|
|
|
119
39
|
if (!options.isInitialHost) {
|
|
120
40
|
return yield* currIter;
|
|
121
41
|
}
|
|
122
|
-
const
|
|
123
|
-
const remoteNames = options.devRemotes?.map((r) => typeof r === 'string' ? r : r.remoteName);
|
|
124
|
-
const remotes = (0, utils_1.getRemotes)(remoteNames, options.skipRemotes, moduleFederationConfig, {
|
|
125
|
-
projectName: context.projectName,
|
|
126
|
-
projectGraph: context.projectGraph,
|
|
127
|
-
root: context.root,
|
|
128
|
-
}, pathToManifestFile);
|
|
129
|
-
options.staticRemotesPort ??= remotes.staticRemotePort;
|
|
130
|
-
// Set NX_MF_DEV_REMOTES for the Nx Runtime Library Control Plugin
|
|
131
|
-
process.env.NX_MF_DEV_REMOTES = JSON.stringify([
|
|
132
|
-
...(remotes.devRemotes.map((r) => typeof r === 'string' ? r : r.remoteName) ?? []).map((r) => r.replace(/-/g, '_')),
|
|
133
|
-
p.name.replace(/-/g, '_'),
|
|
134
|
-
]);
|
|
135
|
-
const staticRemotesConfig = (0, utils_1.parseStaticRemotesConfig)([...remotes.staticRemotes, ...remotes.dynamicRemotes], context);
|
|
136
|
-
const mappedLocationsOfStaticRemotes = await (0, build_static_remotes_1.buildStaticRemotes)(staticRemotesConfig, nxBin, context, options);
|
|
137
|
-
const devRemoteIters = await startRemotes(remotes.devRemotes, context, options, 'serve');
|
|
138
|
-
const staticRemotesIter = startStaticRemotesFileServer(staticRemotesConfig, context, options);
|
|
139
|
-
(0, utils_1.startRemoteProxies)(staticRemotesConfig, mappedLocationsOfStaticRemotes, options.ssl
|
|
140
|
-
? {
|
|
141
|
-
pathToCert: (0, path_1.join)(devkit_1.workspaceRoot, options.sslCert),
|
|
142
|
-
pathToKey: (0, path_1.join)(devkit_1.workspaceRoot, options.sslKey),
|
|
143
|
-
}
|
|
144
|
-
: undefined);
|
|
42
|
+
const { staticRemotesIter, devRemoteIters, remotes } = await (0, utils_1.startRemoteIterators)(options, context, lib_1.startRemotes, pathToManifestFile, 'react');
|
|
145
43
|
return yield* (0, async_iterable_1.combineAsyncIterables)(currIter, ...devRemoteIters, ...(staticRemotesIter ? [staticRemotesIter] : []), (0, async_iterable_1.createAsyncIterable)(async ({ next, done }) => {
|
|
146
44
|
if (!options.isInitialHost) {
|
|
147
45
|
done();
|
|
@@ -15,4 +15,11 @@ export type ModuleFederationDevServerOptions = DevServerExecutorSchema & {
|
|
|
15
15
|
parallel?: number;
|
|
16
16
|
staticRemotesPort?: number;
|
|
17
17
|
pathToManifestFile?: string;
|
|
18
|
+
verbose?: boolean;
|
|
18
19
|
};
|
|
20
|
+
|
|
21
|
+
export type NormalizedModuleFederationDevServerOptions =
|
|
22
|
+
ModuleFederationDevServerOptions & {
|
|
23
|
+
devRemotes: DevServerExecutorSchema['devRemotes'];
|
|
24
|
+
verbose: boolean;
|
|
25
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ModuleFederationSsrDevServerOptions, NormalizedModuleFederationSsrDevServerOptions } from '../schema';
|
|
2
|
+
import { ExecutorContext } from '@nx/devkit';
|
|
3
|
+
export declare function normalizeOptions(options: ModuleFederationSsrDevServerOptions): NormalizedModuleFederationSsrDevServerOptions;
|
|
4
|
+
export declare function getBuildOptions(buildTarget: string, context: ExecutorContext): any;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeOptions = normalizeOptions;
|
|
4
|
+
exports.getBuildOptions = getBuildOptions;
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const devkit_1 = require("@nx/devkit");
|
|
7
|
+
function normalizeOptions(options) {
|
|
8
|
+
return {
|
|
9
|
+
...options,
|
|
10
|
+
devRemotes: options.devRemotes ?? [],
|
|
11
|
+
verbose: options.verbose ?? false,
|
|
12
|
+
ssl: options.ssl ?? false,
|
|
13
|
+
sslCert: options.sslCert ? (0, path_1.join)(devkit_1.workspaceRoot, options.sslCert) : undefined,
|
|
14
|
+
sslKey: options.sslKey ? (0, path_1.join)(devkit_1.workspaceRoot, options.sslKey) : undefined,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function getBuildOptions(buildTarget, context) {
|
|
18
|
+
const target = (0, devkit_1.parseTargetString)(buildTarget, context);
|
|
19
|
+
const buildOptions = (0, devkit_1.readTargetOptions)(target, context);
|
|
20
|
+
return {
|
|
21
|
+
...buildOptions,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ModuleFederationSsrDevServerOptions } from '../schema';
|
|
2
|
+
import { ExecutorContext, ProjectConfiguration } from '@nx/devkit';
|
|
3
|
+
export declare function startRemotes(remotes: string[], workspaceProjects: Record<string, ProjectConfiguration>, options: Partial<Pick<ModuleFederationSsrDevServerOptions, 'devRemotes' | 'host' | 'ssl' | 'sslCert' | 'sslKey' | 'verbose'>>, context: ExecutorContext): Promise<AsyncIterable<{
|
|
4
|
+
success: boolean;
|
|
5
|
+
}>[]>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startRemotes = startRemotes;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
async function startRemotes(remotes, workspaceProjects, options, context) {
|
|
6
|
+
const remoteIters = [];
|
|
7
|
+
const target = 'serve';
|
|
8
|
+
for (const app of remotes) {
|
|
9
|
+
const remoteProjectServeTarget = workspaceProjects[app].targets[target];
|
|
10
|
+
const isUsingModuleFederationSsrDevServerExecutor = remoteProjectServeTarget.executor.includes('module-federation-ssr-dev-server');
|
|
11
|
+
const configurationOverride = options.devRemotes?.find((remote) => typeof remote !== 'string' && remote.remoteName === app)?.configuration;
|
|
12
|
+
{
|
|
13
|
+
const defaultOverrides = {
|
|
14
|
+
...(options.host ? { host: options.host } : {}),
|
|
15
|
+
...(options.ssl ? { ssl: options.ssl } : {}),
|
|
16
|
+
...(options.sslCert ? { sslCert: options.sslCert } : {}),
|
|
17
|
+
...(options.sslKey ? { sslKey: options.sslKey } : {}),
|
|
18
|
+
};
|
|
19
|
+
const overrides = {
|
|
20
|
+
watch: true,
|
|
21
|
+
...defaultOverrides,
|
|
22
|
+
...(isUsingModuleFederationSsrDevServerExecutor
|
|
23
|
+
? { isInitialHost: false }
|
|
24
|
+
: {}),
|
|
25
|
+
};
|
|
26
|
+
remoteIters.push(await (0, devkit_1.runExecutor)({
|
|
27
|
+
project: app,
|
|
28
|
+
target,
|
|
29
|
+
configuration: configurationOverride ?? context.configurationName,
|
|
30
|
+
}, overrides, context));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return remoteIters;
|
|
34
|
+
}
|
package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.d.ts
CHANGED
|
@@ -1,21 +1,5 @@
|
|
|
1
1
|
import { ExecutorContext } from '@nx/devkit';
|
|
2
|
-
import {
|
|
3
|
-
type ModuleFederationSsrDevServerOptions = RspackSsrDevServerOptions & {
|
|
4
|
-
devRemotes?: (string | {
|
|
5
|
-
remoteName: string;
|
|
6
|
-
configuration: string;
|
|
7
|
-
})[];
|
|
8
|
-
skipRemotes?: string[];
|
|
9
|
-
host: string;
|
|
10
|
-
pathToManifestFile?: string;
|
|
11
|
-
staticRemotesPort?: number;
|
|
12
|
-
parallel?: number;
|
|
13
|
-
ssl?: boolean;
|
|
14
|
-
sslKey?: string;
|
|
15
|
-
sslCert?: string;
|
|
16
|
-
isInitialHost?: boolean;
|
|
17
|
-
};
|
|
2
|
+
import { ModuleFederationSsrDevServerOptions } from './schema';
|
|
18
3
|
export default function moduleFederationSsrDevServer(ssrDevServerOptions: ModuleFederationSsrDevServerOptions, context: ExecutorContext): AsyncGenerator<{
|
|
19
4
|
success: boolean;
|
|
20
5
|
}, any, any>;
|
|
21
|
-
export {};
|
package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.js
CHANGED
|
@@ -4,145 +4,17 @@ exports.default = moduleFederationSsrDevServer;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const devkit_1 = require("@nx/devkit");
|
|
6
6
|
const path_1 = require("path");
|
|
7
|
-
const utils_1 = require("@nx/module-federation/src/utils");
|
|
7
|
+
const utils_1 = require("@nx/module-federation/src/executors/utils");
|
|
8
8
|
const ssr_dev_server_impl_1 = tslib_1.__importDefault(require("../ssr-dev-server/ssr-dev-server.impl"));
|
|
9
9
|
const async_iterable_1 = require("@nx/devkit/src/utils/async-iterable");
|
|
10
|
-
const child_process_1 = require("child_process");
|
|
11
10
|
const fs_1 = require("fs");
|
|
12
|
-
const file_server_impl_1 = tslib_1.__importDefault(require("@nx/web/src/executors/file-server/file-server.impl"));
|
|
13
11
|
const wait_for_port_open_1 = require("@nx/web/src/utils/wait-for-port-open");
|
|
14
|
-
const
|
|
15
|
-
function normalizeOptions(options) {
|
|
16
|
-
return {
|
|
17
|
-
...options,
|
|
18
|
-
ssl: options.ssl ?? false,
|
|
19
|
-
sslCert: options.sslCert ? (0, path_1.join)(devkit_1.workspaceRoot, options.sslCert) : undefined,
|
|
20
|
-
sslKey: options.sslKey ? (0, path_1.join)(devkit_1.workspaceRoot, options.sslKey) : undefined,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function getBuildOptions(buildTarget, context) {
|
|
24
|
-
const target = (0, devkit_1.parseTargetString)(buildTarget, context);
|
|
25
|
-
const buildOptions = (0, devkit_1.readTargetOptions)(target, context);
|
|
26
|
-
return {
|
|
27
|
-
...buildOptions,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function startSsrStaticRemotesFileServer(ssrStaticRemotesConfig, context, options) {
|
|
31
|
-
if (ssrStaticRemotesConfig.remotes.length === 0) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
// The directories are usually generated with /browser and /server suffixes so we need to copy them to a common directory
|
|
35
|
-
const commonOutputDirectory = (0, path_1.join)(devkit_1.workspaceRoot, 'tmp/static-remotes');
|
|
36
|
-
for (const app of ssrStaticRemotesConfig.remotes) {
|
|
37
|
-
const remoteConfig = ssrStaticRemotesConfig.config[app];
|
|
38
|
-
(0, fs_1.cpSync)(remoteConfig.outputPath, (0, path_1.join)(commonOutputDirectory, remoteConfig.urlSegment), {
|
|
39
|
-
force: true,
|
|
40
|
-
recursive: true,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
const staticRemotesIter = (0, file_server_impl_1.default)({
|
|
44
|
-
cors: true,
|
|
45
|
-
watch: false,
|
|
46
|
-
staticFilePath: commonOutputDirectory,
|
|
47
|
-
parallel: false,
|
|
48
|
-
spa: false,
|
|
49
|
-
withDeps: false,
|
|
50
|
-
host: options.host,
|
|
51
|
-
port: options.staticRemotesPort,
|
|
52
|
-
ssl: options.ssl,
|
|
53
|
-
sslCert: options.sslCert,
|
|
54
|
-
sslKey: options.sslKey,
|
|
55
|
-
cacheSeconds: -1,
|
|
56
|
-
}, context);
|
|
57
|
-
return staticRemotesIter;
|
|
58
|
-
}
|
|
59
|
-
async function startRemotes(remotes, context, options) {
|
|
60
|
-
const remoteIters = [];
|
|
61
|
-
const target = 'serve';
|
|
62
|
-
for (const app of remotes) {
|
|
63
|
-
const remoteProjectServeTarget = context.projectGraph.nodes[app].data.targets[target];
|
|
64
|
-
const isUsingModuleFederationSsrDevServerExecutor = remoteProjectServeTarget.executor.includes('module-federation-ssr-dev-server');
|
|
65
|
-
const configurationOverride = options.devRemotes?.find((remote) => typeof remote !== 'string' && remote.remoteName === app)?.configuration;
|
|
66
|
-
{
|
|
67
|
-
const defaultOverrides = {
|
|
68
|
-
...(options.host ? { host: options.host } : {}),
|
|
69
|
-
...(options.ssl ? { ssl: options.ssl } : {}),
|
|
70
|
-
...(options.sslCert ? { sslCert: options.sslCert } : {}),
|
|
71
|
-
...(options.sslKey ? { sslKey: options.sslKey } : {}),
|
|
72
|
-
};
|
|
73
|
-
const overrides = {
|
|
74
|
-
watch: true,
|
|
75
|
-
...defaultOverrides,
|
|
76
|
-
...(isUsingModuleFederationSsrDevServerExecutor
|
|
77
|
-
? { isInitialHost: false }
|
|
78
|
-
: {}),
|
|
79
|
-
};
|
|
80
|
-
remoteIters.push(await (0, devkit_1.runExecutor)({
|
|
81
|
-
project: app,
|
|
82
|
-
target,
|
|
83
|
-
configuration: configurationOverride ?? context.configurationName,
|
|
84
|
-
}, overrides, context));
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return remoteIters;
|
|
88
|
-
}
|
|
89
|
-
async function buildSsrStaticRemotes(staticRemotesConfig, nxBin, context, options) {
|
|
90
|
-
if (!staticRemotesConfig.remotes.length) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
devkit_1.logger.info(`Nx is building ${staticRemotesConfig.remotes.length} static remotes...`);
|
|
94
|
-
const mapLocationOfRemotes = {};
|
|
95
|
-
for (const remoteApp of staticRemotesConfig.remotes) {
|
|
96
|
-
mapLocationOfRemotes[remoteApp] = `http${options.ssl ? 's' : ''}://${options.host}:${options.staticRemotesPort}/${staticRemotesConfig.config[remoteApp].urlSegment}`;
|
|
97
|
-
}
|
|
98
|
-
await new Promise((resolve) => {
|
|
99
|
-
const childProcess = (0, child_process_1.fork)(nxBin, [
|
|
100
|
-
'run-many',
|
|
101
|
-
'--target=server',
|
|
102
|
-
'--projects',
|
|
103
|
-
staticRemotesConfig.remotes.join(','),
|
|
104
|
-
...(context.configurationName
|
|
105
|
-
? [`--configuration=${context.configurationName}`]
|
|
106
|
-
: []),
|
|
107
|
-
...(options.parallel ? [`--parallel=${options.parallel}`] : []),
|
|
108
|
-
], {
|
|
109
|
-
cwd: context.root,
|
|
110
|
-
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
111
|
-
});
|
|
112
|
-
// Add a listener to the child process to capture the build log
|
|
113
|
-
const remoteBuildLogFile = (0, path_1.join)(cache_directory_1.workspaceDataDirectory,
|
|
114
|
-
// eslint-disable-next-line
|
|
115
|
-
`${new Date().toISOString().replace(/[:\.]/g, '_')}-build.log`);
|
|
116
|
-
const remoteBuildLogStream = (0, fs_1.createWriteStream)(remoteBuildLogFile);
|
|
117
|
-
childProcess.stdout.on('data', (data) => {
|
|
118
|
-
const ANSII_CODE_REGEX =
|
|
119
|
-
// eslint-disable-next-line no-control-regex
|
|
120
|
-
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
|
121
|
-
const stdoutString = data.toString().replace(ANSII_CODE_REGEX, '');
|
|
122
|
-
remoteBuildLogStream.write(stdoutString);
|
|
123
|
-
// in addition to writing into the stdout stream, also show error directly in console
|
|
124
|
-
// so the error is easily discoverable. 'ERROR in' is the key word to search in webpack output.
|
|
125
|
-
if (stdoutString.includes('ERROR in')) {
|
|
126
|
-
devkit_1.logger.log(stdoutString);
|
|
127
|
-
}
|
|
128
|
-
if (stdoutString.includes('Successfully ran target server')) {
|
|
129
|
-
childProcess.stdout.removeAllListeners('data');
|
|
130
|
-
devkit_1.logger.info(`Nx Built ${staticRemotesConfig.remotes.length} static remotes.`);
|
|
131
|
-
resolve();
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
process.on('SIGTERM', () => childProcess.kill('SIGTERM'));
|
|
135
|
-
process.on('exit', () => childProcess.kill('SIGTERM'));
|
|
136
|
-
});
|
|
137
|
-
return mapLocationOfRemotes;
|
|
138
|
-
}
|
|
12
|
+
const lib_1 = require("./lib");
|
|
139
13
|
async function* moduleFederationSsrDevServer(ssrDevServerOptions, context) {
|
|
140
|
-
const options = normalizeOptions(ssrDevServerOptions);
|
|
141
|
-
// Force Node to resolve to look for the nx binary that is inside node_modules
|
|
142
|
-
const nxBin = require.resolve('nx/bin/nx');
|
|
14
|
+
const options = (0, lib_1.normalizeOptions)(ssrDevServerOptions);
|
|
143
15
|
const iter = (0, ssr_dev_server_impl_1.default)(options, context);
|
|
144
16
|
const projectConfig = context.projectsConfigurations.projects[context.projectName];
|
|
145
|
-
const buildOptions = getBuildOptions(options.browserTarget, context);
|
|
17
|
+
const buildOptions = (0, lib_1.getBuildOptions)(options.browserTarget, context);
|
|
146
18
|
let pathToManifestFile = (0, path_1.join)(context.root, projectConfig.sourceRoot, 'assets/module-federation.manifest.json');
|
|
147
19
|
if (options.pathToManifestFile) {
|
|
148
20
|
const userPathToManifestFile = (0, path_1.join)(context.root, options.pathToManifestFile);
|
|
@@ -157,28 +29,7 @@ async function* moduleFederationSsrDevServer(ssrDevServerOptions, context) {
|
|
|
157
29
|
if (!options.isInitialHost) {
|
|
158
30
|
return yield* iter;
|
|
159
31
|
}
|
|
160
|
-
const
|
|
161
|
-
const remoteNames = options.devRemotes?.map((remote) => typeof remote === 'string' ? remote : remote.remoteName);
|
|
162
|
-
const remotes = (0, utils_1.getRemotes)(remoteNames, options.skipRemotes, moduleFederationConfig, {
|
|
163
|
-
projectName: context.projectName,
|
|
164
|
-
projectGraph: context.projectGraph,
|
|
165
|
-
root: context.root,
|
|
166
|
-
}, pathToManifestFile);
|
|
167
|
-
options.staticRemotesPort ??= remotes.staticRemotePort;
|
|
168
|
-
process.env.NX_MF_DEV_REMOTES = JSON.stringify([
|
|
169
|
-
...(remotes.devRemotes.map((r) => typeof r === 'string' ? r : r.remoteName) ?? []).map((r) => r.replace(/-/g, '_')),
|
|
170
|
-
projectConfig.name.replace(/-/g, '_'),
|
|
171
|
-
]);
|
|
172
|
-
const staticRemotesConfig = (0, utils_1.parseStaticSsrRemotesConfig)([...remotes.staticRemotes, ...remotes.dynamicRemotes], context);
|
|
173
|
-
const mappedLocationsOfStaticRemotes = await buildSsrStaticRemotes(staticRemotesConfig, nxBin, context, options);
|
|
174
|
-
const devRemoteIters = await startRemotes(remotes.devRemotes, context, options);
|
|
175
|
-
const staticRemotesIter = startSsrStaticRemotesFileServer(staticRemotesConfig, context, options);
|
|
176
|
-
(0, utils_1.startSsrRemoteProxies)(staticRemotesConfig, mappedLocationsOfStaticRemotes, options.ssl
|
|
177
|
-
? {
|
|
178
|
-
pathToCert: options.sslCert,
|
|
179
|
-
pathToKey: options.sslKey,
|
|
180
|
-
}
|
|
181
|
-
: undefined);
|
|
32
|
+
const { staticRemotesIter, devRemoteIters, remotes } = await (0, utils_1.startRemoteIterators)(options, context, lib_1.startRemotes, pathToManifestFile, 'react', true);
|
|
182
33
|
return yield* (0, async_iterable_1.combineAsyncIterables)(iter, ...devRemoteIters, ...(staticRemotesIter ? [staticRemotesIter] : []), (0, async_iterable_1.createAsyncIterable)(async ({ next, done }) => {
|
|
183
34
|
if (!options.isInitialHost) {
|
|
184
35
|
done();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DevRemoteDefinition } from '@nx/module-federation/src/executors/utils';
|
|
2
|
+
import { RspackSsrDevServerOptions } from '../ssr-dev-server/schema';
|
|
3
|
+
|
|
4
|
+
export type ModuleFederationSsrDevServerOptions = RspackSsrDevServerOptions & {
|
|
5
|
+
devRemotes?: (
|
|
6
|
+
| string
|
|
7
|
+
| {
|
|
8
|
+
remoteName: string;
|
|
9
|
+
configuration: string;
|
|
10
|
+
}
|
|
11
|
+
)[];
|
|
12
|
+
|
|
13
|
+
skipRemotes?: string[];
|
|
14
|
+
host: string;
|
|
15
|
+
pathToManifestFile?: string;
|
|
16
|
+
staticRemotesPort?: number;
|
|
17
|
+
parallel?: number;
|
|
18
|
+
ssl?: boolean;
|
|
19
|
+
sslKey?: string;
|
|
20
|
+
sslCert?: string;
|
|
21
|
+
isInitialHost?: boolean;
|
|
22
|
+
verbose?: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type NormalizedModuleFederationSsrDevServerOptions =
|
|
26
|
+
ModuleFederationSsrDevServerOptions & {
|
|
27
|
+
devRemotes: DevRemoteDefinition[];
|
|
28
|
+
verbose: boolean;
|
|
29
|
+
};
|
package/src/executors/module-federation-static-server/module-federation-static-server.impl.js
CHANGED
|
@@ -11,7 +11,7 @@ const child_process_1 = require("child_process");
|
|
|
11
11
|
const fs_1 = require("fs");
|
|
12
12
|
const path_1 = require("path");
|
|
13
13
|
const utils_1 = require("@nx/module-federation/src/utils");
|
|
14
|
-
const
|
|
14
|
+
const utils_2 = require("@nx/module-federation/src/executors/utils");
|
|
15
15
|
function getBuildAndServeOptionsFromServeTarget(serveTarget, context) {
|
|
16
16
|
const target = (0, devkit_1.parseTargetString)(serveTarget, context);
|
|
17
17
|
const serveOptions = (0, devkit_1.readTargetOptions)(target, context);
|
|
@@ -177,7 +177,7 @@ async function* moduleFederationStaticServer(schema, context) {
|
|
|
177
177
|
}, options.pathToManifestFile);
|
|
178
178
|
const staticRemotesConfig = (0, utils_1.parseStaticRemotesConfig)([...remotes.staticRemotes, ...remotes.dynamicRemotes], context);
|
|
179
179
|
options.serveOptions.staticRemotesPort ??= remotes.staticRemotePort;
|
|
180
|
-
const mappedLocationsOfStaticRemotes = await (0,
|
|
180
|
+
const mappedLocationsOfStaticRemotes = await (0, utils_2.buildStaticRemotes)(staticRemotesConfig, nxBin, context, options.serveOptions);
|
|
181
181
|
// Build the host
|
|
182
182
|
const hostUrlSegment = (0, path_1.basename)(options.buildOptions.outputPath);
|
|
183
183
|
const mappedLocationOfHost = `http${options.serveOptions.ssl ? 's' : ''}://${options.serveOptions.host}:${options.serveOptions.staticRemotesPort}/${hostUrlSegment}`;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { ExecutorContext } from '@nx/devkit';
|
|
2
|
-
import { ModuleFederationDevServerOptions } from '../../executors/module-federation-dev-server/schema';
|
|
3
|
-
import type { StaticRemotesConfig } from '@nx/module-federation/src/utils';
|
|
4
|
-
export declare function buildStaticRemotes(staticRemotesConfig: StaticRemotesConfig, nxBin: any, context: ExecutorContext, options: ModuleFederationDevServerOptions): Promise<Record<string, string>>;
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildStaticRemotes = buildStaticRemotes;
|
|
4
|
-
const fs_1 = require("fs");
|
|
5
|
-
const node_child_process_1 = require("node:child_process");
|
|
6
|
-
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
7
|
-
const logger_1 = require("nx/src/utils/logger");
|
|
8
|
-
const path_1 = require("path");
|
|
9
|
-
async function buildStaticRemotes(staticRemotesConfig, nxBin, context, options) {
|
|
10
|
-
if (!staticRemotesConfig.remotes.length) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
logger_1.logger.info(`NX Building ${staticRemotesConfig.remotes.length} static remotes...`);
|
|
14
|
-
const mappedLocationOfRemotes = {};
|
|
15
|
-
for (const app of staticRemotesConfig.remotes) {
|
|
16
|
-
mappedLocationOfRemotes[app] = `http${options.ssl ? 's' : ''}://${options.host}:${options.staticRemotesPort}/${staticRemotesConfig.config[app].urlSegment}`;
|
|
17
|
-
}
|
|
18
|
-
await new Promise((res, rej) => {
|
|
19
|
-
const staticProcess = (0, node_child_process_1.fork)(nxBin, [
|
|
20
|
-
'run-many',
|
|
21
|
-
`--target=build`,
|
|
22
|
-
`--projects=${staticRemotesConfig.remotes.join(',')}`,
|
|
23
|
-
...(context.configurationName
|
|
24
|
-
? [`--configuration=${context.configurationName}`]
|
|
25
|
-
: []),
|
|
26
|
-
...(options.parallel ? [`--parallel=${options.parallel}`] : []),
|
|
27
|
-
], {
|
|
28
|
-
cwd: context.root,
|
|
29
|
-
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
30
|
-
});
|
|
31
|
-
// File to debug build failures e.g. 2024-01-01T00_00_0_0Z-build.log'
|
|
32
|
-
const remoteBuildLogFile = (0, path_1.join)(cache_directory_1.workspaceDataDirectory,
|
|
33
|
-
// eslint-disable-next-line
|
|
34
|
-
`${new Date().toISOString().replace(/[:\.]/g, '_')}-build.log`);
|
|
35
|
-
const stdoutStream = (0, fs_1.createWriteStream)(remoteBuildLogFile);
|
|
36
|
-
staticProcess.stdout.on('data', (data) => {
|
|
37
|
-
const ANSII_CODE_REGEX =
|
|
38
|
-
// eslint-disable-next-line no-control-regex
|
|
39
|
-
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
|
40
|
-
const stdoutString = data.toString().replace(ANSII_CODE_REGEX, '');
|
|
41
|
-
stdoutStream.write(stdoutString);
|
|
42
|
-
// in addition to writing into the stdout stream, also show error directly in console
|
|
43
|
-
// so the error is easily discoverable. 'ERROR in' is the key word to search in webpack output.
|
|
44
|
-
if (stdoutString.includes('ERROR in')) {
|
|
45
|
-
logger_1.logger.log(stdoutString);
|
|
46
|
-
}
|
|
47
|
-
if (stdoutString.includes('Successfully ran target build')) {
|
|
48
|
-
staticProcess.stdout.removeAllListeners('data');
|
|
49
|
-
logger_1.logger.info(`NX Built ${staticRemotesConfig.remotes.length} static remotes`);
|
|
50
|
-
res();
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
staticProcess.stderr.on('data', (data) => logger_1.logger.info(data.toString()));
|
|
54
|
-
staticProcess.once('exit', (code) => {
|
|
55
|
-
stdoutStream.end();
|
|
56
|
-
staticProcess.stdout.removeAllListeners('data');
|
|
57
|
-
staticProcess.stderr.removeAllListeners('data');
|
|
58
|
-
if (code !== 0) {
|
|
59
|
-
rej(`Remote failed to start. A complete log can be found in: ${remoteBuildLogFile}`);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
res();
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
process.on('SIGTERM', () => staticProcess.kill('SIGTERM'));
|
|
66
|
-
process.on('exit', () => staticProcess.kill('SIGTERM'));
|
|
67
|
-
});
|
|
68
|
-
return mappedLocationOfRemotes;
|
|
69
|
-
}
|