Skip to content

Commit

Permalink
WIP:feat(angular): add an option to set custom mf config path
Browse files Browse the repository at this point in the history
added an option to make the module-federation-dev-server and ssr builder accept a custom path for the module federation config file.

Closes nrwl#15739
  • Loading branch information
Giuseppe Ettorre committed Mar 28, 2023
1 parent 9dbc90d commit 4c54add
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,39 @@ export function executeModuleFederationDevServerBuilder(
pathToManifestFile = userPathToManifestFile;
}

let pathToModuleFederationConfigFile = join(
context.workspaceRoot,
project.sourceRoot,
'module-federation.config.js'
);

if(options.moduleFederationConfigOptions){
const userPathToModuleFederationConfigFile = join(
context.workspaceRoot,
options.moduleFederationConfigOptions.path
);
if (!existsSync(userPathToModuleFederationConfigFile)) {
throw new Error(
`The provided Module Federation config file path does not exist. Please check the file exists at "${userPathToModuleFederationConfigFile}".`
);
} else if (extname(options.moduleFederationConfigOptions) !== '.js' || extname(options.moduleFederationConfigOptions) !== '.ts') {
throw new Error(
`The Module Federation config file must be a JS or TS file. Please ensure the file at ${userPathToModuleFederationConfigFile} is a JS or TS file.`
);
}

pathToModuleFederationConfigFile = userPathToModuleFederationConfigFile;
}

validateDevRemotes(options, workspaceProjects);

const remotesToSkip = new Set(options.skipRemotes ?? []);
const staticRemotes = getStaticRemotes(
project,
context,
workspaceProjects,
remotesToSkip
remotesToSkip,
pathToModuleFederationConfigFile
);
const dynamicRemotes = getDynamicRemotes(
project,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ export interface Schema {
devRemotes?: string[];
skipRemotes?: string[];
pathToManifestFile?: string;
moduleFederationConfigOptions?: { path: string };
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@
"pathToManifestFile": {
"type": "string",
"description": "Path to a Module Federation manifest file (e.g. `my/path/to/module-federation.manifest.json`) containing the dynamic remote applications relative to the workspace root."
},
"moduleFederationConfigOptions": {
"type": "object",
"description": "Custom Module Federation configuration to be used instead of the default configuration generated by the builder. This can be useful for multi-repository module federation setups where the host application uses a remote application from an external repository.",
"properties": {
"path": { "type": "string" }
}
}
},
"additionalProperties": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,39 @@ export function executeModuleFederationDevSSRBuilder(
pathToManifestFile = userPathToManifestFile;
}

let pathToModuleFederationConfigFile = join(
context.workspaceRoot,
project.sourceRoot,
'module-federation.config.js'
);

if(options.moduleFederationConfigOptions){
const userPathToModuleFederationConfigFile = join(
context.workspaceRoot,
options.moduleFederationConfigOptions.path
);
if (!existsSync(userPathToModuleFederationConfigFile)) {
throw new Error(
`The provided Module Federation config file path does not exist. Please check the file exists at "${userPathToModuleFederationConfigFile}".`
);
} else if (extname(options.moduleFederationConfigOptions) !== '.js' || extname(options.moduleFederationConfigOptions) !== '.ts') {
throw new Error(
`The Module Federation config file must be a JS or TS file. Please ensure the file at ${userPathToModuleFederationConfigFile} is a JS or TS file.`
);
}

pathToModuleFederationConfigFile = userPathToModuleFederationConfigFile;
}

validateDevRemotes(options, workspaceProjects);

const remotesToSkip = new Set(options.skipRemotes ?? []);
const staticRemotes = getStaticRemotes(
project,
context,
workspaceProjects,
remotesToSkip
remotesToSkip,
pathToModuleFederationConfigFile
);
const dynamicRemotes = getDynamicRemotes(
project,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export interface Schema {
skipRemotes?: string[];
verbose: boolean;
pathToManifestFile?: string;
moduleFederationConfigOptions?: { path: string }
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@
"pathToManifestFile": {
"type": "string",
"description": "Path to a Module Federation manifest file (e.g. `my/path/to/module-federation.manifest.json`) containing the dynamic remote applications relative to the workspace root."
},
"moduleFederationConfigOptions": {
"type": "object",
"description": "Custom Module Federation configuration to be used instead of the default configuration generated by the builder. This can be useful for multi-repository module federation setups where the host application uses a remote application from an external repository.",
"properties": {
"path": { "type": "string" }
}
}
},
"additionalProperties": false,
Expand Down
18 changes: 9 additions & 9 deletions packages/angular/src/builders/utilities/module-federation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,20 @@ export function getStaticRemotes(
project: ProjectConfiguration,
context: import('@angular-devkit/architect').BuilderContext,
workspaceProjects: Record<string, ProjectConfiguration>,
remotesToSkip: Set<string>
): string[] {
const mfConfigPath = join(
remotesToSkip: Set<string>,
pathToModuleFederationConfigFile = join(
context.workspaceRoot,
project.root,
project.sourceRoot,
'module-federation.config.js'
);
)
): string[] {

let mfeConfig: { remotes: Remotes };
try {
mfeConfig = require(mfConfigPath);
mfeConfig = require(pathToModuleFederationConfigFile);
} catch {
throw new Error(
`Could not load ${mfConfigPath}. Was this project generated with "@nrwl/angular:host"?`
`Could not load ${pathToModuleFederationConfigFile}. Was this project generated with "@nrwl/angular:host"?`
);
}

Expand All @@ -101,8 +101,8 @@ export function getStaticRemotes(
if (invalidStaticRemotes.length) {
throw new Error(
invalidStaticRemotes.length === 1
? `Invalid static remote configured in "${mfConfigPath}": ${invalidStaticRemotes[0]}.`
: `Invalid static remotes configured in "${mfConfigPath}": ${invalidStaticRemotes.join(
? `Invalid static remote configured in "${pathToModuleFederationConfigFile}": ${invalidStaticRemotes[0]}.`
: `Invalid static remotes configured in "${pathToModuleFederationConfigFile}": ${invalidStaticRemotes.join(
', '
)}.`
);
Expand Down

0 comments on commit 4c54add

Please sign in to comment.