This commit is contained in:
parent
fc58ef45d6
commit
c64f26ef3c
@ -107,7 +107,7 @@
|
|||||||
"skipRemotes": {
|
"skipRemotes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": { "type": "string" },
|
"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."
|
"description": "List of remote applications to not automatically serve, either statically or in development mode."
|
||||||
},
|
},
|
||||||
"pathToManifestFile": {
|
"pathToManifestFile": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@ -72,7 +72,7 @@
|
|||||||
"skipRemotes": {
|
"skipRemotes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": { "type": "string" },
|
"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."
|
"description": "List of remote applications to not automatically serve, either statically or in development mode."
|
||||||
},
|
},
|
||||||
"verbose": {
|
"verbose": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
"skipRemotes": {
|
"skipRemotes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": { "type": "string" },
|
"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.",
|
"description": "List of remote applications to not automatically serve, either statically or in development mode.",
|
||||||
"x-priority": "important"
|
"x-priority": "important"
|
||||||
},
|
},
|
||||||
"buildTarget": {
|
"buildTarget": {
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
"skipRemotes": {
|
"skipRemotes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": { "type": "string" },
|
"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.",
|
"description": "List of remote applications to not automatically serve, either statically or in development mode.",
|
||||||
"x-priority": "important"
|
"x-priority": "important"
|
||||||
},
|
},
|
||||||
"host": {
|
"host": {
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
import type { Schema } from './schema';
|
import type { Schema } from './schema';
|
||||||
import { readCachedProjectGraph, workspaceRoot, Workspaces } from '@nx/devkit';
|
import {
|
||||||
|
logger,
|
||||||
|
readCachedProjectGraph,
|
||||||
|
workspaceRoot,
|
||||||
|
Workspaces,
|
||||||
|
} from '@nx/devkit';
|
||||||
import { scheduleTarget } from 'nx/src/adapter/ngcli-adapter';
|
import { scheduleTarget } from 'nx/src/adapter/ngcli-adapter';
|
||||||
import { executeWebpackDevServerBuilder } from '../webpack-dev-server/webpack-dev-server.impl';
|
import { executeWebpackDevServerBuilder } from '../webpack-dev-server/webpack-dev-server.impl';
|
||||||
import { readProjectsConfigurationFromProjectGraph } from 'nx/src/project-graph/project-graph';
|
import { readProjectsConfigurationFromProjectGraph } from 'nx/src/project-graph/project-graph';
|
||||||
@ -51,6 +56,12 @@ export function executeModuleFederationDevServerBuilder(
|
|||||||
const remotesToSkip = new Set(
|
const remotesToSkip = new Set(
|
||||||
findMatchingProjects(options.skipRemotes, projectGraph.nodes) ?? []
|
findMatchingProjects(options.skipRemotes, projectGraph.nodes) ?? []
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (remotesToSkip.size > 0) {
|
||||||
|
logger.info(
|
||||||
|
`Remotes not served automatically: ${[...remotesToSkip].join(', ')}`
|
||||||
|
);
|
||||||
|
}
|
||||||
const staticRemotes = getStaticRemotes(
|
const staticRemotes = getStaticRemotes(
|
||||||
project,
|
project,
|
||||||
context,
|
context,
|
||||||
|
|||||||
@ -117,7 +117,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"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."
|
"description": "List of remote applications to not automatically serve, either statically or in development mode."
|
||||||
},
|
},
|
||||||
"pathToManifestFile": {
|
"pathToManifestFile": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@ -73,7 +73,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"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."
|
"description": "List of remote applications to not automatically serve, either statically or in development mode."
|
||||||
},
|
},
|
||||||
"verbose": {
|
"verbose": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json';
|
import { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { existsSync, readFileSync } from 'fs';
|
import { existsSync, readFileSync } from 'fs';
|
||||||
import { Remotes } from '@nx/devkit';
|
import { logger, Remotes } from '@nx/devkit';
|
||||||
|
|
||||||
export function getDynamicRemotes(
|
export function getDynamicRemotes(
|
||||||
project: ProjectConfiguration,
|
project: ProjectConfiguration,
|
||||||
@ -45,19 +45,26 @@ export function getDynamicRemotes(
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const dynamicRemotes = Object.entries(parsedManifest)
|
const allDynamicRemotes = Object.entries(parsedManifest)
|
||||||
.map(([remoteName]) => remoteName)
|
.map(([remoteName]) => remoteName)
|
||||||
.filter((r) => !remotesToSkip.has(r));
|
.filter((r) => !remotesToSkip.has(r));
|
||||||
const invalidDynamicRemotes = dynamicRemotes.filter(
|
|
||||||
(remote) => !workspaceProjects[remote]
|
const remotesNotInWorkspace: string[] = [];
|
||||||
);
|
|
||||||
if (invalidDynamicRemotes.length) {
|
const dynamicRemotes = allDynamicRemotes.filter((remote) => {
|
||||||
throw new Error(
|
if (!workspaceProjects[remote]) {
|
||||||
invalidDynamicRemotes.length === 1
|
remotesNotInWorkspace.push(remote);
|
||||||
? `Invalid dynamic remote configured in "${pathToManifestFile}": ${invalidDynamicRemotes[0]}.`
|
|
||||||
: `Invalid dynamic remotes configured in "${pathToManifestFile}": ${invalidDynamicRemotes.join(
|
return false;
|
||||||
', '
|
}
|
||||||
)}.`
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (remotesNotInWorkspace.length > 0) {
|
||||||
|
logger.warn(
|
||||||
|
`Skipping serving ${remotesNotInWorkspace.join(
|
||||||
|
', '
|
||||||
|
)} as they could not be found in the workspace. Ensure they are served correctly.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,22 +96,27 @@ export function getStaticRemotes(
|
|||||||
Array.isArray(mfeConfig.remotes) && mfeConfig.remotes.length > 0
|
Array.isArray(mfeConfig.remotes) && mfeConfig.remotes.length > 0
|
||||||
? mfeConfig.remotes
|
? mfeConfig.remotes
|
||||||
: [];
|
: [];
|
||||||
const staticRemotes = remotesConfig
|
const allStaticRemotes = remotesConfig
|
||||||
.map((remoteDefinition) =>
|
.map((remoteDefinition) =>
|
||||||
Array.isArray(remoteDefinition) ? remoteDefinition[0] : remoteDefinition
|
Array.isArray(remoteDefinition) ? remoteDefinition[0] : remoteDefinition
|
||||||
)
|
)
|
||||||
.filter((r) => !remotesToSkip.has(r));
|
.filter((r) => !remotesToSkip.has(r));
|
||||||
|
const remotesNotInWorkspace: string[] = [];
|
||||||
|
|
||||||
const invalidStaticRemotes = staticRemotes.filter(
|
const staticRemotes = allStaticRemotes.filter((remote) => {
|
||||||
(remote) => !workspaceProjects[remote]
|
if (!workspaceProjects[remote]) {
|
||||||
);
|
remotesNotInWorkspace.push(remote);
|
||||||
if (invalidStaticRemotes.length) {
|
|
||||||
throw new Error(
|
return false;
|
||||||
invalidStaticRemotes.length === 1
|
}
|
||||||
? `Invalid static remote configured in "${mfConfigPath}": ${invalidStaticRemotes[0]}.`
|
return true;
|
||||||
: `Invalid static remotes configured in "${mfConfigPath}": ${invalidStaticRemotes.join(
|
});
|
||||||
', '
|
|
||||||
)}.`
|
if (remotesNotInWorkspace.length > 0) {
|
||||||
|
logger.warn(
|
||||||
|
`Skipping serving ${remotesNotInWorkspace.join(
|
||||||
|
', '
|
||||||
|
)} as they could not be found in the workspace. Ensure they are served correctly.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@ import {
|
|||||||
findMatchingProjects,
|
findMatchingProjects,
|
||||||
getMatchingStringsWithCache,
|
getMatchingStringsWithCache,
|
||||||
} from './find-matching-projects';
|
} from './find-matching-projects';
|
||||||
import minimatch = require('minimatch');
|
|
||||||
import type { ProjectGraphProjectNode } from '../config/project-graph';
|
import type { ProjectGraphProjectNode } from '../config/project-graph';
|
||||||
|
import minimatch = require('minimatch');
|
||||||
|
|
||||||
describe('findMatchingProjects', () => {
|
describe('findMatchingProjects', () => {
|
||||||
let projectGraph: Record<string, ProjectGraphProjectNode> = {
|
let projectGraph: Record<string, ProjectGraphProjectNode> = {
|
||||||
|
|||||||
@ -39,12 +39,39 @@ export default async function* moduleFederationDevServer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const remotesToSkip = new Set(
|
const remotesToSkip = new Set(
|
||||||
findMatchingProjects(options.skipRemotes ?? [], context.projectGraph.nodes)
|
findMatchingProjects(options.skipRemotes, context.projectGraph.nodes) ?? []
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (remotesToSkip.size > 0) {
|
||||||
|
logger.info(
|
||||||
|
`Remotes not served automatically: ${[...remotesToSkip.values()].join(
|
||||||
|
', '
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const remotesNotInWorkspace: string[] = [];
|
||||||
|
|
||||||
const knownRemotes = (moduleFederationConfig.remotes ?? []).filter((r) => {
|
const knownRemotes = (moduleFederationConfig.remotes ?? []).filter((r) => {
|
||||||
const validRemote = Array.isArray(r) ? r[0] : r;
|
const validRemote = Array.isArray(r) ? r[0] : r;
|
||||||
return !remotesToSkip.has(validRemote);
|
|
||||||
|
if (remotesToSkip.has(validRemote)) {
|
||||||
|
return false;
|
||||||
|
} else if (!context.projectGraph.nodes[validRemote]) {
|
||||||
|
remotesNotInWorkspace.push(validRemote);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (remotesNotInWorkspace.length > 0) {
|
||||||
|
logger.warn(
|
||||||
|
`Skipping serving ${remotesNotInWorkspace.join(
|
||||||
|
', '
|
||||||
|
)} as they could not be found in the workspace. Ensure they are served correctly.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const remotePorts = knownRemotes.map(
|
const remotePorts = knownRemotes.map(
|
||||||
(r) => context.projectGraph.nodes[r].data.targets['serve'].options.port
|
(r) => context.projectGraph.nodes[r].data.targets['serve'].options.port
|
||||||
);
|
);
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"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.",
|
"description": "List of remote applications to not automatically serve, either statically or in development mode.",
|
||||||
"x-priority": "important"
|
"x-priority": "important"
|
||||||
},
|
},
|
||||||
"buildTarget": {
|
"buildTarget": {
|
||||||
|
|||||||
@ -46,9 +46,27 @@ export default async function* moduleFederationSsrDevServer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const remotesToSkip = new Set(options.skipRemotes ?? []);
|
const remotesToSkip = new Set(options.skipRemotes ?? []);
|
||||||
const knownRemotes = (moduleFederationConfig.remotes ?? []).filter(
|
const remotesNotInWorkspace: string[] = [];
|
||||||
(r) => !remotesToSkip.has(r)
|
const knownRemotes = (moduleFederationConfig.remotes ?? []).filter((r) => {
|
||||||
);
|
const validRemote = Array.isArray(r) ? r[0] : r;
|
||||||
|
|
||||||
|
if (remotesToSkip.has(validRemote)) {
|
||||||
|
return false;
|
||||||
|
} else if (!context.projectGraph.nodes[validRemote]) {
|
||||||
|
remotesNotInWorkspace.push(validRemote);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (remotesNotInWorkspace.length > 0) {
|
||||||
|
logger.warn(
|
||||||
|
`Skipping serving ${remotesNotInWorkspace.join(
|
||||||
|
', '
|
||||||
|
)} as they could not be found in the workspace. Ensure they are served correctly.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const devServeApps = !options.devRemotes
|
const devServeApps = !options.devRemotes
|
||||||
? []
|
? []
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"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.",
|
"description": "List of remote applications to not automatically serve, either statically or in development mode.",
|
||||||
"x-priority": "important"
|
"x-priority": "important"
|
||||||
},
|
},
|
||||||
"host": {
|
"host": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user