diff --git a/docs/shared/recipes/module-federation/dynamic-mfe-angular.md b/docs/shared/recipes/module-federation/dynamic-mfe-angular.md index 80bfdc6ea1..37b9b56b02 100644 --- a/docs/shared/recipes/module-federation/dynamic-mfe-angular.md +++ b/docs/shared/recipes/module-federation/dynamic-mfe-angular.md @@ -36,34 +36,71 @@ Here's the source code of the final result for this guide. ### Create an Nx Workspace -To start with, we need to create a new Nx Workspace. We can do this easily with: +To start with, we need to create a new Nx Workspace and add the Nx Angular plugin. We can do this easily with: {% tabs %} {% tab label="npm" %} +```{% command="npx create-nx-workspace@latest ng-mf" path="~/" %} + NX Let's create a new workspace [https://nx.dev/getting-started/intro] + +✔ Which stack do you want to use? · none +✔ Package-based monorepo, integrated monorepo, or standalone project? · integrated +✔ Which CI provider would you like to use? · skip +✔ Would you like remote caching to make your build faster? · skip + +``` + +Next run: + ```shell -npx create-nx-workspace ng-mf +cd ng-mf +npx nx add @nx/angular ``` {% /tab %} {% tab label="yarn" %} +```{% command="yarn create nx-workspace ng-mf" path="~/" %} + NX Let's create a new workspace [https://nx.dev/getting-started/intro] + +✔ Which stack do you want to use? · none +✔ Package-based monorepo, integrated monorepo, or standalone project? · integrated +✔ Which CI provider would you like to use? · skip +✔ Would you like remote caching to make your build faster? · skip + +``` + +Next run: + ```shell -yarn create nx-workspace ng-mf +cd ng-mf +yarn nx add @nx/angular ``` {% /tab %} {% tab label="pnpm" %} +```{% command="pnpx create-nx-workspace@latest ng-mf" path="~/" %} + NX Let's create a new workspace [https://nx.dev/getting-started/intro] + +✔ Which stack do you want to use? · none +✔ Package-based monorepo, integrated monorepo, or standalone project? · integrated +✔ Which CI provider would you like to use? · skip +✔ Would you like remote caching to make your build faster? · skip + +``` + +Next run: + ```shell -pnpm create nx-workspace ng-mf +cd ng-mf +pnpx nx add @nx/angular ``` {% /tab %} {% /tabs %} -You'll be prompted a few questions. Pick the `Angular` stack, `Integrated Monorepo` layout and the `webpack` bundler. You can use the default values for the rest of the prompts. We won't use the application that gets generated by default on this guide, so you can remove it. - ### Creating our applications We need to generate two applications that support Module Federation. @@ -140,7 +177,7 @@ This config is then used in the `webpack.config.ts` file: import { withModuleFederation } from '@nx/angular/module-federation'; import config from './module-federation.config'; -export default withModuleFederation(config); +export default withModuleFederation(config, { dts: false }); ``` We can see the following in the **Dashboard** micro frontend configuration: @@ -168,7 +205,8 @@ We'll start by building the **Login** application, which will consist of a login ### User Library -Let's create a user data-access library that will be shared between the host application and the remote application. This will be used to determine if there is an authenticated user as well as providing logic for authenticating the user. +Let's create a user data-access library that will be shared between the host application and the remote application. +This will be used to determine if there is an authenticated user as well as providing logic for authenticating the user. ```shell nx g @nx/angular:lib libs/shared/data-access-user @@ -221,6 +259,7 @@ import { Component } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { UserService } from '@ng-mf/data-access-user'; +import { inject } from '@angular/core'; @Component({ standalone: true, @@ -264,12 +303,11 @@ import { UserService } from '@ng-mf/data-access-user'; ], }) export class RemoteEntryComponent { + private userService = inject(UserService); username = ''; password = ''; isLoggedIn$ = this.userService.isUserLoggedIn$; - constructor(private userService: UserService) {} - login() { this.userService.checkCredentials(this.username, this.password); } @@ -308,7 +346,7 @@ Next, let's add our logic to the `app.component.ts` file. Change it to match the ```ts {% fileName="apps/dashboard/src/app/app.component.ts" %} import { CommonModule } from '@angular/common'; -import { Component, OnInit } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; import { Router, RouterModule } from '@angular/router'; import { UserService } from '@ng-mf/data-access-user'; import { distinctUntilChanged } from 'rxjs/operators'; @@ -326,10 +364,10 @@ import { distinctUntilChanged } from 'rxjs/operators'; `, }) export class AppComponent implements OnInit { + private router = inject(Router); + private userService = inject(UserService); isLoggedIn$ = this.userService.isUserLoggedIn$; - constructor(private userService: UserService, private router: Router) {} - ngOnInit() { this.isLoggedIn$ .pipe(distinctUntilChanged()) @@ -403,9 +441,9 @@ There are 3 steps involved with this: Perhaps one of the easiest methods of fetching the Remote Definitions at runtime is to store them in a JSON file that can be present in each environment. The Host application then only has to make a GET request to the JSON file. -We’ll start by creating this file. Add a `module-federation.manifest.json` file to the `src/assets/` folder in our **Dashboard** application with the following content: +We’ll start by creating this file. Add a `module-federation.manifest.json` file to the `src/public/` folder in our **Dashboard** application with the following content: -```json {% fileName="apps/dashboard/src/assets/module-federation.manifest.json" %} +```json {% fileName="apps/dashboard/src/public/module-federation.manifest.json" %} { "login": "http://localhost:4201" } @@ -416,7 +454,7 @@ Next, open the `main.ts` file and replace it with the following: ```ts {% fileName="apps/dashboard/src/main.ts" %} import { setRemoteDefinitions } from '@nx/angular/mf'; -fetch('/assets/module-federation.manifest.json') +fetch('/module-federation.manifest.json') .then((res) => res.json()) .then((definitions) => setRemoteDefinitions(definitions)) .then(() => import('./bootstrap').catch((err) => console.error(err)));