feat(angular): init mfe generator (#6209)

Add generator to scaffold Module Federation configuration for a given Angular application
This commit is contained in:
Colum Ferry 2021-07-02 13:45:36 +01:00 committed by GitHub
parent 80d3999d42
commit dd51c18d12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 764 additions and 2 deletions

View File

@ -0,0 +1,59 @@
# setup-mfe
Generate a Module Federation configuration for a given Angular application.
## Usage
```bash
nx generate setup-mfe ...
```
By default, Nx will search for `setup-mfe` in the default collection provisioned in `angular.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/angular:setup-mfe ...
```
Show what will be generated without writing to disk:
```bash
nx g setup-mfe ... --dry-run
```
## Options
### appName
Type: `string`
The name of the application to generate the Module Federation configuration for.
### mfeType
Default: `shell`
Type: `string`
Possible values: `shell`, `remote`
Type of application to generate the Module Federation configuration for.
### port
Type: `number`
The port at which the remote application should be served.
### remotes
Type: `array`
A list of remote application names that the shell application should consume.
### skipFormat
Type: `boolean`
Skip formatting the workspace after the generator completes.

View File

@ -1031,6 +1031,8 @@ Reads a project configuration.
The project configuration is stored in workspace.json and nx.json. The utility will read The project configuration is stored in workspace.json and nx.json. The utility will read
both files. both files.
**`throws`** If supplied projectName cannot be found
#### Parameters #### Parameters
| Name | Type | Description | | Name | Type | Description |

View File

@ -422,6 +422,11 @@
"id": "ngrx", "id": "ngrx",
"file": "angular/api-angular/generators/ngrx" "file": "angular/api-angular/generators/ngrx"
}, },
{
"name": "setup-mfe generator",
"id": "setup-mfe",
"file": "angular/api-angular/generators/setup-mfe"
},
{ {
"name": "stories generator", "name": "stories generator",
"id": "stories", "id": "stories",
@ -1558,6 +1563,11 @@
"id": "ngrx", "id": "ngrx",
"file": "react/api-angular/generators/ngrx" "file": "react/api-angular/generators/ngrx"
}, },
{
"name": "setup-mfe generator",
"id": "setup-mfe",
"file": "react/api-angular/generators/setup-mfe"
},
{ {
"name": "stories generator", "name": "stories generator",
"id": "stories", "id": "stories",
@ -2658,6 +2668,11 @@
"id": "ngrx", "id": "ngrx",
"file": "node/api-angular/generators/ngrx" "file": "node/api-angular/generators/ngrx"
}, },
{
"name": "setup-mfe generator",
"id": "setup-mfe",
"file": "node/api-angular/generators/setup-mfe"
},
{ {
"name": "stories generator", "name": "stories generator",
"id": "stories", "id": "stories",

View File

@ -0,0 +1,59 @@
# setup-mfe
Generate a Module Federation configuration for a given Angular application.
## Usage
```bash
nx generate setup-mfe ...
```
By default, Nx will search for `setup-mfe` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/angular:setup-mfe ...
```
Show what will be generated without writing to disk:
```bash
nx g setup-mfe ... --dry-run
```
## Options
### appName
Type: `string`
The name of the application to generate the Module Federation configuration for.
### mfeType
Default: `shell`
Type: `string`
Possible values: `shell`, `remote`
Type of application to generate the Module Federation configuration for.
### port
Type: `number`
The port at which the remote application should be served.
### remotes
Type: `array`
A list of remote application names that the shell application should consume.
### skipFormat
Type: `boolean`
Skip formatting the workspace after the generator completes.

View File

@ -1031,6 +1031,8 @@ Reads a project configuration.
The project configuration is stored in workspace.json and nx.json. The utility will read The project configuration is stored in workspace.json and nx.json. The utility will read
both files. both files.
**`throws`** If supplied projectName cannot be found
#### Parameters #### Parameters
| Name | Type | Description | | Name | Type | Description |

View File

@ -0,0 +1,59 @@
# setup-mfe
Generate a Module Federation configuration for a given Angular application.
## Usage
```bash
nx generate setup-mfe ...
```
By default, Nx will search for `setup-mfe` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/angular:setup-mfe ...
```
Show what will be generated without writing to disk:
```bash
nx g setup-mfe ... --dry-run
```
## Options
### appName
Type: `string`
The name of the application to generate the Module Federation configuration for.
### mfeType
Default: `shell`
Type: `string`
Possible values: `shell`, `remote`
Type of application to generate the Module Federation configuration for.
### port
Type: `number`
The port at which the remote application should be served.
### remotes
Type: `array`
A list of remote application names that the shell application should consume.
### skipFormat
Type: `boolean`
Skip formatting the workspace after the generator completes.

View File

@ -1031,6 +1031,8 @@ Reads a project configuration.
The project configuration is stored in workspace.json and nx.json. The utility will read The project configuration is stored in workspace.json and nx.json. The utility will read
both files. both files.
**`throws`** If supplied projectName cannot be found
#### Parameters #### Parameters
| Name | Type | Description | | Name | Type | Description |

View File

@ -122,6 +122,7 @@ myorg/
- [library](/{{framework}}/angular/library) - Creates an Angular library. - [library](/{{framework}}/angular/library) - Creates an Angular library.
- [move](/{{framework}}/angular/move) - Moves an Angular application or library to another folder within the workspace and updates the project configuration. - [move](/{{framework}}/angular/move) - Moves an Angular application or library to another folder within the workspace and updates the project configuration.
- [ngrx](/{{framework}}/angular/ngrx) - Adds NgRx support to an application or library. - [ngrx](/{{framework}}/angular/ngrx) - Adds NgRx support to an application or library.
- [setup-mfe](/{{framework}}/angular/setup-mfe) - Generate a Module Federation configuration for a given Angular application.
- [stories](/{{framework}}/angular/stories) - Creates stories/specs for all components declared in a project. - [stories](/{{framework}}/angular/stories) - Creates stories/specs for all components declared in a project.
- [storybook-configuration](/{{framework}}/angular/storybook-configuration) - Adds Storybook configuration to a project. - [storybook-configuration](/{{framework}}/angular/storybook-configuration) - Adds Storybook configuration to a project.
- [storybook-migrate-defaults-5-to-6](/{{framework}}/angular/storybook-migrate-defaults-5-to-6) - Generates default Storybook configuration files using Storybook version >=6.x specs, for projects that already have Storybook instances and configurations of versions <6.x. - [storybook-migrate-defaults-5-to-6](/{{framework}}/angular/storybook-migrate-defaults-5-to-6) - Generates default Storybook configuration files using Storybook version >=6.x specs, for projects that already have Storybook instances and configurations of versions <6.x.

View File

@ -84,7 +84,6 @@
"@storybook/angular": "~6.3.0", "@storybook/angular": "~6.3.0",
"@storybook/core": "~6.3.0", "@storybook/core": "~6.3.0",
"@storybook/react": "~6.3.0", "@storybook/react": "~6.3.0",
"@svgr/webpack": "^5.4.0",
"@svgr/webpack": "5.5.0", "@svgr/webpack": "5.5.0",
"@tailwindcss/typography": "^0.4.0", "@tailwindcss/typography": "^0.4.0",
"@testing-library/react": "11.2.5", "@testing-library/react": "11.2.5",
@ -279,4 +278,4 @@
"ng-packagr/rxjs": "6.6.7", "ng-packagr/rxjs": "6.6.7",
"**/xmlhttprequest-ssl": "~1.6.2" "**/xmlhttprequest-ssl": "~1.6.2"
} }
} }

View File

@ -96,6 +96,13 @@
"schema": "./src/generators/upgrade-module/schema.json", "schema": "./src/generators/upgrade-module/schema.json",
"description": "Sets up an Upgrade Module." "description": "Sets up an Upgrade Module."
}, },
"setup-mfe": {
"factory": "./src/generators/setup-mfe/compat",
"schema": "./src/generators/setup-mfe/schema.json",
"description": "Generate a Module Federation configuration for a given Angular application."
},
"web-worker": { "web-worker": {
"factory": "./src/generators/web-worker/compat", "factory": "./src/generators/web-worker/compat",
"schema": "./src/generators/web-worker/schema.json", "schema": "./src/generators/web-worker/schema.json",
@ -115,6 +122,11 @@
"aliases": ["app"], "aliases": ["app"],
"description": "Creates an Angular application." "description": "Creates an Angular application."
}, },
"setup-mfe": {
"factory": "./src/generators/setup-mfe/setup-mfe",
"schema": "./src/generators/setup-mfe/schema.json",
"description": "Generate a Module Federation configuration for a given Angular application."
},
"component-cypress-spec": { "component-cypress-spec": {
"factory": "./src/generators/component-cypress-spec/component-cypress-spec", "factory": "./src/generators/component-cypress-spec/component-cypress-spec",
"schema": "./src/generators/component-cypress-spec/schema.json", "schema": "./src/generators/component-cypress-spec/schema.json",

View File

@ -11,3 +11,4 @@ export * from './src/generators/storybook-configuration/storybook-configuration'
export * from './src/generators/storybook-migrate-defaults-5-to-6/storybook-migrate-defaults-5-to-6'; export * from './src/generators/storybook-migrate-defaults-5-to-6/storybook-migrate-defaults-5-to-6';
export * from './src/generators/storybook-migrate-stories-to-6-2/migrate-stories-to-6-2'; export * from './src/generators/storybook-migrate-stories-to-6-2/migrate-stories-to-6-2';
export * from './src/generators/upgrade-module/upgrade-module'; export * from './src/generators/upgrade-module/upgrade-module';
export * from './src/generators/setup-mfe/setup-mfe';

View File

@ -0,0 +1,89 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Init MFE should create webpack configs correctly 1`] = `
"const ModuleFederationPlugin = require(\\"webpack/lib/container/ModuleFederationPlugin\\");
const mf = require(\\"@angular-architects/module-federation/webpack\\");
const path = require(\\"path\\");
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(path.join(__dirname, \\"../../tsconfig.base.json\\"), [
/* mapped paths to share */
]);
module.exports = {
output: {
uniqueName: \\"app1\\",
publicPath: \\"auto\\",
},
optimization: {
runtimeChunk: false,
minimize: false,
},
resolve: {
alias: {
...sharedMappings.getAliases(),
},
},
plugins: [
new ModuleFederationPlugin({
remotes: {
},
shared: {
\\"@angular/core\\": { singleton: true, strictVersion: true },
\\"@angular/common\\": { singleton: true, strictVersion: true },
\\"@angular/common/http\\": { singleton: true, strictVersion: true },
\\"@angular/router\\": { singleton: true, strictVersion: true },
...sharedMappings.getDescriptors(),
},
}),
sharedMappings.getPlugin(),
],
};
"
`;
exports[`Init MFE should create webpack configs correctly 2`] = `
"const ModuleFederationPlugin = require(\\"webpack/lib/container/ModuleFederationPlugin\\");
const mf = require(\\"@angular-architects/module-federation/webpack\\");
const path = require(\\"path\\");
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(path.join(__dirname, \\"../../tsconfig.base.json\\"), [
/* mapped paths to share */
]);
module.exports = {
output: {
uniqueName: \\"remote1\\",
publicPath: \\"auto\\",
},
optimization: {
runtimeChunk: false,
minimize: false,
},
resolve: {
alias: {
...sharedMappings.getAliases(),
},
},
plugins: [
new ModuleFederationPlugin({
name: \\"remote1\\",
filename: \\"remoteEntry.js\\",
exposes: {
'./Component': 'apps/remote1/src/app/app.component.ts',
},
shared: {
\\"@angular/core\\": { singleton: true, strictVersion: true },
\\"@angular/common\\": { singleton: true, strictVersion: true },
\\"@angular/common/http\\": { singleton: true, strictVersion: true },
\\"@angular/router\\": { singleton: true, strictVersion: true },
...sharedMappings.getDescriptors(),
},
}),
sharedMappings.getPlugin(),
],
};
"
`;

View File

@ -0,0 +1,41 @@
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(path.join(__dirname, "../../tsconfig.base.json"), [
/* mapped paths to share */
]);
module.exports = {
output: {
uniqueName: "<%= name %>",
publicPath: "auto",
},
optimization: {
runtimeChunk: false,
minimize: false,
},
resolve: {
alias: {
...sharedMappings.getAliases(),
},
},
plugins: [
new ModuleFederationPlugin({<% if(type === 'remote') { %>
name: "<%= name %>",
filename: "remoteEntry.js",
exposes: {
'./Component': '<%= sourceRoot %>/src/app/app.component.ts',
},<% } %><% if(type === 'shell') { %>
remotes: {
<% remotes.forEach(function(remote) { %>"<%= remote.remoteName %>": "<%= remote.remoteName %>@http://localhost:<%= remote.port %>/remoteEntry.js",<% }); %>
},<% } %>
shared: {<% sharedLibraries.forEach(function (lib) { %>
"<%= lib %>": { singleton: true, strictVersion: true },<% }); %>
...sharedMappings.getDescriptors(),
},
}),
sharedMappings.getPlugin(),
],
};

View File

@ -0,0 +1 @@
module.exports = require('./webpack.config');

View File

@ -0,0 +1,23 @@
import type { Tree } from '@nrwl/devkit';
import type { Schema } from '../schema';
import {
readProjectConfiguration,
updateProjectConfiguration,
} from '@nrwl/devkit';
export function addImplicitDeps(host: Tree, options: Schema) {
if (
options.mfeType === 'shell' &&
Array.isArray(options.remotes) &&
options.remotes.length > 0
) {
const appConfig = readProjectConfiguration(host, options.appName);
appConfig.implicitDependencies = Array.isArray(
appConfig.implicitDependencies
)
? [...appConfig.implicitDependencies, ...options.remotes]
: [...options.remotes];
updateProjectConfiguration(host, options.appName, appConfig);
}
}

View File

@ -0,0 +1,28 @@
import type { Tree } from '@nrwl/devkit';
import type { Schema } from '../schema';
import {
readProjectConfiguration,
updateProjectConfiguration,
} from '@nrwl/devkit';
export function changeBuildTarget(host: Tree, options: Schema) {
const appConfig = readProjectConfiguration(host, options.appName);
appConfig.targets.build.executor = '@nrwl/angular:webpack-browser';
appConfig.targets.build.options = {
...appConfig.targets.build.options,
customWebpackConfig: {
path: `${appConfig.root}/webpack.config.js`,
},
};
appConfig.targets.build.configurations.production = {
...appConfig.targets.build.configurations.production,
customWebpackConfig: {
path: `${appConfig.root}/webpack.prod.config.js`,
},
};
updateProjectConfiguration(host, options.appName, appConfig);
}

View File

@ -0,0 +1,15 @@
import type { Tree } from '@nrwl/devkit';
import type { Schema } from '../schema';
import { joinPathFragments } from '@nrwl/devkit';
export function fixBootstrap(host: Tree, appRoot: string) {
const mainFilePath = joinPathFragments(appRoot, 'src/main.ts');
const bootstrapCode = host.read(mainFilePath, 'utf-8');
host.write(joinPathFragments(appRoot, 'src/bootstrap.ts'), bootstrapCode);
host.write(
mainFilePath,
`import('./bootstrap').catch(err => console.error(err));`
);
}

View File

@ -0,0 +1,35 @@
import type { Tree } from '@nrwl/devkit';
import type { Schema } from '../schema';
import { generateFiles, joinPathFragments, logger } from '@nrwl/devkit';
const SHARED_SINGLETON_LIBRARIES = [
'@angular/core',
'@angular/common',
'@angular/common/http',
'@angular/router',
];
export function generateWebpackConfig(
host: Tree,
options: Schema,
appRoot: string,
remotesWithPorts: { remoteName: string; port: number }[]
) {
if (
host.exists(`${appRoot}/webpack.config.js`) ||
host.exists(`${appRoot}/webpack.prod.config.js`)
) {
logger.warn(
`NOTE: We encountered an existing webpack config for the app ${options.appName}. We have overwritten this file with the Module Federation Config.\n
If this was not the outcome you expected, you can discard the changes we have made, create a backup of your current webpack config, and run the command again.`
);
}
generateFiles(host, joinPathFragments(__dirname, '../files'), appRoot, {
tmpl: '',
type: options.mfeType,
name: options.appName,
remotes: remotesWithPorts ?? [],
sourceRoot: appRoot,
sharedLibraries: SHARED_SINGLETON_LIBRARIES,
});
}

View File

@ -0,0 +1,23 @@
import type { Tree } from '@nrwl/devkit';
import type { Schema } from '../schema';
import { readProjectConfiguration } from '@nrwl/devkit';
export function getRemotesWithPorts(host: Tree, options: Schema) {
// If type is shell and remotes supplied, check remotes exist
const remotesWithPort: { remoteName: string; port: number }[] = [];
if (
options.mfeType === 'shell' &&
Array.isArray(options.remotes) &&
options.remotes.length > 0
) {
for (const remote of options.remotes) {
const remoteConfig = readProjectConfiguration(host, remote);
remotesWithPort.push({
remoteName: remote,
port: remoteConfig.targets['mfe-serve']?.options.port ?? 4200,
});
}
}
return remotesWithPort;
}

View File

@ -0,0 +1,6 @@
export * from './add-implicit-deps';
export * from './change-build-target';
export * from './fix-bootstrap';
export * from './generate-config';
export * from './get-remotes-with-ports';
export * from './setup-serve-target';

View File

@ -0,0 +1,25 @@
import type { Tree } from '@nrwl/devkit';
import type { Schema } from '../schema';
import {
readProjectConfiguration,
updateProjectConfiguration,
} from '@nrwl/devkit';
export function setupServeTarget(host: Tree, options: Schema) {
if (options.mfeType === 'remote') {
const appConfig = readProjectConfiguration(host, options.appName);
const port = options.port ?? 4200;
appConfig.targets['mfe-serve'] = {
executor: '@nrwl/workspace:run-commands',
options: {
command: `nx serve ${options.appName}`,
port,
},
};
updateProjectConfiguration(host, options.appName, appConfig);
}
}

View File

@ -0,0 +1,7 @@
export interface Schema {
appName: string;
mfeType: 'shell' | 'remote';
port?: number;
remotes?: string[];
skipFormat?: boolean;
}

View File

@ -0,0 +1,39 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "GeneratorAngularMFESetup",
"cli": "nx",
"title": "Generate Module Federation Setup for Angular App",
"description": "Create Module Federation configuration files for given Angular Application.",
"type": "object",
"properties": {
"appName": {
"type": "string",
"description": "The name of the application to generate the Module Federation configuration for.",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What app would you like to generate a Module Federation configuration for?"
},
"mfeType": {
"type": "string",
"enum": ["shell", "remote"],
"description": "Type of application to generate the Module Federation configuration for.",
"default": "shell"
},
"port": {
"type": "number",
"description": "The port at which the remote application should be served."
},
"remotes": {
"type": "array",
"description": "A list of remote application names that the shell application should consume."
},
"skipFormat": {
"type": "boolean",
"description": "Skip formatting the workspace after the generator completes."
}
},
"required": ["appName", "mfeType"],
"additionalProperties": false
}

View File

@ -0,0 +1,4 @@
import { convertNxGenerator } from '@nrwl/devkit';
import { setupMfe } from './setup-mfe';
export default convertNxGenerator(setupMfe);

View File

@ -0,0 +1,167 @@
import type { NxJsonConfiguration, Tree } from '@nrwl/devkit';
import { readJson, readProjectConfiguration } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { setupMfe } from './setup-mfe';
import applicationGenerator from '../application/application';
describe('Init MFE', () => {
let host: Tree;
beforeEach(async () => {
host = createTreeWithEmptyWorkspace();
await applicationGenerator(host, {
name: 'app1',
});
await applicationGenerator(host, {
name: 'remote1',
});
});
test.each([
['app1', 'shell'],
['remote1', 'remote'],
])(
'should create webpack configs correctly',
async (app, type: 'shell' | 'remote') => {
// ACT
await setupMfe(host, {
appName: app,
mfeType: type,
});
// ASSERT
expect(host.exists(`apps/${app}/webpack.config.js`)).toBeTruthy();
expect(host.exists(`apps/${app}/webpack.prod.config.js`)).toBeTruthy();
const webpackContetnts = host.read(
`apps/${app}/webpack.config.js`,
'utf-8'
);
expect(webpackContetnts).toMatchSnapshot();
}
);
test.each([
['app1', 'shell'],
['remote1', 'remote'],
])(
'create bootstrap file with the contents of main.ts',
async (app, type: 'shell' | 'remote') => {
// ARRANGE
const mainContents = host.read(`apps/${app}/src/main.ts`, 'utf-8');
// ACT
await setupMfe(host, {
appName: app,
mfeType: type,
});
// ASSERT
const bootstrapContents = host.read(
`apps/${app}/src/bootstrap.ts`,
'utf-8'
);
const updatedMainContents = host.read(`apps/${app}/src/main.ts`, 'utf-8');
expect(bootstrapContents).toEqual(mainContents);
expect(updatedMainContents).not.toEqual(mainContents);
}
);
test.each([
['app1', 'shell'],
['remote1', 'remote'],
])(
'should alter main.ts to import the bootstrap file dynamically',
async (app, type: 'shell' | 'remote') => {
// ARRANGE
const mainContents = host.read(`apps/${app}/src/main.ts`, 'utf-8');
// ACT
await setupMfe(host, {
appName: app,
mfeType: type,
});
// ASSERT
const updatedMainContents = host.read(`apps/${app}/src/main.ts`, 'utf-8');
expect(updatedMainContents).toEqual(
`import('./bootstrap').catch(err => console.error(err));`
);
expect(updatedMainContents).not.toEqual(mainContents);
}
);
test.each([
['app1', 'shell'],
['remote1', 'remote'],
])(
'should change the build target and set correct path to webpack config',
async (app, type: 'shell' | 'remote') => {
// ACT
await setupMfe(host, {
appName: app,
mfeType: type,
});
// ASSERT
const { build } = readProjectConfiguration(host, app).targets;
expect(build.executor).toEqual('@nrwl/angular:webpack-browser');
expect(build.options.customWebpackConfig.path).toEqual(
`apps/${app}/webpack.config.js`
);
}
);
test.each([
['app1', 'shell'],
['remote1', 'remote'],
])(
'should install @angular-architects/module-federation in the monorepo',
async (app, type: 'shell' | 'remote') => {
// ACT
await setupMfe(host, {
appName: app,
mfeType: type,
});
// ASSERT
const { dependencies } = readJson(host, 'package.json');
expect(
dependencies['@angular-architects/module-federation']
).toBeTruthy();
}
);
it('should add the remote config to the shell when --remotes flag supplied', async () => {
// ACT
await setupMfe(host, {
appName: 'app1',
mfeType: 'shell',
remotes: ['remote1'],
});
// ASSERT
const webpackContents = host.read(`apps/app1/webpack.config.js`, 'utf-8');
expect(webpackContents).toContain(
'"remote1": "remote1@http://localhost:4200/remoteEntry.js"'
);
});
it('should update the implicit dependencies of the shell when --remotes flag supplied', async () => {
// ACT
await setupMfe(host, {
appName: 'app1',
mfeType: 'shell',
remotes: ['remote1'],
});
// ASSERT
const nxJson: NxJsonConfiguration = readJson(host, 'nx.json');
expect(nxJson.projects['app1'].implicitDependencies).toContain('remote1');
});
});

View File

@ -0,0 +1,47 @@
import type { Tree } from '@nrwl/devkit';
import type { Schema } from './schema';
import {
readProjectConfiguration,
addDependenciesToPackageJson,
formatFiles,
} from '@nrwl/devkit';
import {
addImplicitDeps,
changeBuildTarget,
fixBootstrap,
generateWebpackConfig,
getRemotesWithPorts,
setupServeTarget,
} from './lib';
export async function setupMfe(host: Tree, options: Schema) {
const projectConfig = readProjectConfiguration(host, options.appName);
const remotesWithPorts = getRemotesWithPorts(host, options);
generateWebpackConfig(host, options, projectConfig.root, remotesWithPorts);
addImplicitDeps(host, options);
changeBuildTarget(host, options);
setupServeTarget(host, options);
fixBootstrap(host, projectConfig.root);
// add package to install
const installPackages = addDependenciesToPackageJson(
host,
{ '@angular-architects/module-federation': '^12.2.0' },
{}
);
// format files
if (!options.skipFormat) {
await formatFiles(host);
}
return installPackages;
}
export default setupMfe;

View File

@ -151,6 +151,7 @@ export function updateWorkspaceConfiguration(
* *
* @param host - the file system tree * @param host - the file system tree
* @param projectName - unique name. Often directories are part of the name (e.g., mydir-mylib) * @param projectName - unique name. Often directories are part of the name (e.g., mydir-mylib)
* @throws If supplied projectName cannot be found
*/ */
export function readProjectConfiguration( export function readProjectConfiguration(
host: Tree, host: Tree,