Skip to content

Commit 6ae2fa8

Browse files
committed
docs(nf): improve readme
1 parent 61414f7 commit 6ae2fa8

File tree

11 files changed

+91
-60
lines changed

11 files changed

+91
-60
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# @angular-architects/module-federation
22

3-
- See [readme here](./libs/mf/README.md)
3+
- [Readme for Module Federation](./libs/mf/README.md)
4+
- [Readme for Native Federation](./libs/native-federation/README.md)

error.png

113 KB
Loading
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"name": "@softarc/native-federation",
3-
"version": "1.1.1",
3+
"version": "1.1.2",
44
"type": "commonjs",
55
"dependencies": {
66
"json5": "^2.2.0",
77
"npmlog": "^6.0.2",
8-
"@softarc/native-federation-runtime": "1.1.1"
8+
"@softarc/native-federation-runtime": "1.1.2"
99
}
1010
}

libs/native-federation-esbuild/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@softarc/native-federation-esbuild",
3-
"version": "1.1.1",
3+
"version": "1.1.2",
44
"type": "commonjs",
55
"dependencies": {
66
"@rollup/plugin-commonjs": "^22.0.2",

libs/native-federation-runtime/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@softarc/native-federation-runtime",
3-
"version": "1.1.1",
3+
"version": "1.1.2",
44
"peerDependencies": {},
55
"dependencies": {
66
"tslib": "^2.3.0"

libs/native-federation/README.md

Lines changed: 70 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,37 @@
1-
# Native Federation
1+
# Native Federation for Angular
22

3-
Native Federation is a "browser-native" implementation of the successful mental model behind wepback Module Federation for building Micro Frontends.
3+
Native Federation is a "browser-native" implementation of the successful mental model behind webpack Module Federation for building Micro Frontends (Plugins, etc.).
44

5-
## Features
5+
## Features 🔥
66

77
- ✅ Mental Model of Module Federation
88
- ✅ Future Proof: Independent of build tools like webpack
99
- ✅ Embraces Import Maps - an emerging web standard
1010
- ✅ Easy to configure: We use the same API and Schematics as for our Module Federation plugin
11-
- ✅ Blazing Fast: The reference implementation not only uses the fast esbuild; it also caches already built shared dependencies (like Angular itself).
11+
- ✅ Blazing Fast: The reference implementation not only uses the fast esbuild; it also caches already built shared dependencies.
1212

13-
## Today and Tomorrow
13+
## Prerequisite
1414

15-
### Bundler
15+
Angular & Angular CLI 16.1 or higher
1616

17-
The current version uses **esbuild**. Future versions will allow to easily **switch out the build tool**.
17+
This package was successfully tested with Angular CLI projects and with Nx projects.
1818

19-
### Frameworks
19+
## Versions
2020

21-
**Angular** is a first-class citizen: The package ships with **Schematics** for the Angular CLI and a **builder** (that delegates to the experimental esbuild builder the CLI team is current working on). Future versions will also make it easy to use the implementation **with other frameworks**.
22-
23-
### Design
24-
25-
This is possible, because by design, most of the implementation runs outside of the bundler und independently of CLI mechanisms. Hence, we will expose 2-3 helper functions everyone can call in their build process regardless of the framework or build tool used.
26-
27-
## Current Limitations
28-
29-
This is a first experimental version. The results look very promising, however it's not intended to be used in production. Feel free to try it out and to provide feedback!
30-
31-
Limitations:
32-
33-
- 🔷 As we use a fork of the experimental esbuild builder the CLI team is current working on, there is currently **only a builder for ng build**. ng serve or ng test are currently not supported. This support will be added with a future version. Also, as the forked esbuile builder is still experimental, you cannot expect to get all the features you are used to. This will also change over time.
34-
- 🔷 Libraries are currently only shared if two or more remotes (Micro Frontends) request the very same version. This is also what works best with Angular. In a future version, we will add optional "version negotiation" for the sake of feature parity with Module Federation. This allows Native Federation to decide for a "higher compatible version" (e. g. a higher minor version provided by another Micro Frontend) at runtime.
21+
We will at least provide a new version of this package per Angular major. If necessary, we will also provide packages to adapt to Angular minors. To make the relationship between Angular versions and versions of this package easy for all of us, **we follow Angular's version numbers**. E. g., `@angular-architects/native-federation` 16.1 is intended for Angular 16.1 and upwards.
3522

3623
## Credits
3724

3825
Big thanks to:
3926

40-
- [Zack Jackson](https://twitter.com/ScriptedAlchemy) for originally coming up with the great idea of Module Federation and its successful mental model
27+
- [Zack [Jackson](https://twitter.com/ScriptedAlchemy) for initially coming up with the great idea of Module Federation and its successful mental model
4128
- [Tobias Koppers](https://twitter.com/wSokra) for helping to make Module Federation a first class citizen of webpack
42-
- [Florian Rappl](https://twitter.com/FlorianRappl) for an good discussion about these topics during a speakers dinner in Nuremberg
29+
- [Florian [Rappl](https://twitter.com/FlorianRappl) for a good discussion about these topics during a speakers dinner in Nuremberg
4330
- [The Nx Team](https://twitter.com/NxDevTools), esp. [Colum Ferry](https://twitter.com/FerryColum), who seamlessly integrated webpack Module Federation into Nx and hence helped to spread the word about it (Nx + Module Federation === ❤️)
4431
- [Michael Egger-Zikes](https://twitter.com/MikeZks) for contributing to our Module Federation efforts and brining in valuable feedback
45-
- The Angular CLI-Team, esp. [Alan Agius](https://twitter.com/AlanAgius4) and [Charles Lyding](https://twitter.com/charleslyding), for working on the experimental esbuild builder for Angular
32+
- The Angular CLI-Team, esp. [Alan Agius](https://twitter.com/AlanAgius4) and [Charles Lyding](https://twitter.com/charleslyding), for their fantastic work on the esbuild builder for Angular
4633

47-
## Example
34+
## Example 🛠️
4835

4936
We migrated our webpack Module Federation example to Native Federation:
5037

@@ -66,6 +53,8 @@ Start the Micro Frontend:
6653
ng serve mfe1 -o
6754
```
6855

56+
_(In the case of an error, see this [information below](#error-file-srcmaints-is-missing-from-the-typescript-compilation-plugin-angular-compiler))_
57+
6958
Wait until the Micro Frontend is started.
7059

7160
Open another console and start the shell:
@@ -74,18 +63,26 @@ Open another console and start the shell:
7463
ng serve shell -o
7564
```
7665

77-
## About the Mental Model
66+
The example loads a Micro Frontends into a shell:
7867

79-
The underlying mental model allows for runtime integration: Loading a part of a separately built and deployed application into your's. This is needed for Micro Frontend architectures but also for plugin-based solutions.
68+
![Microfrontend Loaded into Shell](https://github.com/angular-architects/module-federation-plugin/raw/main/libs/mf/tutorial/result.png)
69+
70+
## Relationship to @angular-architects/module-federation
71+
72+
This package, `@angular-architects/native-federation`, uses the same API as `@angular-architects/module-federation`. To switch over, just make sure you import everything from the former package. Don't mix these packages.
73+
74+
## About the Mental Model 🧠
75+
76+
The underlying mental model allows for runtime integration: Loading a part of a separately built and deployed application into yours. This is needed for Micro Frontend architectures but also for plugin-based solutions.
8077

8178
For this, the mental model introduces several concepts:
8279

8380
- **Remote:** The remote is a separately built and deployed application. It can **expose EcmaScript** modules that can be loaded into other applications.
84-
- **Host:** The host loads one or several remotes on demand. For your framework's perspective, this looks like traditional lazy loading. The big difference is that the host doesn't know the remotes at compilation time.
85-
- **Shared Dependencies:** If a several remotes and the host use the same library, you might not want to download it several times. Instead, you might want to just download it once and share it at runtime. For this use case, the mental model allows for defining such shared dependencies.
86-
- **Version Mismatch:** If two or more applications use a different version of the same shared library, we need to prevent a version mismatch. To deal with it, the mental model defines several strategies, like falling back to another version that fits the application, using a different compatible one (according to semantic versioning) or throwing an error.
81+
- **Host:** The host loads one or several remotes on demand. From your framework's perspective, this looks like traditional lazy loading. The big difference is that the host doesn't know the remotes at compilation time.
82+
- **Shared Dependencies**:\*\* If several remotes and the host use the same library, you might not want to download it several times. Instead, you might want to download it once and share it at runtime. For this use case, the mental model allows for defining such shared dependencies.
83+
- **Version Mismatch:** If two or more applications use a different version of the same shared library, we need to prevent a version mismatch. The mental model defines several strategies to deal with it, like falling back to another version that fits the application, using a different compatible one (according to semantic versioning), or throwing an error.
8784

88-
## Usage/ Tutorial
85+
## Usage/ Tutorial 🧪
8986

9087
You can checkout the [nf-standalone-starter branch](https://github.com/manfredsteyer/module-federation-plugin-example/tree/nf-standalone-starter) to try out Native Federation:
9188

@@ -97,6 +94,10 @@ cd module-federation-plugin-example
9794
npm i
9895
```
9996

97+
This repository consists of two Angular applications: a `shell` and a Micro Frontend called `mfe1`. During this tutorial, you will load `mfe1` into the `shell`:
98+
99+
![Microfrontend Loaded into Shell](https://github.com/angular-architects/module-federation-plugin/raw/main/libs/mf/tutorial/result.png)
100+
100101
### Adding Native Federation
101102

102103
```
@@ -117,6 +118,8 @@ ng g @angular-architects/native-federation:init --project shell --port 4200 --ty
117118

118119
A dynamic host reads the configuration data at runtime from a `.json` file.
119120

121+
> The schematics called here automate most steps of this tutorial, esp. adding configuration files and bootstrapping Native Federation. Hence, the following sections primarily discuss these changes. You just need to add a lazy route (see below) and make sure the correct ports are configured in the federation manifest (see below too).
122+
120123
### Configuring the Host
121124

122125
The host configuration (`projects/shell/federation.config.js`) looks like what you know from our Module Federation plugin:
@@ -200,7 +203,7 @@ initFederation('/assets/federation.manifest.json')
200203

201204
> This file is generated by the schematic described above.
202205
203-
The function points to a federation manifest. This manifest points to the individual Micro Frontends. It can be exchanged when deploying the solution. Hence, you can adopt the solution to the current environment.
206+
The function points to a federation manifest. This manifest lists the individual remotes. It can be exchanged when deploying the solution. Hence, you can adapt the build to the respective environment.
204207

205208
**Credits:** The Nx team originally came up with the idea for the manifest.
206209

@@ -214,7 +217,7 @@ This is what the (also generated) federation manifest (`projects\shell\src\asset
214217

215218
Native Federation generates the `remoteEntry.json`. It contains metadata about the individual remote.
216219

217-
If you follow this tutorial, ensure this entry points to port `4201` (!).
220+
If you follow this tutorial, **ensure** this entry points to port `4201` (!).
218221

219222
### Initializing the Remote
220223

@@ -277,27 +280,53 @@ Start the remote:
277280
ng serve mfe1 -o
278281
```
279282

280-
Once, the remote is started, start the shell:
283+
_(In the case of an error, see this [information below](#error-file-srcmaints-is-missing-from-the-typescript-compilation-plugin-angular-compiler))_
284+
285+
Once the remote is started, start the shell:
281286

282287
```
283288
ng serve shell -o
284289
```
285290

291+
Now, by clicking at the 2nd menu item, you can load the remote directly into the host.
292+
286293
## FAQ
287294

288-
### Should we Already use Native Federation in Production?
295+
### When to use this package?
296+
297+
If you like the idea of webpack Module Federation but want to switch over to Angular's new esbuild builder (currently in developer preview), you can use this package.
298+
299+
### Error: File 'src\main.ts' is missing from the TypeScript compilation. [plugin angular-compiler]
300+
301+
It seems like the current version of Angular's esbuild builder has an issue with paths on Windows when using the traditional command prompt. For the time being, try to ng serve and ng build your application via PowerShell, the git bash, or WSL.
302+
303+
### I get an error when preparing shared packages. What to do?
304+
305+
Native Federation needs to prepare all your shared packages so that it can load them on demand as EcmaScript modules. This only happens once for development and once for production builds. The result of this is cached.
289306

290-
For production, we would stick with Module Federation for the time being. Native Federation, however, shows that you don't need to fear that you are left alone, once you (or the community) wants to move over to other build tools.
307+
If the preparation of one of these packages fails, you get an error like this one:
291308

292-
We will evolve Native Federation but also our Module Federation support and keep you posted.
309+
![error when preparing shared packages](https://github.com/angular-architects/module-federation-plugin/blob/main/error.png?raw=true)
310+
311+
For this, there are several reasons:
312+
313+
- Perhaps you try to share a package intended for NodeJS/ a package that cannot be converted to EcmaScript modules. This happens if you use `shareAll` in the `federation.config.js` and when the package in question is part of your dependencies in `package.json`. If you don't need (to share) this package at runtime, move it to `devDependencies` or add it to the `skip` section of your `federation.config.js`.
314+
315+
- Perhaps your shared packages contain some code esbuild cannot transfer to EcmaScript modules. This should not be the case for packages, built with the Angular CLI or Nx and the underlying package ng-packagr. If this happens, please let us know about the package causing troubles.
316+
317+
### How to speed up package preparation during the build process
318+
319+
The already prepared packages are cached in `node_modules/.cache`. Make sure, this folder is reused across subsequent build process runs.
293320

294321
### How does Native Federation Work under the Covers?
295322

296-
We use Import Maps at runtime. As they are currently not supported in every browser, our `init` schematic installs the `es-module-shims` polyfill. In addition to Import Maps, we use some code at build time and at runtime to provide the Mental Model of Module Federation.
323+
We use Import Maps at runtime. In addition to Import Maps, we use some code at build time and at runtime to provide the Mental Model of Module Federation.
324+
325+
## Documentation 📰
297326

298-
## More: Blog Articles
327+
Please have a look at this [article series](https://www.angulararchitects.io/en/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/).
299328

300-
Find out more about our work including Micro Frontends and Module Federation but also about alternatives to these approaches in our [blog](https://www.angulararchitects.io/en/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/).
329+
Even though these articles were written for Module Federation, thanks to the same API, they also apply to Native Federation.
301330

302331
## More: Angular Architecture Workshop (100% online, interactive)
303332

libs/native-federation/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@angular-architects/native-federation",
3-
"version": "1.1.1",
3+
"version": "16.1.3",
44
"main": "src/index.js",
55
"generators": "./collection.json",
66
"builders": "./builders.json",
@@ -16,8 +16,8 @@
1616
},
1717
"dependencies": {
1818
"@babel/core": "^7.19.0",
19-
"@softarc/native-federation": "1.1.1",
20-
"@softarc/native-federation-runtime": "1.1.1",
19+
"@softarc/native-federation": "1.1.2",
20+
"@softarc/native-federation-runtime": "1.1.2",
2121
"@types/browser-sync": "^2.26.3",
2222
"browser-sync": "^2.29.3",
2323
"esbuild": "^0.18.12",

libs/native-federation/src/builders/build/builder.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,14 @@ export async function runBuilder(
5757

5858
options.externalDependencies = externals.filter((e) => e !== 'tslib');
5959

60-
// const builderRun = await context.scheduleBuilder(
61-
// '@angular-devkit/build-angular:browser-esbuild',
62-
// options as any,
63-
// { target }
64-
// );
65-
66-
const builderRun = await context.scheduleTarget(target, options as any);
60+
const builderRun = await context.scheduleBuilder(
61+
'@angular-devkit/build-angular:browser-esbuild',
62+
options as any,
63+
{ target }
64+
);
65+
66+
// TODO: Allow more flexibility?
67+
// const builderRun = await context.scheduleTarget(target, options as any);
6768

6869
let first = true;
6970
builderRun.output.subscribe(async (output) => {

update-local.bat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
call npm unpublish @softarc/native-federation@1.1.1 --registry http://localhost:4873
2-
call npm unpublish @softarc/native-federation-runtime@1.1.1 --registry http://localhost:4873
3-
call npm unpublish @softarc/native-federation-esbuild@1.1.1 --registry http://localhost:4873
4-
call npm unpublish @angular-architects/native-federation@1.1.1 --registry http://localhost:4873
1+
call npm unpublish @softarc/native-federation@1.1.2 --registry http://localhost:4873
2+
call npm unpublish @softarc/native-federation-runtime@1.1.2 --registry http://localhost:4873
3+
call npm unpublish @softarc/native-federation-esbuild@1.1.2 --registry http://localhost:4873
4+
call npm unpublish @angular-architects/native-federation@16.1.0 --registry http://localhost:4873
55

66
call nx build native-federation
77
call nx build native-federation-core

0 commit comments

Comments
 (0)