Skip to content

Commit 115e717

Browse files
docs: add framework content only (#2378)
Co-authored-by: ScriptedAlchemy <[email protected]> Co-authored-by: Hanric <[email protected]>
1 parent 4c2edbf commit 115e717

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+6634
-0
lines changed

apps/website-new/docs/en/_meta.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"link": "/guide/start/",
55
"activeMatch": "/guide/"
66
},
7+
{
8+
"text": "Practice",
9+
"link": "/practice/overview",
10+
"activeMatch": "/practice/"
11+
},
712
{
813
"text": "Configuration",
914
"link": "/configure/",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"type": "file",
4+
"name": "overview",
5+
"label": "overview"
6+
},
7+
{
8+
"type": "dir",
9+
"name": "frameworks",
10+
"label": "frameworks"
11+
},
12+
{
13+
"type": "file",
14+
"name": "scenario",
15+
"label": "scenario"
16+
}
17+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"type": "file",
4+
"name": "index",
5+
"label": "Framework Overview"
6+
},
7+
{
8+
"type": "dir",
9+
"name": "react",
10+
"label": "React"
11+
},
12+
{
13+
"type": "dir",
14+
"name": "next",
15+
"label": "Next.js"
16+
},
17+
{
18+
"type": "dir",
19+
"name": "angular",
20+
"label": "Angular"
21+
}
22+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
"angular-cli",
3+
"angular-mfe",
4+
"mf-ssr-angular",
5+
"service-workers-mf",
6+
"auth0",
7+
"okta-auth",
8+
"splitting-to-mf-part1",
9+
"splitting-to-mf-part2"
10+
]
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
import { Steps, Tab, Tabs, Badge, Aside } from '@theme';
2+
3+
4+
# Angular CLI Setup
5+
6+
This guide explains how to integrate Module Federation with Angular CLI. The `@angular-architects/module-federation` plugin is used to assist with this integration.
7+
8+
## Prerequisites
9+
10+
- **Angular CLI**: Version 10 or higher.
11+
- **Plugin Installation**: Install the `@angular-architects/module-federation` plugin.
12+
13+
## Installation
14+
15+
16+
To start, configure the Angular CLI to use Module Federation during the build phase.
17+
A custom builder is needed to unlock Module Federation's potential.
18+
19+
The `@angular-architects/module-federation` package provides this custom builder.
20+
Use the ng add command to incorporate it into your projects:
21+
22+
<Tabs>
23+
<Tab label="Angular CLI">
24+
```bash
25+
ng add @angular-architects/module-federation --project shell --port 4200 --type host
26+
ng add @angular-architects/module-federation --project mfe1 --port 4201 --type remote
27+
```
28+
</Tab>
29+
<Tab label="Nx Cli">
30+
For Nx users, the procedure is slightly different.
31+
32+
```bash
33+
npm i @angular-architects/module-federation -D
34+
ng g @angular-architects/module-federation:init --project shell --port 4200 --type host
35+
ng g @angular-architects/module-federation:init --project mfe1 --port 4201 --type remote
36+
```
37+
38+
</Tab>
39+
</Tabs>
40+
<div className={"rspress-directive tip"}>
41+
The `--type` argument, introduced in version 14.3, ensures that only the necessary configuration is generated.
42+
</div>
43+
44+
## Shell (Host) Configuration
45+
46+
The Shell (Host) is crucial for Module Federation integration.
47+
This section configures the Shell to support lazy-loading of a `FlightModule` through routing.
48+
<Steps>
49+
### Routing Configuration
50+
51+
Start by defining the application routes, specifying a lazy-loaded `FlightModule` using a virtual path:
52+
53+
```javascript
54+
export const APP_ROUTES: Routes = [
55+
{
56+
path: '',
57+
component: HomeComponent,
58+
pathMatch: 'full'
59+
},
60+
{
61+
path: 'flights',
62+
loadChildren: () => import('mfe1/Module').then(m => m.FlightsModule)
63+
},
64+
];
65+
```
66+
67+
In this configuration, the path `'mfe1/Module'` is a virtual representation, indicating it doesn't physically exist within the Shell application. Instead, it's a reference to a module in a separate project.
68+
69+
### TypeScript Typing
70+
71+
Create a type definition for the virtual path:
72+
73+
```typescript
74+
// decl.d.ts
75+
declare module 'mfe1/Module';
76+
```
77+
78+
This helps the TypeScript compiler understand the virtual path.
79+
80+
### Webpack Configuration
81+
82+
Instruct Webpack to resolve all paths prefixed with `mfe1` to a remote project. This is done in the `webpack.config.js` file:
83+
84+
```javascript
85+
const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
86+
87+
module.exports = withModuleFederationPlugin({
88+
89+
remotes: {
90+
"mfe1": "http://localhost:4201/remoteEntry.js",
91+
},
92+
93+
shared: {
94+
...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
95+
},
96+
97+
});
98+
```
99+
In the `remotes` section, the path `mfe1` is mapped to the remote micro-frontend's entry point. This entry point, generated by Webpack, contains essential information for interacting with the micro-frontend.
100+
101+
<details>
102+
103+
For development, hardcoding the remote entry's URL is enough. However, a dynamic approach is necessary for production. The concept of dynamic remotes is further explored in a dedicated documentation page on Dynamic Remotes.
104+
105+
- The `shared` property specifies the npm packages to be shared between the Shell and the micro-frontend(s). Using the `shareAll` helper method, all dependencies listed in your `package.json` are shared. While this facilitates a quick setup, it may lead to an excessive number of shared dependencies, which could be a concern for optimization.
106+
- The combination of `singleton: true` and `strictVersion: true` settings instructs Webpack to throw a runtime error if there is a version mismatch between the Shell and the micro-frontend(s). Changing `strictVersion` to `false` would instead result in a runtime warning.
107+
- The `requiredVersion: 'auto'` option, provided by the `@angular-architects/module-federation` plugin, automatically determines the version from your `package.json`, helping to prevent version-related issues.
108+
</details>
109+
</Steps>
110+
111+
112+
## Configuring the Remote
113+
114+
The Micro-frontend, also known as the Remote in Module Federation, has a structure similar to a standard Angular app. It has specific routes in the `AppModule` and a `FlightsModule` for flight-related tasks. This section explains how to smoothly load the `FlightsModule` into the Shell (Host).
115+
116+
<Steps>
117+
### Route Definition
118+
119+
Establish the basic routes within the `AppModule`:
120+
121+
```typescript
122+
export const APP_ROUTES: Routes = [
123+
{ path: '', component: HomeComponent, pathMatch: 'full'}
124+
];
125+
```
126+
127+
This simple routing setup navigates to a `HomeComponent` when the application is accessed.
128+
129+
### Module Creation
130+
131+
Create a `FlightsModule` to handle flight-related operations:
132+
133+
```typescript
134+
@NgModule({
135+
imports: [
136+
CommonModule,
137+
RouterModule.forChild(FLIGHTS_ROUTES)
138+
],
139+
declarations: [
140+
FlightsSearchComponent
141+
]
142+
})
143+
export class FlightsModule { }
144+
```
145+
146+
This module contains a route to a `FlightsSearchComponent` defined as follows:
147+
148+
```typescript
149+
export const FLIGHTS_ROUTES: Routes = [
150+
{
151+
path: 'flights-search',
152+
component: FlightsSearchComponent
153+
}
154+
];
155+
```
156+
157+
### Exposing Modules via Webpack Configuration
158+
159+
To enable the loading of `FlightsModule` into the Shell, expose it through the Remote's Webpack configuration:
160+
161+
```javascript
162+
const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
163+
164+
module.exports = withModuleFederationPlugin({
165+
name: 'mfe1',
166+
exposes: {
167+
'./Module': './projects/mfe1/src/app/flights/flights.module.ts',
168+
},
169+
shared: {
170+
...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
171+
},
172+
});
173+
```
174+
175+
<details>
176+
In this configuration:
177+
178+
- The `name` property identifies the micro-frontend as `mfe1`.
179+
- The `exposes` property signifies the exposure of `FlightsModule` under the public name `Module`, allowing its consumption by the Shell.
180+
- The `shared` property lists the libraries to be shared with the Shell, using the `shareAll` method to share all dependencies found in your `package.json`. The `singleton: true` and `strictVersion: true` properties ensure that a single version of shared libraries is used, and a runtime error is triggered in case of version incompatibility, respectively.
181+
</details>
182+
183+
</Steps>
184+
185+
## Starting the Applications
186+
187+
Having set up the Shell (Host) and Micro-frontend (Remote), it's time to test the configuration to ensure the seamless integration of Module Federation.
188+
189+
To start the Shell and Micro-frontend, use the following commands:
190+
191+
```bash
192+
ng serve shell -o
193+
ng serve mfe1 -o
194+
```
195+
196+
Navigate to the Flights section in the Shell to see the Micro-frontend being dynamically loaded.
197+
198+
:::tip
199+
The plugin installs an npm script `run:all` during the `ng-add` and `init` schematics, allowing for simultaneous serving of all applications:
200+
201+
```bash
202+
npm run run:all
203+
# or
204+
npm run run:all shell mfe1
205+
```
206+
:::
207+
208+
209+
## Optimizing Dependency Sharing
210+
211+
The initial setup with `shareAll` is simple and functional, but it can result in the creation of unnecessarily large shared bundles.
212+
213+
To manage shared dependencies more effectively, consider switching from `shareAll` to using the `share` helper. This provides finer control over which dependencies are shared:
214+
215+
```javascript
216+
// Replace shareAll with share:
217+
const { share, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
218+
219+
module.exports = withModuleFederationPlugin({
220+
// Specify the packages to share:
221+
shared: share({
222+
"@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
223+
"@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
224+
"@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
225+
"@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
226+
})
227+
});
228+
```
229+
230+
In this configuration, the `share` helper allows for explicit sharing of selected packages, enabling a more optimized bundle sharing and potentially reducing load times.
231+

0 commit comments

Comments
 (0)