@angular-architects/native-federation 1.0.0-beta.1 → 16.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -137
- package/builders.json +1 -1
- package/config.d.ts +1 -1
- package/config.js +4 -4
- package/package.json +12 -16
- package/src/builders/build/builder.d.ts +5 -5
- package/src/builders/build/builder.js +78 -145
- package/src/builders/build/builder.js.map +1 -1
- package/src/builders/build/schema.d.ts +8 -1
- package/src/builders/build/schema.json +19 -532
- package/src/builders/serve/builder.ts.bak +57 -0
- package/src/builders/serve/schema.json.bak +107 -0
- package/src/config.d.ts +2 -2
- package/src/config.js +9 -9
- package/src/executors/build/executor.d.ts +4 -4
- package/src/executors/build/executor.js +12 -12
- package/src/generators/native-federation/generator.d.ts +3 -3
- package/src/generators/native-federation/generator.js +43 -43
- package/src/generators/native-federation/generator.js.map +1 -1
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -5
- package/src/plugin/dev-externals-mixin.d.ts +1 -0
- package/src/plugin/dev-externals-mixin.js +30 -0
- package/src/plugin/dev-externals-mixin.js.map +1 -0
- package/src/plugin/externals-skip-list.d.ts +2 -0
- package/src/plugin/externals-skip-list.js +9 -0
- package/src/plugin/externals-skip-list.js.map +1 -0
- package/src/plugin/index.d.ts +2 -0
- package/src/plugin/index.js +101 -0
- package/src/plugin/index.js.map +1 -0
- package/src/schematics/init/files/federation.config.js__tmpl__ +8 -0
- package/src/schematics/init/schematic.d.ts +4 -4
- package/src/schematics/init/schematic.js +194 -161
- package/src/schematics/init/schematic.js.map +1 -1
- package/src/utils/angular-esbuild-adapter.d.ts +6 -3
- package/src/utils/angular-esbuild-adapter.js +140 -90
- package/src/utils/angular-esbuild-adapter.js.map +1 -1
- package/src/utils/dev-server.d.ts +4 -0
- package/src/utils/dev-server.js +41 -0
- package/src/utils/dev-server.js.map +1 -0
- package/src/utils/event-sorce.d.ts +9 -0
- package/src/utils/event-sorce.js +20 -0
- package/src/utils/event-sorce.js.map +1 -0
- package/src/utils/rebuild-events.d.ts +9 -0
- package/src/utils/rebuild-events.js +12 -0
- package/src/utils/rebuild-events.js.map +1 -0
- package/src/utils/rollup.d.ts +1 -1
- package/src/utils/rollup.js +57 -57
- package/src/utils/rollup.js.map +1 -1
- package/src/utils/rollup.ts.bak +60 -0
- package/src/utils/shared-mappings-plugin.d.ts +3 -3
- package/src/utils/shared-mappings-plugin.js +28 -28
- package/src/utils/shared-mappings-plugin.js.map +1 -1
- package/src/utils/transform.d.ts +1 -0
- package/src/utils/transform.js +45 -0
- package/src/utils/transform.js.map +1 -0
- package/src/utils/updateIndexHtml.d.ts +2 -0
- package/src/utils/updateIndexHtml.js +33 -0
- package/src/utils/updateIndexHtml.js.map +1 -0
package/README.md
CHANGED
|
@@ -1,85 +1,100 @@
|
|
|
1
|
-
# Native Federation
|
|
1
|
+
# Native Federation for Angular
|
|
2
2
|
|
|
3
|
-
Native Federation is a "browser-native" implementation of the successful mental model behind
|
|
3
|
+
Native Federation is a "browser-native" implementation of the successful mental model behind webpack Module Federation for building Micro Frontends (Plugins, etc.).
|
|
4
4
|
|
|
5
|
-
## Features
|
|
5
|
+
## Features 🔥
|
|
6
6
|
|
|
7
7
|
- ✅ Mental Model of Module Federation
|
|
8
8
|
- ✅ Future Proof: Independent of build tools like webpack
|
|
9
9
|
- ✅ Embraces Import Maps - an emerging web standard
|
|
10
10
|
- ✅ 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
|
|
11
|
+
- ✅ Blazing Fast: The reference implementation not only uses the fast esbuild; it also caches already built shared dependencies.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Prerequisite
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Angular & Angular CLI 16.1 or higher
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
This package was successfully tested with Angular CLI projects and with Nx projects.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## Versions
|
|
20
20
|
|
|
21
|
-
|
|
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.
|
|
35
22
|
|
|
36
23
|
## Credits
|
|
37
24
|
|
|
38
25
|
Big thanks to:
|
|
39
26
|
|
|
40
|
-
- [Zack Jackson](https://twitter.com/ScriptedAlchemy) for
|
|
27
|
+
- [Zack [Jackson](https://twitter.com/ScriptedAlchemy) for initially coming up with the great idea of Module Federation and its successful mental model
|
|
41
28
|
- [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
|
|
29
|
+
- [Florian [Rappl](https://twitter.com/FlorianRappl) for a good discussion about these topics during a speakers dinner in Nuremberg
|
|
43
30
|
- [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 === ❤️)
|
|
44
31
|
- [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
|
|
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
|
|
46
33
|
|
|
47
|
-
## Example
|
|
34
|
+
## Example 🛠️
|
|
48
35
|
|
|
49
36
|
We migrated our webpack Module Federation example to Native Federation:
|
|
50
37
|
|
|
51
38
|

|
|
52
39
|
|
|
53
|
-
Please find the example [here (branch:
|
|
40
|
+
Please find the example [here (branch: nf-standalone-solution)](https://github.com/manfredsteyer/module-federation-plugin-example/tree/nf-standalone-solution):
|
|
54
41
|
|
|
55
42
|
```
|
|
56
|
-
git clone https://github.com/manfredsteyer/module-federation-plugin-example.git --branch nf-solution
|
|
43
|
+
git clone https://github.com/manfredsteyer/module-federation-plugin-example.git --branch nf-standalone-solution
|
|
57
44
|
|
|
58
45
|
cd module-federation-plugin-example
|
|
59
46
|
|
|
60
47
|
npm i
|
|
61
|
-
npm run build
|
|
62
|
-
npm start
|
|
63
48
|
```
|
|
64
49
|
|
|
65
|
-
|
|
50
|
+
Start the Micro Frontend:
|
|
66
51
|
|
|
67
|
-
|
|
52
|
+
```
|
|
53
|
+
ng serve mfe1 -o
|
|
54
|
+
```
|
|
68
55
|
|
|
69
|
-
|
|
56
|
+
Wait until the Micro Frontend is started.
|
|
70
57
|
|
|
71
|
-
|
|
58
|
+
Open another console and start the shell:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
ng serve shell -o
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The example loads a Micro Frontends into a shell:
|
|
65
|
+
|
|
66
|
+

|
|
67
|
+
|
|
68
|
+
## Relationship to @angular-architects/module-federation
|
|
69
|
+
|
|
70
|
+
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.
|
|
71
|
+
|
|
72
|
+
## About the Mental Model 🧠
|
|
73
|
+
|
|
74
|
+
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.
|
|
72
75
|
|
|
73
76
|
For this, the mental model introduces several concepts:
|
|
74
77
|
|
|
75
78
|
- **Remote:** The remote is a separately built and deployed application. It can **expose EcmaScript** modules that can be loaded into other applications.
|
|
76
|
-
- **Host:** The host loads one or several remotes on demand.
|
|
77
|
-
- **Shared Dependencies
|
|
78
|
-
- **Version Mismatch:** If two or more applications use a different version of the same shared library, we need to prevent a version mismatch.
|
|
79
|
+
- **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.
|
|
80
|
+
- **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.
|
|
81
|
+
- **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.
|
|
79
82
|
|
|
80
|
-
## Usage
|
|
83
|
+
## Usage/ Tutorial 🧪
|
|
81
84
|
|
|
82
|
-
|
|
85
|
+
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:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
git clone https://github.com/manfredsteyer/module-federation-plugin-example.git --branch nf-standalone-starter
|
|
89
|
+
|
|
90
|
+
cd module-federation-plugin-example
|
|
91
|
+
|
|
92
|
+
npm i
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
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`:
|
|
96
|
+
|
|
97
|
+

|
|
83
98
|
|
|
84
99
|
### Adding Native Federation
|
|
85
100
|
|
|
@@ -87,31 +102,27 @@ For this, the mental model introduces several concepts:
|
|
|
87
102
|
npm i @angular-architects/native-federation -D
|
|
88
103
|
```
|
|
89
104
|
|
|
90
|
-
Making an application a
|
|
105
|
+
Making an application a remote (Micro Frontend):
|
|
91
106
|
|
|
92
107
|
```
|
|
93
|
-
ng g @angular-architects/native-federation:init --project
|
|
108
|
+
ng g @angular-architects/native-federation:init --project mfe1 --port 4201 --type remote
|
|
94
109
|
```
|
|
95
110
|
|
|
96
|
-
|
|
111
|
+
Making an application a host (shell):
|
|
97
112
|
|
|
98
113
|
```
|
|
99
|
-
ng g @angular-architects/native-federation:init --project shell --type dynamic-host
|
|
114
|
+
ng g @angular-architects/native-federation:init --project shell --port 4200 --type dynamic-host
|
|
100
115
|
```
|
|
101
116
|
|
|
102
|
-
|
|
117
|
+
A dynamic host reads the configuration data at runtime from a `.json` file.
|
|
103
118
|
|
|
104
|
-
|
|
105
|
-
ng g @angular-architects/native-federation:init --project mfe1 --type remote
|
|
106
|
-
```
|
|
119
|
+
> 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).
|
|
107
120
|
|
|
108
121
|
### Configuring the Host
|
|
109
122
|
|
|
110
|
-
The host configuration looks like what you know from our Module Federation plugin:
|
|
123
|
+
The host configuration (`projects/shell/federation.config.js`) looks like what you know from our Module Federation plugin:
|
|
111
124
|
|
|
112
125
|
```javascript
|
|
113
|
-
// projects/shell/federation.config.js
|
|
114
|
-
|
|
115
126
|
const {
|
|
116
127
|
withNativeFederation,
|
|
117
128
|
shareAll,
|
|
@@ -125,16 +136,24 @@ module.exports = withNativeFederation({
|
|
|
125
136
|
requiredVersion: 'auto',
|
|
126
137
|
}),
|
|
127
138
|
},
|
|
139
|
+
|
|
140
|
+
skip: [
|
|
141
|
+
'rxjs/ajax',
|
|
142
|
+
'rxjs/fetch',
|
|
143
|
+
'rxjs/testing',
|
|
144
|
+
'rxjs/webSocket',
|
|
145
|
+
// Add further packages you don't need at runtime
|
|
146
|
+
],
|
|
128
147
|
});
|
|
129
148
|
```
|
|
130
149
|
|
|
150
|
+
> Our `init` schematic shown above generates this file for you.
|
|
151
|
+
|
|
131
152
|
### Configuring the Remote
|
|
132
153
|
|
|
133
|
-
Also the remote configuration looks familiar:
|
|
154
|
+
Also, the remote configuration (`projects/mfe1/federation.config.js`) looks familiar:
|
|
134
155
|
|
|
135
156
|
```javascript
|
|
136
|
-
// projects/mfe1/federation.config.js
|
|
137
|
-
|
|
138
157
|
const {
|
|
139
158
|
withNativeFederation,
|
|
140
159
|
shareAll,
|
|
@@ -144,7 +163,7 @@ module.exports = withNativeFederation({
|
|
|
144
163
|
name: 'mfe1',
|
|
145
164
|
|
|
146
165
|
exposes: {
|
|
147
|
-
'./
|
|
166
|
+
'./Component': './projects/mfe1/src/app/app.component.ts',
|
|
148
167
|
},
|
|
149
168
|
|
|
150
169
|
shared: {
|
|
@@ -154,37 +173,24 @@ module.exports = withNativeFederation({
|
|
|
154
173
|
requiredVersion: 'auto',
|
|
155
174
|
}),
|
|
156
175
|
},
|
|
157
|
-
});
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Initializing the Host
|
|
161
|
-
|
|
162
|
-
Call `initFederation` before bootstrapping your `main.ts`:
|
|
163
176
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
})
|
|
172
|
-
.catch((err) => console.error(err))
|
|
173
|
-
.then((_) => import('./bootstrap'))
|
|
174
|
-
.catch((err) => console.error(err));
|
|
177
|
+
skip: [
|
|
178
|
+
'rxjs/ajax',
|
|
179
|
+
'rxjs/fetch',
|
|
180
|
+
'rxjs/testing',
|
|
181
|
+
'rxjs/webSocket',
|
|
182
|
+
// Add further packages you don't need at runtime
|
|
183
|
+
],
|
|
184
|
+
});
|
|
175
185
|
```
|
|
176
186
|
|
|
177
|
-
> Our `init` schematic shown above generates
|
|
187
|
+
> Our `init` schematic shown above generates this file for you.
|
|
178
188
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
Please note that in Native Federation, the remote entry is just a `.json` file while its a `.js` file in Module Federation.
|
|
189
|
+
### Initializing the Host
|
|
182
190
|
|
|
183
|
-
|
|
191
|
+
When bootstrapping the host (shell), Native Federation (`projects\shell\src\main.ts`) is initialized:
|
|
184
192
|
|
|
185
193
|
```typescript
|
|
186
|
-
// projects/shell/src/main.ts
|
|
187
|
-
|
|
188
194
|
import { initFederation } from '@angular-architects/native-federation';
|
|
189
195
|
|
|
190
196
|
initFederation('/assets/federation.manifest.json')
|
|
@@ -193,23 +199,27 @@ initFederation('/assets/federation.manifest.json')
|
|
|
193
199
|
.catch((err) => console.error(err));
|
|
194
200
|
```
|
|
195
201
|
|
|
196
|
-
This
|
|
202
|
+
> This file is generated by the schematic described above.
|
|
197
203
|
|
|
198
|
-
|
|
204
|
+
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.
|
|
199
205
|
|
|
200
|
-
Credits
|
|
206
|
+
**Credits:** The Nx team originally came up with the idea for the manifest.
|
|
201
207
|
|
|
202
|
-
This is what the (also generated) federation manifest looks like:
|
|
208
|
+
This is what the (also generated) federation manifest (`projects\shell\src\assets\federation.manifest.json`) looks like:
|
|
203
209
|
|
|
204
210
|
```json
|
|
205
211
|
{
|
|
206
|
-
"mfe1": "http://localhost:
|
|
212
|
+
"mfe1": "http://localhost:4201/remoteEntry.json"
|
|
207
213
|
}
|
|
208
214
|
```
|
|
209
215
|
|
|
216
|
+
Native Federation generates the `remoteEntry.json`. It contains metadata about the individual remote.
|
|
217
|
+
|
|
218
|
+
If you follow this tutorial, **ensure** this entry points to port `4201` (!).
|
|
219
|
+
|
|
210
220
|
### Initializing the Remote
|
|
211
221
|
|
|
212
|
-
|
|
222
|
+
When bootstrapping your remote (`projects\mfe1\src\main.ts`), Native Federation is initialized too:
|
|
213
223
|
|
|
214
224
|
```typescript
|
|
215
225
|
import { initFederation } from '@angular-architects/native-federation';
|
|
@@ -220,92 +230,95 @@ initFederation()
|
|
|
220
230
|
.catch((err) => console.error(err));
|
|
221
231
|
```
|
|
222
232
|
|
|
233
|
+
> Our `init` schematic shown above also generates this file.
|
|
234
|
+
|
|
235
|
+
After the initialization, it loads the file `bootstrap.ts` starting your Angular application.
|
|
236
|
+
|
|
223
237
|
### Loading a Remote
|
|
224
238
|
|
|
225
|
-
|
|
239
|
+
For loading a component (or any other building block) exposed by a remote into the host, use Native Federation's `loadRemoteModule` function together with lazy loading (`projects\shell\src\app\app.routes.ts`):
|
|
226
240
|
|
|
227
241
|
```typescript
|
|
242
|
+
import { Routes } from '@angular/router';
|
|
243
|
+
import { HomeComponent } from './home/home.component';
|
|
244
|
+
import { NotFoundComponent } from './not-found/not-found.component';
|
|
245
|
+
|
|
246
|
+
// Add this import:
|
|
228
247
|
import { loadRemoteModule } from '@angular-architects/native-federation';
|
|
229
|
-
[...]
|
|
230
248
|
|
|
231
249
|
export const APP_ROUTES: Routes = [
|
|
232
|
-
|
|
250
|
+
{
|
|
251
|
+
path: '',
|
|
252
|
+
component: HomeComponent,
|
|
253
|
+
pathMatch: 'full',
|
|
254
|
+
},
|
|
233
255
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
},
|
|
256
|
+
// Add this route:
|
|
257
|
+
{
|
|
258
|
+
path: 'flights',
|
|
259
|
+
loadComponent: () =>
|
|
260
|
+
loadRemoteModule('mfe1', './Component').then((m) => m.AppComponent),
|
|
261
|
+
},
|
|
241
262
|
|
|
242
|
-
|
|
243
|
-
|
|
263
|
+
{
|
|
264
|
+
path: '**',
|
|
265
|
+
component: NotFoundComponent,
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
// DO NOT insert routes after this one.
|
|
269
|
+
// { path:'**', ...} needs to be the LAST one.
|
|
270
|
+
];
|
|
244
271
|
```
|
|
245
272
|
|
|
246
|
-
|
|
273
|
+
### Starting your example
|
|
247
274
|
|
|
248
|
-
|
|
275
|
+
Start the remote:
|
|
249
276
|
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
|
|
277
|
+
```
|
|
278
|
+
ng serve mfe1 -o
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Once the remote is started, start the shell:
|
|
253
282
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
{
|
|
258
|
-
path: 'flights',
|
|
259
|
-
loadChildren: () => loadRemoteModule({
|
|
260
|
-
// Alternative: You can also use the remoteEntry i/o the remoteName:
|
|
261
|
-
remoteEntry: 'http://localhost:3001/remoteEntry.json',
|
|
262
|
-
exposedModule: './Module'
|
|
263
|
-
}).then(m => m.FlightsModule)
|
|
264
|
-
},
|
|
265
|
-
|
|
266
|
-
[...]
|
|
267
|
-
}
|
|
283
|
+
```
|
|
284
|
+
ng serve shell -o
|
|
268
285
|
```
|
|
269
286
|
|
|
270
|
-
|
|
287
|
+
Now, by clicking at the 2nd menu item, you can load the remote directly into the host.
|
|
271
288
|
|
|
272
|
-
|
|
289
|
+
## FAQ
|
|
273
290
|
|
|
274
|
-
|
|
291
|
+
### When to use this package?
|
|
275
292
|
|
|
276
|
-
|
|
293
|
+
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.
|
|
277
294
|
|
|
278
|
-
|
|
279
|
-
<script type="esms-options">
|
|
280
|
-
{
|
|
281
|
-
"shimMode": true
|
|
282
|
-
}
|
|
283
|
-
</script>
|
|
295
|
+
### I get an error when preparing shared packages. What to do?
|
|
284
296
|
|
|
285
|
-
|
|
297
|
+
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.
|
|
286
298
|
|
|
287
|
-
|
|
288
|
-
```
|
|
299
|
+
If the preparation of one of these packages fails, you get an error like this one:
|
|
289
300
|
|
|
290
|
-
|
|
301
|
+

|
|
291
302
|
|
|
292
|
-
|
|
303
|
+
For this, there are several reasons:
|
|
293
304
|
|
|
294
|
-
|
|
305
|
+
- 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`.
|
|
295
306
|
|
|
296
|
-
|
|
307
|
+
- 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.
|
|
297
308
|
|
|
298
|
-
|
|
309
|
+
### How to speed up package preparation during the build process
|
|
299
310
|
|
|
300
|
-
|
|
311
|
+
The already prepared packages are cached in `node_modules/.cache`. Make sure, this folder is reused across subsequent build process runs.
|
|
301
312
|
|
|
302
313
|
### How does Native Federation Work under the Covers?
|
|
303
314
|
|
|
304
|
-
We use Import Maps at runtime.
|
|
315
|
+
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.
|
|
316
|
+
|
|
317
|
+
## Documentation 📰
|
|
305
318
|
|
|
306
|
-
|
|
319
|
+
Please have a look at this [article series](https://www.angulararchitects.io/en/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/).
|
|
307
320
|
|
|
308
|
-
|
|
321
|
+
Even though these articles were written for Module Federation, thanks to the same API, they also apply to Native Federation.
|
|
309
322
|
|
|
310
323
|
## More: Angular Architecture Workshop (100% online, interactive)
|
|
311
324
|
|
package/builders.json
CHANGED
package/config.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './src/config';
|
|
1
|
+
export * from './src/config';
|
package/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
tslib_1.__exportStar(require("./src/config"), exports);
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./src/config"), exports);
|
|
5
5
|
//# sourceMappingURL=config.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-architects/native-federation",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "16.1.0",
|
|
4
4
|
"main": "src/index.js",
|
|
5
5
|
"generators": "./collection.json",
|
|
6
6
|
"builders": "./builders.json",
|
|
@@ -15,23 +15,19 @@
|
|
|
15
15
|
"url": "https://github.com/angular-architects/module-federation-plugin"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@angular-architects/build-angular": "^14.2.0-next.0",
|
|
19
|
-
"@rollup/plugin-commonjs": "^22.0.2",
|
|
20
|
-
"@rollup/plugin-node-resolve": "^13.3.0",
|
|
21
|
-
"@rollup/plugin-replace": "^4.0.0",
|
|
22
|
-
"rollup": "^2.79.0",
|
|
23
|
-
"rollup-plugin-node-externals": "^4.1.1",
|
|
24
|
-
"esbuild": "^0.15.5",
|
|
25
18
|
"@babel/core": "^7.19.0",
|
|
26
|
-
"@softarc/native-federation": "1.
|
|
27
|
-
"@softarc/native-federation-runtime": "1.
|
|
28
|
-
"@
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
19
|
+
"@softarc/native-federation": "1.1.2",
|
|
20
|
+
"@softarc/native-federation-runtime": "1.1.2",
|
|
21
|
+
"@types/browser-sync": "^2.26.3",
|
|
22
|
+
"browser-sync": "^2.29.3",
|
|
23
|
+
"esbuild": "^0.18.12",
|
|
24
|
+
"mrmime": "^1.0.1",
|
|
25
|
+
"npmlog": "^6.0.2",
|
|
26
|
+
"process": "0.11.10",
|
|
27
|
+
"vite": "4.3.9"
|
|
32
28
|
},
|
|
33
29
|
"peerDependencies": {
|
|
34
|
-
"
|
|
30
|
+
"rxjs": ">=7.0.0"
|
|
35
31
|
},
|
|
36
|
-
"
|
|
32
|
+
"types": "./src/index.d.ts"
|
|
37
33
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
|
|
2
|
-
import {
|
|
3
|
-
export declare function runBuilder(
|
|
4
|
-
declare const _default: import("@angular-devkit/architect/src/internal").Builder<
|
|
5
|
-
export default _default;
|
|
1
|
+
import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
|
|
2
|
+
import { NfBuilderSchema } from './schema';
|
|
3
|
+
export declare function runBuilder(nfOptions: NfBuilderSchema, context: BuilderContext): Promise<BuilderOutput>;
|
|
4
|
+
declare const _default: import("@angular-devkit/architect/src/internal").Builder<NfBuilderSchema & import("@angular-devkit/core").JsonObject>;
|
|
5
|
+
export default _default;
|