@softarc/native-federation 3.5.5 → 4.0.0-RC10

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.
Files changed (152) hide show
  1. package/package.json +33 -5
  2. package/src/config.d.ts +4 -1
  3. package/src/config.js +4 -6
  4. package/src/domain.d.ts +2 -0
  5. package/src/domain.js +2 -0
  6. package/src/index.d.ts +10 -1
  7. package/src/index.js +10 -5
  8. package/src/internal.d.ts +13 -0
  9. package/src/internal.js +10 -0
  10. package/src/lib/config/configuration-context.js +3 -9
  11. package/src/lib/config/default-skip-list.d.ts +4 -0
  12. package/src/lib/config/default-skip-list.js +31 -0
  13. package/src/lib/config/remove-unused-deps.d.ts +3 -0
  14. package/src/lib/config/remove-unused-deps.js +10 -0
  15. package/src/lib/config/share-utils.d.ts +6 -18
  16. package/src/lib/config/share-utils.js +49 -128
  17. package/src/lib/config/with-native-federation.d.ts +1 -1
  18. package/src/lib/config/with-native-federation.js +48 -75
  19. package/src/lib/core/build-adapter.d.ts +3 -28
  20. package/src/lib/core/build-adapter.js +8 -13
  21. package/src/lib/core/build-for-federation.d.ts +4 -10
  22. package/src/lib/core/build-for-federation.js +84 -79
  23. package/src/lib/core/bundle-exposed-and-mappings.d.ts +6 -10
  24. package/src/lib/core/bundle-exposed-and-mappings.js +78 -60
  25. package/src/lib/core/bundle-shared.d.ts +11 -6
  26. package/src/lib/core/bundle-shared.js +88 -72
  27. package/src/lib/core/default-external-list.js +1 -8
  28. package/src/lib/core/federation-builder.d.ts +11 -6
  29. package/src/lib/core/federation-builder.js +27 -21
  30. package/src/lib/core/federation-cache.d.ts +8 -0
  31. package/src/lib/core/federation-cache.js +11 -0
  32. package/src/lib/core/get-externals.d.ts +1 -1
  33. package/src/lib/core/get-externals.js +2 -6
  34. package/src/lib/core/normalize-options.d.ts +12 -0
  35. package/src/lib/core/normalize-options.js +57 -0
  36. package/src/lib/core/rebuild-for-federation.d.ts +4 -0
  37. package/src/lib/core/rebuild-for-federation.js +37 -0
  38. package/src/lib/core/write-federation-info.d.ts +2 -2
  39. package/src/lib/core/write-federation-info.js +3 -8
  40. package/src/lib/core/write-import-map.d.ts +6 -3
  41. package/src/lib/core/write-import-map.js +13 -9
  42. package/src/lib/domain/config/external-config.contract.d.ts +43 -0
  43. package/src/lib/domain/config/external-config.contract.js +1 -0
  44. package/src/lib/domain/config/federation-config.contract.d.ts +35 -0
  45. package/src/lib/domain/config/federation-config.contract.js +1 -0
  46. package/src/lib/domain/config/index.d.ts +3 -0
  47. package/src/lib/domain/config/index.js +1 -0
  48. package/src/lib/{core/default-skip-list.d.ts → domain/config/skip-list.contract.d.ts} +0 -3
  49. package/src/lib/domain/config/skip-list.contract.js +1 -0
  50. package/src/lib/domain/config/with-native-federation.contract.d.ts +2 -0
  51. package/src/lib/domain/config/with-native-federation.contract.js +1 -0
  52. package/src/lib/domain/core/build-adapter.contract.d.ts +40 -0
  53. package/src/lib/domain/core/build-adapter.contract.js +1 -0
  54. package/src/lib/domain/core/build-notification-options.contract.d.ts +9 -0
  55. package/src/lib/domain/core/build-notification-options.contract.js +6 -0
  56. package/src/lib/domain/core/chunk.d.ts +2 -0
  57. package/src/lib/domain/core/chunk.js +8 -0
  58. package/src/lib/domain/core/federation-cache.contract.d.ts +7 -0
  59. package/src/lib/domain/core/federation-cache.contract.js +1 -0
  60. package/src/lib/domain/core/federation-info.contract.d.ts +33 -0
  61. package/src/lib/domain/core/federation-info.contract.js +1 -0
  62. package/src/lib/domain/core/federation-options.contract.d.ts +21 -0
  63. package/src/lib/domain/core/federation-options.contract.js +1 -0
  64. package/src/lib/domain/core/index.d.ts +6 -0
  65. package/src/lib/domain/core/index.js +2 -0
  66. package/src/lib/domain/utils/index.d.ts +2 -0
  67. package/src/lib/domain/utils/index.js +1 -0
  68. package/src/lib/domain/utils/keyvaluepair.contract.d.ts +4 -0
  69. package/src/lib/domain/utils/keyvaluepair.contract.js +1 -0
  70. package/src/lib/domain/utils/mapped-path.contract.d.ts +1 -0
  71. package/src/lib/domain/utils/mapped-path.contract.js +5 -0
  72. package/src/lib/domain/utils/used-dependencies.contract.d.ts +5 -0
  73. package/src/lib/domain/utils/used-dependencies.contract.js +1 -0
  74. package/src/lib/utils/build-result-map.d.ts +3 -2
  75. package/src/lib/utils/build-result-map.js +14 -13
  76. package/src/lib/utils/{bundle-caching.d.ts → cache-persistence.d.ts} +6 -4
  77. package/src/lib/utils/cache-persistence.js +66 -0
  78. package/src/lib/utils/errors.js +1 -6
  79. package/src/lib/utils/get-external-imports.js +5 -10
  80. package/src/lib/utils/get-used-dependencies.d.ts +7 -0
  81. package/src/lib/utils/get-used-dependencies.js +123 -0
  82. package/src/lib/utils/hash-file.js +3 -8
  83. package/src/lib/utils/logger.js +10 -16
  84. package/src/lib/utils/mapped-paths.d.ts +7 -10
  85. package/src/lib/utils/mapped-paths.js +18 -37
  86. package/src/lib/utils/normalize.js +2 -7
  87. package/src/lib/utils/package-info.js +36 -47
  88. package/src/lib/utils/rebuild-queue.d.ts +14 -1
  89. package/src/lib/utils/rebuild-queue.js +36 -21
  90. package/src/lib/utils/resolve-glob.js +7 -12
  91. package/src/lib/utils/resolve-wildcard-keys.js +9 -15
  92. package/src/lib/utils/rewrite-chunk-imports.d.ts +0 -2
  93. package/src/lib/utils/rewrite-chunk-imports.js +13 -29
  94. package/LICENSE +0 -8
  95. package/README.md +0 -509
  96. package/build.d.ts +0 -1
  97. package/build.js +0 -5
  98. package/build.js.map +0 -1
  99. package/src/build.d.ts +0 -19
  100. package/src/build.js +0 -38
  101. package/src/build.js.map +0 -1
  102. package/src/config.js.map +0 -1
  103. package/src/index.js.map +0 -1
  104. package/src/lib/config/configuration-context.js.map +0 -1
  105. package/src/lib/config/federation-config.d.ts +0 -55
  106. package/src/lib/config/federation-config.js +0 -3
  107. package/src/lib/config/federation-config.js.map +0 -1
  108. package/src/lib/config/share-utils.js.map +0 -1
  109. package/src/lib/config/with-native-federation.js.map +0 -1
  110. package/src/lib/core/build-adapter.js.map +0 -1
  111. package/src/lib/core/build-for-federation.js.map +0 -1
  112. package/src/lib/core/bundle-exposed-and-mappings.js.map +0 -1
  113. package/src/lib/core/bundle-shared.js.map +0 -1
  114. package/src/lib/core/default-external-list.js.map +0 -1
  115. package/src/lib/core/default-server-deps-list.d.ts +0 -2
  116. package/src/lib/core/default-server-deps-list.js +0 -10
  117. package/src/lib/core/default-server-deps-list.js.map +0 -1
  118. package/src/lib/core/default-skip-list.js +0 -49
  119. package/src/lib/core/default-skip-list.js.map +0 -1
  120. package/src/lib/core/federation-builder.js.map +0 -1
  121. package/src/lib/core/federation-options.d.ts +0 -14
  122. package/src/lib/core/federation-options.js +0 -3
  123. package/src/lib/core/federation-options.js.map +0 -1
  124. package/src/lib/core/get-externals.js.map +0 -1
  125. package/src/lib/core/load-federation-config.d.ts +0 -3
  126. package/src/lib/core/load-federation-config.js +0 -24
  127. package/src/lib/core/load-federation-config.js.map +0 -1
  128. package/src/lib/core/remove-unused-deps.d.ts +0 -2
  129. package/src/lib/core/remove-unused-deps.js +0 -98
  130. package/src/lib/core/remove-unused-deps.js.map +0 -1
  131. package/src/lib/core/write-federation-info.js.map +0 -1
  132. package/src/lib/core/write-import-map.js.map +0 -1
  133. package/src/lib/utils/build-result-map.js.map +0 -1
  134. package/src/lib/utils/build-utils.d.ts +0 -2
  135. package/src/lib/utils/build-utils.js +0 -9
  136. package/src/lib/utils/build-utils.js.map +0 -1
  137. package/src/lib/utils/bundle-caching.js +0 -78
  138. package/src/lib/utils/bundle-caching.js.map +0 -1
  139. package/src/lib/utils/config-utils.d.ts +0 -2
  140. package/src/lib/utils/config-utils.js +0 -13
  141. package/src/lib/utils/config-utils.js.map +0 -1
  142. package/src/lib/utils/errors.js.map +0 -1
  143. package/src/lib/utils/get-external-imports.js.map +0 -1
  144. package/src/lib/utils/hash-file.js.map +0 -1
  145. package/src/lib/utils/logger.js.map +0 -1
  146. package/src/lib/utils/mapped-paths.js.map +0 -1
  147. package/src/lib/utils/normalize.js.map +0 -1
  148. package/src/lib/utils/package-info.js.map +0 -1
  149. package/src/lib/utils/rebuild-queue.js.map +0 -1
  150. package/src/lib/utils/resolve-glob.js.map +0 -1
  151. package/src/lib/utils/resolve-wildcard-keys.js.map +0 -1
  152. package/src/lib/utils/rewrite-chunk-imports.js.map +0 -1
package/README.md DELETED
@@ -1,509 +0,0 @@
1
- # @softarc/native-federation
2
-
3
- Native Federation is a "browser-native" implementation of the successful mental model behind wepback Module Federation for building Micro Frontends and plugin-based solutions. It can be **used with any framework and build tool** for implementing **Micro Frontends** and plugin-based architectures.
4
-
5
- ## Features
6
-
7
- - ✅ Mental Model of Module Federation
8
- - ✅ Future Proof: Independent of build tools like webpack and frameworks
9
- - ✅ Embraces Import Maps -- an emerging browser technology -- and EcmaScript modules
10
- - ✅ Easy to configure
11
- - ✅ Blazing Fast: The reference implementation not only uses the fast esbuild; it also caches already built shared dependencies (like Angular itself). However, as mentioned above, feel free to use it with any other build tool.
12
-
13
- ## Stack
14
-
15
- This library allows to augment your build process, to configure hosts (Micro Frontend shells) and remotes (Micro Frontends), and to load remotes at runtime.
16
-
17
- While this core library can be used with any framework and build tool, there is a higher level API on top of it. It hooks into the Angular CLI and provides a builder and schematics:
18
-
19
- ![Stack](https://github.com/angular-architects/module-federation-plugin/raw/main/libs/native-federation-core/stack.png)
20
-
21
- > Please find the [Angular-based version here](https://www.npmjs.com/package/@angular-architects/native-federation).
22
-
23
- > Please find the [vite plugin here](https://www.npmjs.com/package/@gioboa/vite-module-federation).
24
-
25
- Also, other higher level abstractions on top of this core library are possible.
26
-
27
- ## About the Mental Model
28
-
29
- 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.
30
-
31
- For this, the mental model introduces several concepts:
32
-
33
- - **Remote:** The remote is a separately built and deployed application. It can **expose EcmaScript** modules that can be loaded into other applications.
34
- - **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.
35
- - **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.
36
- - **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.
37
-
38
- ## Example
39
-
40
- - [VanillaJS example](https://github.com/manfredsteyer/native-federation-core-microfrontend).
41
- - [React example](https://github.com/manfredsteyer/native-federation-react-example)
42
- - This example also shows the **watch mode** for compiling a federated application
43
- - [Vite + Svelte example](https://github.com/gioboa/svelte-microfrontend-demo)
44
- - [Vite + Angular example powered by AnalogJS](https://github.com/manfredsteyer/native-federation-vite-angular-demo)
45
- - **Your Example:** If you have an example with aspects not covered here, let us know. We are happy to link it here.
46
-
47
- ## Credits
48
-
49
- Big thanks to:
50
-
51
- - [Zack Jackson](https://twitter.com/ScriptedAlchemy) for originally coming up with the great idea of Module Federation and its successful mental model
52
- - [Tobias Koppers](https://twitter.com/wSokra) for helping to make Module Federation a first class citizen of webpack
53
- - [Florian Rappl](https://twitter.com/FlorianRappl) for an good discussion about these topics during a speakers dinner in Nuremberg
54
- - [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 === ❤️)
55
- - [Michael Egger-Zikes](https://twitter.com/MikeZks) for contributing to our Module Federation efforts and brining in valuable feedback
56
- - 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
57
- - [Giorgio Boa](https://twitter.com/giorgio_boa) for implementing the awesome vite plugin for module federation.
58
-
59
- ## Using this Library
60
-
61
- ### Installing the Library
62
-
63
- ```
64
- npm i @softarc/native-federation
65
- ```
66
-
67
- As Native Federation is tooling agnostic, we need an adapter to make it work with specific build tools. The package `@softarc/native-federation-esbuild` contains a simple adapter that uses esbuild:
68
-
69
- ```
70
- npm i @softarc/native-federation-esbuild
71
- ```
72
-
73
- In some situations, this builder also delegates to rollup. This is necessary b/c esbuild does not provide all features we need (yet). We hope to minimize the usage of rollup in the future.
74
-
75
- You can also provide your own adapter by providing a function aligning with the `BuildAdapter` type.
76
-
77
- ### Augment your Build Process
78
-
79
- Just call three helper methods provided by our `federationBuilder` in your build process to adjust it for Native Federation.
80
-
81
- ```typescript
82
- import * as esbuild from 'esbuild';
83
- import * as path from 'path';
84
- import * as fs from 'fs';
85
- import { esBuildAdapter } from '@softarc/native-federation-esbuild';
86
- import { federationBuilder } from '@softarc/native-federation/build';
87
-
88
-
89
- const projectName = 'shell';
90
- const tsConfig = 'tsconfig.json';
91
- const outputPath = `dist/${projectName}`;
92
-
93
- /*
94
- * Step 1: Initialize Native Federation
95
- */
96
- await federationBuilder.init({
97
- options: {
98
- workspaceRoot: path.join(__dirname, '..'),
99
- outputPath,
100
- tsConfig,
101
- federationConfig: `${projectName}/federation.config.js`,
102
- verbose: false,
103
- },
104
-
105
- /*
106
- * As this core lib is tooling-agnostic, you
107
- * need a simple adapter for your bundler.
108
- * It's just a matter of one function.
109
- */
110
- adapter: esBuildAdapter
111
- });
112
-
113
- /*
114
- * Step 2: Trigger your build process
115
- *
116
- * You can use any tool for this. Here, we go
117
- * with a very simple esbuild-based build.
118
- *
119
- * Just respect the externals in
120
- * `federationBuilder.externals`.
121
- */
122
-
123
- [...]
124
-
125
- await esbuild.build({
126
- [...]
127
- external: federationBuilder.externals,
128
- [...]
129
- });
130
-
131
- [...]
132
-
133
- /*
134
- * Step 3: Let the build method do the additional tasks
135
- * for supporting Native Federation
136
- */
137
-
138
- await federationBuilder.build();
139
- ```
140
-
141
- The method `federationBuilder.build` bundles the shared and exposed parts of your app.
142
-
143
- ### Configuring Hosts
144
-
145
- The `withNativeFederation` function sets up a configuration for your applications. This is an example configuration for a host:
146
-
147
- The `shareAll` helper shares all your dependencies defined in your `package.json`. The `package.json` is look up as described above:
148
-
149
- ```typescript
150
- // shell/federation.config.js
151
-
152
- const { withNativeFederation, shareAll } = require('@softarc/native-federation/build');
153
-
154
- module.exports = withNativeFederation({
155
- name: 'host',
156
-
157
- shared: {
158
- ...shareAll({
159
- singleton: true,
160
- strictVersion: true,
161
- requiredVersion: 'auto',
162
- includeSecondaries: false,
163
- }),
164
- },
165
- });
166
- ```
167
-
168
- The options passed to shareAll are applied to all dependencies found in your `package.json`.
169
-
170
- This might come in handy in an mono repo scenario and when doing some experiments/ trouble shooting.
171
-
172
- > Since v21.1 it's also possible to add overrides to the shareAll for specific packages.
173
-
174
- ```typescript
175
- // shell/federation.config.js
176
-
177
- const { withNativeFederation, shareAll } = require('@softarc/native-federation/build');
178
-
179
- module.exports = withNativeFederation({
180
- name: 'host',
181
-
182
- shared: {
183
- ...shareAll(
184
- {
185
- singleton: true,
186
- strictVersion: true,
187
- requiredVersion: 'auto',
188
- },
189
- {
190
- overrides: {
191
- 'package-a/themes/xyz': {
192
- singleton: true,
193
- strictVersion: true,
194
- requiredVersion: 'auto',
195
- includeSecondaries: { skip: '@package-a/themes/xyz/*' },
196
- build: 'package',
197
- },
198
- 'package-b': {
199
- singleton: false,
200
- strictVersion: true,
201
- requiredVersion: 'auto',
202
- includeSecondaries: { skip: 'package-b/icons/*' },
203
- build: 'package',
204
- },
205
- },
206
- },
207
- ),
208
- },
209
- });
210
- ```
211
-
212
- ### Share Helper
213
-
214
- The helper function share adds some additional options for the shared dependencies:
215
-
216
- ```typescript
217
- shared: share({
218
- "package-a": {
219
- singleton: true,
220
- strictVersion: true,
221
- requiredVersion: 'auto',
222
- includeSecondaries: true
223
- },
224
- [...]
225
- })
226
- ```
227
-
228
- The added options are `requireVersion: 'auto'` and `includeSecondaries`.
229
-
230
- #### requireVersion: 'auto'
231
-
232
- If you set `requireVersion` to `'auto'`, the helper takes the version defined in your `package.json`.
233
-
234
- This helps to solve issues with not (fully) met peer dependencies and secondary entry points (see Pitfalls section below).
235
-
236
- By default, it takes the `package.json` that is closest to the caller (normally the `webpack.config.js`). However, you can pass the path to an other `package.json` using the second optional parameter. Also, you need to define the shared libray within the node dependencies in your `package.json`.
237
-
238
- Instead of setting requireVersion to auto time and again, you can also skip this option and call `setInferVersion(true)` before:
239
-
240
- ```typescript
241
- setInferVersion(true);
242
- ```
243
-
244
- #### includeSecondaries
245
-
246
- If set to `true`, all secondary entry points are added too. In the case of `@angular/common` this is also `@angular/common/http`, `@angular/common/http/testing`, `@angular/common/testing`, `@angular/common/http/upgrade`, and `@angular/common/locales`. This exhaustive list shows that using this option for `@angular/common` is not the best idea because normally, you don't need most of them.
247
-
248
- > `includeSecondaries` is true by default.
249
-
250
- However, this option can come in handy for quick experiments or if you want to quickly share a package like `@angular/material` that comes with a myriad of secondary entry points.
251
-
252
- Even if you share too much, Native Federation will only load the needed ones at runtime. However, please keep in mind that shared packages can not be tree-shaken.
253
-
254
- To skip some secondary entry points, you can assign a configuration option instead of `true`:
255
-
256
- ```typescript
257
- shared: share({
258
- "@angular/common": {
259
- singleton: true,
260
- strictVersion: true,
261
- requiredVersion: 'auto',
262
- includeSecondaries: {
263
- skip: ['@angular/common/http/testing']
264
- }
265
- },
266
- [...]
267
- })
268
- ```
269
-
270
- ### includeSecondaries
271
-
272
- Since v21 it's also possible to resolve Glob exports by enabling the `globResolve` property:
273
-
274
- ```typescript
275
- shared: share({
276
- "package-a": {
277
- singleton: true,
278
- strictVersion: true,
279
- requiredVersion: "auto",
280
- includeSecondaries: {resolveGlob: true}
281
- },
282
- [...]
283
- })
284
- ```
285
-
286
- This is disabled by default since it will create a bundle of every valid exported file it finds, **Only use this feature in combination with `ignoreUnusedDeps` flag**. If you want to specifically skip certain parts of the glob export, you can also use the wildcard in the skip section:
287
-
288
- ```typescript
289
- shared: share({
290
- "package-a/themes/xyz": {
291
- singleton: true,
292
- strictVersion: true,
293
- requiredVersion: "auto",
294
- includeSecondaries: {skip: "package-a/themes/xyz/*", resolveGlob: true}
295
- },
296
- [...]
297
- })
298
- ```
299
-
300
- Finally, it's also possible to break out of the "removeUnusedDep" for a specific external if desired, for example when sharing a whole suite of external modules. This can be handy when you want to avoid the chance of cross-version secondary entrypoints being used by the different micro frontends. E.g. mfe1 uses @angular/core v20.1.0 and mfe2 uses @angular/core/rxjs-interop v20.0.8, then you might want to use consistent use of v20.1.0 so rxjs-interop should be exported by mfe1. The "keepAll" prop allows you to enforce this:
301
-
302
- ```typescript
303
- shared: share({
304
- "@angular/core": {
305
- singleton: true,
306
- strictVersion: true,
307
- requiredVersion: "auto",
308
- includeSecondaries: {keepAll: true}
309
- },
310
- [...]
311
- })
312
- ```
313
-
314
- The API for configuring and using Native Federation is very similar to the one provided by our Module Federation plugin [@angular-architects/module-federation](https://www.npmjs.com/package/@angular-architects/native-federation). Hence, most the articles on it are also valid for Native Federation.
315
-
316
- ### Sharing
317
-
318
- The `shareAll`-helper used here shares all dependencies found in your `package.json`. Hence, they only need to be loaded once (instead of once per remote and host). If you don't want to share all of them, you can opt-out of sharing by using the `skip` option:
319
-
320
- ```typescript
321
- module.exports = withNativeFederation({
322
- [...]
323
-
324
- // Don't share my-lib
325
- skip: [
326
- 'my-lib'
327
- ]
328
-
329
- [...]
330
- }
331
- ```
332
-
333
- ### Sharing Mapped Paths (Monorepo-internal Libraries)
334
-
335
- Paths mapped in your `tsconfig.json` are shared by default too. While they are part of your (mono) repository, they are treaded like libraries:
336
-
337
- ```json
338
- {
339
- "compilerOptions": {
340
- [...]
341
- "paths": {
342
- "shared-lib": [
343
- "libs/shared-lib/index.ts"
344
- ]
345
- }
346
- }
347
- }
348
- ```
349
-
350
- If you don't want to share (all of) them, put their names into the skip array (see above).
351
-
352
- ### Configuring Remotes
353
-
354
- When configuring a remote, you can expose files that can be loaded into the shell at runtime:
355
-
356
- ```javascript
357
- const { withNativeFederation, shareAll } = require('@softarc/native-federation/build');
358
-
359
- module.exports = withNativeFederation({
360
- name: 'mfe1',
361
-
362
- exposes: {
363
- './component': './mfe1/component',
364
- },
365
-
366
- shared: {
367
- ...shareAll({
368
- singleton: true,
369
- strictVersion: true,
370
- requiredVersion: 'auto',
371
- includeSecondaries: false,
372
- }),
373
- },
374
- });
375
- ```
376
-
377
- ### Initializing a Host
378
-
379
- On startup, call the `initFederation` method. It takes a mapping between the names of remotes and their `remoteEntry.json`. This is a file containing meta data generated by the augmented build process (see above).
380
-
381
- ```typescript
382
- import { initFederation } from '@softarc/native-federation';
383
-
384
- (async () => {
385
- await initFederation({
386
- mfe1: 'http://localhost:3001/remoteEntry.json',
387
- });
388
-
389
- await import('./app');
390
- })();
391
- ```
392
-
393
- You can also pass the name of a file with the key data about your remotes:
394
-
395
- ```typescript
396
- import { initFederation } from '@softarc/native-federation';
397
-
398
- (async () => {
399
- await initFederation('assets/manifest.json');
400
-
401
- await import('./app');
402
- })();
403
- ```
404
-
405
- Following the ideas of our friends at [Nrwl](https://nrwl.io), we call such a file a manifest:
406
-
407
- ```json
408
- {
409
- "mfe1": "http://localhost:3001/remoteEntry.json"
410
- }
411
- ```
412
-
413
- Manifests allow to adjust your application to different environments without any recompilation.
414
-
415
- ## Initializing a Remote
416
-
417
- For initializing a remote, also call `initFederation`. If you don't plan to load further remotes into your remote, you don't need to pass any parameters:
418
-
419
- ```typescript
420
- import { initFederation } from '@softarc/native-federation';
421
-
422
- (async () => {
423
- await initFederation();
424
- await import('./component');
425
- })();
426
- ```
427
-
428
- ### Loading a Remote
429
-
430
- To load a remote, just call the `loadRemoteModule` function:
431
-
432
- ```typescript
433
- const module = await loadRemoteModule({
434
- remoteName: 'mfe1',
435
- exposedModule: './component',
436
- });
437
- ```
438
-
439
- If you know the type of the loaded module (perhaps you have a shared interface), you can use it as a type parameter:
440
-
441
- ```typescript
442
- const module = await loadRemoteModule<MyRemoteType>({
443
- remoteName: 'mfe1',
444
- exposedModule: './component',
445
- });
446
- ```
447
-
448
- ### Polyfill
449
-
450
- This library uses Import Maps. As currently not all browsers support this emerging browser feature, we need a polyfill. We recommend the polyfill `es-module-shims` which has been developed for production use cases:
451
-
452
- ```html
453
- <script type="esms-options">
454
- {
455
- "shimMode": true,
456
- "mapOverrides": true
457
- }
458
- </script>
459
-
460
- <script src="https://ga.jspm.io/npm:es-module-shims@1.5.17/dist/es-module-shims.js"></script>
461
-
462
- <script type="module-shim" src="main.js"></script>
463
- ```
464
-
465
- The script with the type `esms-options` configures the polyfill. This library was built for shim mode. In this mode, the polyfill provides some additional features beyond the proposal for Import Maps. These features, for instance, allow for dynamically creating an import map after loading a first EcmaScript module. Native Federation uses this possibility.
466
-
467
- To make the polyfill to load your EcmaScript modules (bundles) in shim mode, assign the type `module-shim`.
468
-
469
- ## React and Other CommonJS Libs
470
-
471
- Native Federation uses Web Standards like EcmaScript Modules. Most libs and frameworks support them meanwhile. Unfortunately, React still uses CommonJS (und UMD). We do our best to convert these libs to EcmaScript Modules. In the case of React there are some challenges due to the dynamic way the React bundles use the `exports` object.
472
-
473
- As the community is moving to EcmaScrpt Modules, we expect that these issues will vanish over time. In between, we provide some solutions for dealing with CommonJS-based libraries using `exports` in a dynamic way.
474
-
475
- One of them is `fileReplacemnts`:
476
-
477
- ```javascript
478
- import { reactReplacements } from '@softarc/native-federation-esbuild/src/lib/react-replacements';
479
- import { createEsBuildAdapter } from '@softarc/native-federation-esbuild';
480
-
481
- [...]
482
-
483
- createEsBuildAdapter({
484
- plugins: [],
485
- fileReplacements: reactReplacements.prod
486
- })
487
- ```
488
-
489
- Please note that the adapter comes with `fileReplacements` settings for React for both, `dev` mode and `prod` mode. For similar libraries you can add your own replacements. Also, using the `compensateExports` property, you can activate some additional logic for such libraries to make sure the exports are not lost
490
-
491
- ```javascript
492
- createEsBuildAdapter({
493
- plugins: [],
494
- fileReplacements: reactReplacements.prod,
495
- compensateExports: [new RegExp('/my-lib/')],
496
- });
497
- ```
498
-
499
- The default value for `compensateExports` is `[new RegExp('/react/')]`.
500
-
501
- ## More: Blog Articles
502
-
503
- 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/).
504
-
505
- ## More: Angular Architecture Workshop (100% online, interactive)
506
-
507
- In our [Angular Architecture Workshop](https://www.angulararchitects.io/en/angular-workshops/advanced-angular-enterprise-architecture-incl-ivy/), we cover all these topics and far more. We provide different options and alternatives and show up their consequences.
508
-
509
- [Details: Angular Architecture Workshop](https://www.angulararchitects.io/en/angular-workshops/advanced-angular-enterprise-architecture-incl-ivy/)
package/build.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from './src/build';
package/build.js DELETED
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./src/build"), exports);
5
- //# sourceMappingURL=build.js.map
package/build.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../libs/native-federation-core/build.ts"],"names":[],"mappings":";;;AAAA,sDAA4B"}
package/src/build.d.ts DELETED
@@ -1,19 +0,0 @@
1
- export { DEFAULT_SKIP_LIST } from './lib/core/default-skip-list';
2
- export { NormalizedFederationConfig, SharedConfig, } from './lib/config/federation-config';
3
- export { withNativeFederation } from './lib/config/with-native-federation';
4
- export { BuildAdapter, BuildAdapterOptions, BuildKind, BuildResult, EntryPoint, setBuildAdapter, } from './lib/core/build-adapter';
5
- export { buildForFederation } from './lib/core/build-for-federation';
6
- export { bundleExposedAndMappings } from './lib/core/bundle-exposed-and-mappings';
7
- export { FederationOptions } from './lib/core/federation-options';
8
- export { getExternals } from './lib/core/get-externals';
9
- export { loadFederationConfig } from './lib/core/load-federation-config';
10
- export { writeFederationInfo } from './lib/core/write-federation-info';
11
- export { writeImportMap } from './lib/core/write-import-map';
12
- export { MappedPath } from './lib/utils/mapped-paths';
13
- export { RebuildQueue } from './lib/utils/rebuild-queue';
14
- export { findRootTsConfigJson, share, shareAll, } from './lib/config/share-utils';
15
- export { BuildHelperParams, federationBuilder, } from './lib/core/federation-builder';
16
- export * from './lib/utils/build-result-map';
17
- export { hashFile } from './lib/utils/hash-file';
18
- export * from './lib/utils/errors';
19
- export { logger, setLogLevel } from './lib/utils/logger';
package/src/build.js DELETED
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setLogLevel = exports.logger = exports.hashFile = exports.federationBuilder = exports.shareAll = exports.share = exports.findRootTsConfigJson = exports.RebuildQueue = exports.writeImportMap = exports.writeFederationInfo = exports.loadFederationConfig = exports.getExternals = exports.bundleExposedAndMappings = exports.buildForFederation = exports.setBuildAdapter = exports.withNativeFederation = exports.DEFAULT_SKIP_LIST = void 0;
4
- const tslib_1 = require("tslib");
5
- var default_skip_list_1 = require("./lib/core/default-skip-list");
6
- Object.defineProperty(exports, "DEFAULT_SKIP_LIST", { enumerable: true, get: function () { return default_skip_list_1.DEFAULT_SKIP_LIST; } });
7
- var with_native_federation_1 = require("./lib/config/with-native-federation");
8
- Object.defineProperty(exports, "withNativeFederation", { enumerable: true, get: function () { return with_native_federation_1.withNativeFederation; } });
9
- var build_adapter_1 = require("./lib/core/build-adapter");
10
- Object.defineProperty(exports, "setBuildAdapter", { enumerable: true, get: function () { return build_adapter_1.setBuildAdapter; } });
11
- var build_for_federation_1 = require("./lib/core/build-for-federation");
12
- Object.defineProperty(exports, "buildForFederation", { enumerable: true, get: function () { return build_for_federation_1.buildForFederation; } });
13
- var bundle_exposed_and_mappings_1 = require("./lib/core/bundle-exposed-and-mappings");
14
- Object.defineProperty(exports, "bundleExposedAndMappings", { enumerable: true, get: function () { return bundle_exposed_and_mappings_1.bundleExposedAndMappings; } });
15
- var get_externals_1 = require("./lib/core/get-externals");
16
- Object.defineProperty(exports, "getExternals", { enumerable: true, get: function () { return get_externals_1.getExternals; } });
17
- var load_federation_config_1 = require("./lib/core/load-federation-config");
18
- Object.defineProperty(exports, "loadFederationConfig", { enumerable: true, get: function () { return load_federation_config_1.loadFederationConfig; } });
19
- var write_federation_info_1 = require("./lib/core/write-federation-info");
20
- Object.defineProperty(exports, "writeFederationInfo", { enumerable: true, get: function () { return write_federation_info_1.writeFederationInfo; } });
21
- var write_import_map_1 = require("./lib/core/write-import-map");
22
- Object.defineProperty(exports, "writeImportMap", { enumerable: true, get: function () { return write_import_map_1.writeImportMap; } });
23
- var rebuild_queue_1 = require("./lib/utils/rebuild-queue");
24
- Object.defineProperty(exports, "RebuildQueue", { enumerable: true, get: function () { return rebuild_queue_1.RebuildQueue; } });
25
- var share_utils_1 = require("./lib/config/share-utils");
26
- Object.defineProperty(exports, "findRootTsConfigJson", { enumerable: true, get: function () { return share_utils_1.findRootTsConfigJson; } });
27
- Object.defineProperty(exports, "share", { enumerable: true, get: function () { return share_utils_1.share; } });
28
- Object.defineProperty(exports, "shareAll", { enumerable: true, get: function () { return share_utils_1.shareAll; } });
29
- var federation_builder_1 = require("./lib/core/federation-builder");
30
- Object.defineProperty(exports, "federationBuilder", { enumerable: true, get: function () { return federation_builder_1.federationBuilder; } });
31
- tslib_1.__exportStar(require("./lib/utils/build-result-map"), exports);
32
- var hash_file_1 = require("./lib/utils/hash-file");
33
- Object.defineProperty(exports, "hashFile", { enumerable: true, get: function () { return hash_file_1.hashFile; } });
34
- tslib_1.__exportStar(require("./lib/utils/errors"), exports);
35
- var logger_1 = require("./lib/utils/logger");
36
- Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
37
- Object.defineProperty(exports, "setLogLevel", { enumerable: true, get: function () { return logger_1.setLogLevel; } });
38
- //# sourceMappingURL=build.js.map
package/src/build.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../../libs/native-federation-core/src/build.ts"],"names":[],"mappings":";;;;AAAA,kEAAiE;AAAxD,sHAAA,iBAAiB,OAAA;AAM1B,8EAA2E;AAAlE,8HAAA,oBAAoB,OAAA;AAC7B,0DAOkC;AADhC,gHAAA,eAAe,OAAA;AAEjB,wEAAqE;AAA5D,0HAAA,kBAAkB,OAAA;AAC3B,sFAAkF;AAAzE,uIAAA,wBAAwB,OAAA;AAEjC,0DAAwD;AAA/C,6GAAA,YAAY,OAAA;AACrB,4EAAyE;AAAhE,8HAAA,oBAAoB,OAAA;AAC7B,0EAAuE;AAA9D,4HAAA,mBAAmB,OAAA;AAC5B,gEAA6D;AAApD,kHAAA,cAAc,OAAA;AAEvB,2DAAyD;AAAhD,6GAAA,YAAY,OAAA;AACrB,wDAIkC;AAHhC,mHAAA,oBAAoB,OAAA;AACpB,oGAAA,KAAK,OAAA;AACL,uGAAA,QAAQ,OAAA;AAEV,oEAGuC;AADrC,uHAAA,iBAAiB,OAAA;AAEnB,uEAA6C;AAC7C,mDAAiD;AAAxC,qGAAA,QAAQ,OAAA;AACjB,6DAAmC;AACnC,6CAAyD;AAAhD,gGAAA,MAAM,OAAA;AAAE,qGAAA,WAAW,OAAA"}
package/src/config.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../libs/native-federation-core/src/config.ts"],"names":[],"mappings":";;;AAAA,iCAAiC;AACjC,kDAAwB"}
package/src/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/native-federation-core/src/index.ts"],"names":[],"mappings":";;;AAAA,6EAAmD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"configuration-context.js","sourceRoot":"","sources":["../../../../../../libs/native-federation-core/src/lib/config/configuration-context.ts"],"names":[],"mappings":";;AAOA,oCAEC;AAED,wCAEC;AAED,4CAEC;AAZD,IAAI,QAAQ,GAAyB,EAAE,CAAC;AAExC,SAAgB,YAAY,CAAC,aAAqB;IAChD,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,CAAC;AAC5C,CAAC;AAED,SAAgB,cAAc,CAAC,WAAoB;IACjD,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,CAAC;AAC1C,CAAC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1,55 +0,0 @@
1
- import { PreparedSkipList, SkipList } from '../core/default-skip-list';
2
- import { MappedPath } from '../utils/mapped-paths';
3
- export interface SharedConfig {
4
- singleton?: boolean;
5
- strictVersion?: boolean;
6
- requiredVersion?: string;
7
- version?: string;
8
- includeSecondaries?: boolean;
9
- transient?: boolean;
10
- platform?: 'browser' | 'node';
11
- build?: 'default' | 'separate';
12
- packageInfo?: {
13
- entryPoint: string;
14
- version: string;
15
- esm: boolean;
16
- };
17
- }
18
- export interface FederationConfig {
19
- name?: string;
20
- exposes?: Record<string, string>;
21
- shared?: Record<string, SharedConfig>;
22
- sharedMappings?: Array<string>;
23
- skip?: SkipList;
24
- externals?: string[];
25
- features?: {
26
- mappingVersion?: boolean;
27
- ignoreUnusedDeps?: boolean;
28
- };
29
- }
30
- export interface NormalizedSharedConfig {
31
- singleton: boolean;
32
- strictVersion: boolean;
33
- requiredVersion: string;
34
- version?: string;
35
- includeSecondaries?: boolean;
36
- platform: 'browser' | 'node';
37
- build: 'default' | 'separate' | 'package';
38
- packageInfo?: {
39
- entryPoint: string;
40
- version: string;
41
- esm: boolean;
42
- };
43
- }
44
- export interface NormalizedFederationConfig {
45
- name: string;
46
- exposes: Record<string, string>;
47
- shared: Record<string, NormalizedSharedConfig>;
48
- sharedMappings: Array<MappedPath>;
49
- skip: PreparedSkipList;
50
- externals: string[];
51
- features: {
52
- mappingVersion: boolean;
53
- ignoreUnusedDeps: boolean;
54
- };
55
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=federation-config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"federation-config.js","sourceRoot":"","sources":["../../../../../../libs/native-federation-core/src/lib/config/federation-config.ts"],"names":[],"mappings":""}