@angular-architects/native-federation 0.9.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.
Files changed (61) hide show
  1. package/README.md +259 -0
  2. package/builders.json +10 -0
  3. package/collection.json +17 -0
  4. package/config.d.ts +1 -0
  5. package/config.js +5 -0
  6. package/config.js.map +1 -0
  7. package/executors.json +10 -0
  8. package/generators.json +12 -0
  9. package/package.json +27 -0
  10. package/src/builders/build/builder.d.ts +5 -0
  11. package/src/builders/build/builder.js +224 -0
  12. package/src/builders/build/builder.js.map +1 -0
  13. package/src/builders/build/schema.d.ts +3 -0
  14. package/src/builders/build/schema.json +550 -0
  15. package/src/config/federation-config.d.ts +26 -0
  16. package/src/config/federation-config.js +3 -0
  17. package/src/config/federation-config.js.map +1 -0
  18. package/src/config/index.d.ts +2 -0
  19. package/src/config/index.js +10 -0
  20. package/src/config/index.js.map +1 -0
  21. package/src/config/with-native-federation.d.ts +2 -0
  22. package/src/config/with-native-federation.js +53 -0
  23. package/src/config/with-native-federation.js.map +1 -0
  24. package/src/config.d.ts +2 -0
  25. package/src/config.js +10 -0
  26. package/src/config.js.map +1 -0
  27. package/src/executors/build/executor.d.ts +4 -0
  28. package/src/executors/build/executor.js +13 -0
  29. package/src/executors/build/executor.js.map +1 -0
  30. package/src/executors/build/schema.d.ts +1 -0
  31. package/src/executors/build/schema.json +9 -0
  32. package/src/generators/native-federation/files/src/index.ts__template__ +1 -0
  33. package/src/generators/native-federation/generator.d.ts +3 -0
  34. package/src/generators/native-federation/generator.js +44 -0
  35. package/src/generators/native-federation/generator.js.map +1 -0
  36. package/src/generators/native-federation/schema.d.ts +5 -0
  37. package/src/generators/native-federation/schema.json +29 -0
  38. package/src/index.d.ts +1 -0
  39. package/src/index.js +5 -0
  40. package/src/index.js.map +1 -0
  41. package/src/schematics/init/files/federation.config.js +19 -0
  42. package/src/schematics/init/schema.d.ts +6 -0
  43. package/src/schematics/init/schema.json +34 -0
  44. package/src/schematics/init/schematic.d.ts +4 -0
  45. package/src/schematics/init/schematic.js +174 -0
  46. package/src/schematics/init/schematic.js.map +1 -0
  47. package/src/utils/build-utils.d.ts +9 -0
  48. package/src/utils/build-utils.js +38 -0
  49. package/src/utils/build-utils.js.map +1 -0
  50. package/src/utils/hash-file.d.ts +1 -0
  51. package/src/utils/hash-file.js +13 -0
  52. package/src/utils/hash-file.js.map +1 -0
  53. package/src/utils/mapped-paths.d.ts +10 -0
  54. package/src/utils/mapped-paths.js +37 -0
  55. package/src/utils/mapped-paths.js.map +1 -0
  56. package/src/utils/package-info.d.ts +7 -0
  57. package/src/utils/package-info.js +94 -0
  58. package/src/utils/package-info.js.map +1 -0
  59. package/src/utils/shared-mappings-plugin.d.ts +3 -0
  60. package/src/utils/shared-mappings-plugin.js +29 -0
  61. package/src/utils/shared-mappings-plugin.js.map +1 -0
package/README.md ADDED
@@ -0,0 +1,259 @@
1
+ # Native Federation
2
+
3
+ Native Federation is a "browser-native" implementation of the successful mental model behind wepback Module Federation for building Micro Frontends.
4
+
5
+ ## Features
6
+
7
+ - ✅ Mental Model of Module Federation
8
+ - ✅ Future Proof: Independent of build tools like webpack
9
+ - ✅ Embraces Import Maps - an emerging web standard
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 (like Angular itself).
12
+
13
+ ## Today and Tomorrow
14
+
15
+ ### Bundler
16
+
17
+ The current version uses **esbuild**. Future versions will allow to easily **switch out the build tool**.
18
+
19
+ ### Frameworks
20
+
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.
34
+
35
+ - 🔷 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.
36
+
37
+ ## Credits
38
+
39
+ Big thanks to:
40
+
41
+ - [Zack Jackson](https://twitter.com/ScriptedAlchemy) for originally coming up with the great idea of Module Federation and its successful mental model
42
+ - [Tobias Koppers](https://twitter.com/wSokra) for helping to make Module Federation a first class citizen of webpack
43
+ - [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
+ - [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
46
+
47
+ ## Example
48
+
49
+ We migrated our webpack Module Federation example to Native Federation:
50
+
51
+ ![Example](https://raw.githubusercontent.com/angular-architects/module-federation-plugin/main/libs/native-federation/example.png)
52
+
53
+ Please find the example [here (branch: ng-solution)](https://github.com/manfredsteyer/module-federation-plugin-example/tree/nf-solution):
54
+
55
+ ```
56
+ git clone https://github.com/manfredsteyer/module-federation-plugin-example.git --branch nf-solution
57
+
58
+ cd module-federation-plugin-example
59
+
60
+ npm i
61
+ npm run build
62
+ npm run start
63
+ ```
64
+
65
+ Then, open http://localhost:3000 in your browser.
66
+
67
+ Please note, that the current **experimental** version does **not** support ``ng serve``. Hence, you need to build it and serve it from the ``dist`` folder (this is what npm run build && npm run start in the above shown example do).
68
+
69
+ ## Usage
70
+
71
+ > You can checkout the [nf-starter branch](https://github.com/manfredsteyer/module-federation-plugin-example/tree/nf-solution) to try out Native Federation.
72
+
73
+ ### Adding Native Federation
74
+
75
+ ```
76
+ npm i @angular-architects/native-federation -D
77
+ ```
78
+
79
+ Making an application a host:
80
+
81
+ ```
82
+ ng g @angular-architects/native-federation:init --project shell --type host
83
+ ```
84
+
85
+ A dynamic host is a host reading the configuration data at runtime from a ``.json`` file:
86
+
87
+ ```
88
+ ng g @angular-architects/native-federation:init --project shell --type dynamic-host
89
+ ```
90
+
91
+ Making an application a remote:
92
+
93
+ ```
94
+ ng g @angular-architects/native-federation:init --project mfe1 --type remote
95
+ ```
96
+
97
+ ### Configuring the Host
98
+
99
+ The host configuration looks like what you know from our Module Federation plugin:
100
+
101
+ ```javascript
102
+ // projects/shell/federation.config.js
103
+
104
+ const { withNativeFederation, shareAll } = require('@angular-architects/native-federation/config');
105
+
106
+ module.exports = withNativeFederation({
107
+
108
+ shared: {
109
+ ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
110
+ },
111
+
112
+ });
113
+ ```
114
+
115
+ ### Configuring the Remote
116
+
117
+ Also the remote configuration looks familiar:
118
+
119
+ ```javascript
120
+ // projects/mfe1/federation.config.js
121
+
122
+ const { withNativeFederation, shareAll } = require('@angular-architects/native-federation/config');
123
+
124
+ module.exports = withNativeFederation({
125
+
126
+ name: 'mfe1',
127
+
128
+ exposes: {
129
+ './Module': './projects/mfe1/src/app/flights/flights.module.ts',
130
+ },
131
+
132
+ shared: {
133
+ ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
134
+ },
135
+
136
+ });
137
+ ```
138
+
139
+ ### Initializing the Host
140
+
141
+ Call ``initFederation`` before bootstrapping your ``main.ts``:
142
+
143
+ ```typescript
144
+ // projects/shell/src/main.ts
145
+
146
+ import { initFederation } from '@angular-architects/native-federation';
147
+
148
+ initFederation({
149
+ mfe1: 'http://localhost:3001/remoteEntry.json'
150
+ })
151
+ .catch(err => console.error(err))
152
+ .then(_ => import('./bootstrap'))
153
+ .catch(err => console.error(err));
154
+ ```
155
+
156
+ > Our ``init`` schematic shown above generates all of this if you pass ``--type host``.
157
+
158
+ You can directly pass a mapping between remote names and their ``remoteEntry.json``. The ``remoteEntry.json`` contains the necessary metadata. It is generated when compiling the remote.
159
+
160
+ Please note that in Native Federation, the remote entry is just a ``.json`` file while its a ``.js`` file in Module Federation.
161
+
162
+ However, you don't need to hardcode this mapping. Feel free to point to the file name of a federation manifest:
163
+
164
+ ```typescript
165
+ // projects/shell/src/main.ts
166
+
167
+ import { initFederation } from '@angular-architects/native-federation';
168
+
169
+ initFederation('/assets/federation.manifest.json')
170
+ .catch(err => console.error(err))
171
+ .then(_ => import('./bootstrap'))
172
+ .catch(err => console.error(err));
173
+ ```
174
+
175
+ This manifest can be exchanged when deploying the solution. Hence, you can adopt the solution to the current environment.
176
+
177
+ > Our ``init`` schematic shown above generates this variation if you pass ``--type dynamic-host``.
178
+
179
+ Credits: The Nx team originally came up with the idea for the manifest.
180
+
181
+ This is what the (also generated) federation manifest looks like:
182
+
183
+ ```json
184
+ {
185
+ "mfe1": "http://localhost:3001/remoteEntry.json"
186
+ }
187
+ ```
188
+
189
+ ### Initializing the Remote
190
+
191
+ Also, the remote needs to be initialized. If a remote doesn't load further remotes, you don't need to pass any mappings to ``initFederation``:
192
+
193
+ ```typescript
194
+ import { initFederation } from '@angular-architects/native-federation';
195
+
196
+ initFederation()
197
+ .catch(err => console.error(err))
198
+ .then(_ => import('./bootstrap'))
199
+ .catch(err => console.error(err));
200
+ ```
201
+
202
+ ### Loading a Remote
203
+
204
+ Use the helper function ``loadRemoteModule`` to load a configured remote:
205
+
206
+ ```typescript
207
+ import { loadRemoteModule } from '@angular-architects/native-federation';
208
+ [...]
209
+
210
+ export const APP_ROUTES: Routes = [
211
+ [...]
212
+
213
+ {
214
+ path: 'flights',
215
+ loadChildren: () => loadRemoteModule({
216
+ remoteName: 'mfe1',
217
+ exposedModule: './Module'
218
+ }).then(m => m.FlightsModule)
219
+ },
220
+
221
+ [...]
222
+ }
223
+ ```
224
+
225
+ This can be used with and without routing; with ``NgModule``s but also with **standalone** building blocks. Just use it instead of dynamic imports.
226
+
227
+ For the sake of compatibility with our Module Federation API, you can also use the ``remoteEntry`` to identify the remote in question:
228
+
229
+ ```typescript
230
+ import { loadRemoteModule } from '@angular-architects/native-federation';
231
+ [...]
232
+
233
+ export const APP_ROUTES: Routes = [
234
+ [...]
235
+
236
+ {
237
+ path: 'flights',
238
+ loadChildren: () => loadRemoteModule({
239
+ // Alternative: You can also use the remoteEntry i/o the remoteName:
240
+ remoteEntry: 'http://localhost:3001/remoteEntry.json',
241
+ exposedModule: './Module'
242
+ }).then(m => m.FlightsModule)
243
+ },
244
+
245
+ [...]
246
+ }
247
+ ```
248
+
249
+ However, we prefer the first option where just the ``remoteName`` is passed.
250
+
251
+ ## More: Blog Articles
252
+
253
+ 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/).
254
+
255
+ ## More: Angular Architecture Workshop (100% online, interactive)
256
+
257
+ 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.
258
+
259
+ [Details: Angular Architecture Workshop](https://www.angulararchitects.io/en/angular-workshops/advanced-angular-enterprise-architecture-incl-ivy/)
package/builders.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "../../node_modules/@angular-devkit/architect/src/builders-schema.json",
3
+ "builders": {
4
+ "build": {
5
+ "implementation": "./src/builders/build/builder",
6
+ "schema": "./src/builders/build/schema.json",
7
+ "description": "build builder"
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "../../node_modules/@angular-devkit/schematics/collection-schema.json",
3
+ "name": "module-federation",
4
+ "version": "0.0.1",
5
+ "schematics": {
6
+ "ng-add": {
7
+ "factory": "./src/schematics/init/schematic",
8
+ "schema": "./src/schematics/init/schema.json",
9
+ "description": "Initialize an angular project for webpack module federation"
10
+ },
11
+ "init": {
12
+ "factory": "./src/schematics/init/schematic",
13
+ "schema": "./src/schematics/init/schema.json",
14
+ "description": "Initialize an angular project for webpack module federation"
15
+ }
16
+ }
17
+ }
package/config.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './src/config';
package/config.js ADDED
@@ -0,0 +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);
5
+ //# sourceMappingURL=config.js.map
package/config.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../libs/native-federation/config.ts"],"names":[],"mappings":";;;AAAA,uDAA6B"}
package/executors.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "executors": {
4
+ "build": {
5
+ "implementation": "./src/executors/build/executor",
6
+ "schema": "./src/executors/build/schema.json",
7
+ "description": "build executor"
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "name": "native-federation",
4
+ "version": "0.0.1",
5
+ "generators": {
6
+ "native-federation": {
7
+ "factory": "./src/generators/native-federation/generator",
8
+ "schema": "./src/generators/native-federation/schema.json",
9
+ "description": "native-federation generator"
10
+ }
11
+ }
12
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@angular-architects/native-federation",
3
+ "version": "0.9.0",
4
+ "main": "src/index.js",
5
+ "generators": "./collection.json",
6
+ "builders": "./builders.json",
7
+ "schematics": "./collection.json",
8
+ "license": "MIT",
9
+ "author": {
10
+ "name": "Manfred Steyer",
11
+ "url": "http://www.angulararchitects.io"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/angular-architects/module-federation-plugin"
16
+ },
17
+ "peerDependencies": {
18
+ "@angular-architects/build-angular": "^14.2.0-next.0",
19
+ "@angular-architects/module-federation": "^14.0.0",
20
+ "@angular-architects/module-federation-runtime": "^14.3.10",
21
+ "semver": "^7.3.5",
22
+ "rxjs": "~6.6.3",
23
+ "@angular-architects/native-federation-runtime": "0.9.0"
24
+ },
25
+ "typings": "./src/index.d.ts",
26
+ "dependencies": {}
27
+ }
@@ -0,0 +1,5 @@
1
+ import { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
2
+ import { Schema } from '@angular-architects/build-angular/src/builders/browser-esbuild/schema';
3
+ export declare function runBuilder(options: Schema, context: BuilderContext): Promise<BuilderOutput>;
4
+ declare const _default: import("@angular-devkit/architect/src/internal").Builder<Schema & import("@angular-devkit/core").JsonObject>;
5
+ export default _default;
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runBuilder = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const architect_1 = require("@angular-devkit/architect");
6
+ const index_1 = require("@angular-architects/build-angular/src/builders/browser-esbuild/index");
7
+ const path = require("path");
8
+ const fs = require("fs");
9
+ const build_utils_1 = require("../../utils/build-utils");
10
+ const package_info_1 = require("../../utils/package-info");
11
+ const shared_mappings_plugin_1 = require("../../utils/shared-mappings-plugin");
12
+ const hash_file_1 = require("../../utils/hash-file");
13
+ const DEFAULT_SKIP_LIST = new Set([
14
+ '@angular-architects/native-federation',
15
+ '@angular-architects/native-federation-runtime',
16
+ 'es-module-shims',
17
+ ]);
18
+ function runBuilder(options, context) {
19
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
20
+ const config = yield loadFederationConfig(options, context);
21
+ const externals = getExternals(config);
22
+ options.externalDependencies = externals;
23
+ const output = yield build(config, options, context);
24
+ const exposesInfo = yield bundleExposed(config, options, externals);
25
+ const sharedPackageInfo = yield bundleShared(config, options, context, externals);
26
+ const sharedMappingInfo = yield bundleSharedMappings(config, options, context, externals);
27
+ const sharedInfo = [...sharedPackageInfo, ...sharedMappingInfo];
28
+ const federationInfo = {
29
+ name: config.name,
30
+ shared: sharedInfo,
31
+ exposes: exposesInfo,
32
+ };
33
+ writeFederationInfo(federationInfo, context, options);
34
+ writeImportMap(sharedInfo, context, options);
35
+ updateIndexHtml(context, options);
36
+ return output;
37
+ });
38
+ }
39
+ exports.runBuilder = runBuilder;
40
+ exports.default = (0, architect_1.createBuilder)(runBuilder);
41
+ function updateIndexHtml(context, options) {
42
+ const outputPath = path.join(context.workspaceRoot, options.outputPath);
43
+ const indexPath = path.join(outputPath, 'index.html');
44
+ const mainName = fs
45
+ .readdirSync(outputPath)
46
+ .find((f) => f.startsWith('main.') && f.endsWith('.js'));
47
+ const polyfillsName = fs
48
+ .readdirSync(outputPath)
49
+ .find((f) => f.startsWith('polyfills.') && f.endsWith('.js'));
50
+ const htmlFragment = `
51
+ <script type="esms-options">
52
+ {
53
+ "shimMode": true
54
+ }
55
+ </script>
56
+
57
+ <script type="module" src="${polyfillsName}"></script>
58
+ <script type="module-shim" src="${mainName}"></script>
59
+ `;
60
+ const indexContent = fs.readFileSync(indexPath, 'utf-8');
61
+ const updatedContent = indexContent.replace('</body>', `${htmlFragment}</body>`);
62
+ fs.writeFileSync(indexPath, updatedContent, 'utf-8');
63
+ }
64
+ function build(config, options, context) {
65
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
66
+ const esbuildConfiguration = (options) => {
67
+ options.plugins = [
68
+ ...options.plugins,
69
+ (0, shared_mappings_plugin_1.createSharedMappingsPlugin)(config.sharedMappings),
70
+ ];
71
+ return options;
72
+ };
73
+ // TODO: Remove cast to any after updating version
74
+ const output = yield (0, index_1.buildEsbuildBrowser)(options, context, {
75
+ esbuildConfiguration,
76
+ });
77
+ return output;
78
+ });
79
+ }
80
+ function writeImportMap(sharedInfo, context, options) {
81
+ const imports = sharedInfo.reduce((acc, cur) => {
82
+ return Object.assign(Object.assign({}, acc), { [cur.packageName]: cur.outFileName });
83
+ }, {});
84
+ const importMap = { imports };
85
+ const importMapPath = path.join(context.workspaceRoot, options.outputPath, 'importmap.json');
86
+ fs.writeFileSync(importMapPath, JSON.stringify(importMap, null, 2));
87
+ }
88
+ function writeFederationInfo(federationInfo, context, options) {
89
+ const metaDataPath = path.join(context.workspaceRoot, options.outputPath, 'remoteEntry.json');
90
+ fs.writeFileSync(metaDataPath, JSON.stringify(federationInfo, null, 2));
91
+ }
92
+ function bundleShared(config, options, context, externals) {
93
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
94
+ const result = [];
95
+ const packageInfos = Object.keys(config.shared)
96
+ .filter(packageName => !DEFAULT_SKIP_LIST.has(packageName))
97
+ .map(packageName => (0, package_info_1.getPackageInfo)(packageName, context))
98
+ .filter((pi) => !!pi);
99
+ for (const pi of packageInfos) {
100
+ console.info('Bundling shared package', pi.packageName, '...');
101
+ const encName = pi.packageName.replace(/[^A-Za-z0-9]/g, '_');
102
+ const encVersion = pi.version.replace(/[^A-Za-z0-9]/g, '_');
103
+ const outFileName = `${encName}-${encVersion}.js`;
104
+ const cachePath = path.join(context.workspaceRoot, 'node_modules/.cache/native-federation');
105
+ fs.mkdirSync(cachePath, { recursive: true });
106
+ const cachedFile = path.join(cachePath, outFileName);
107
+ if (!fs.existsSync(cachedFile)) {
108
+ yield (0, build_utils_1.bundle)({
109
+ entryPoint: pi.entryPoint,
110
+ tsConfigPath: options.tsConfig,
111
+ external: externals,
112
+ outfile: cachedFile,
113
+ mappedPaths: config.sharedMappings,
114
+ useSharedMappingPlugin: true,
115
+ });
116
+ }
117
+ const shared = config.shared[pi.packageName];
118
+ result.push({
119
+ packageName: pi.packageName,
120
+ outFileName: outFileName,
121
+ requiredVersion: shared.requiredVersion,
122
+ singleton: shared.singleton,
123
+ strictVersion: shared.strictVersion,
124
+ version: pi.version,
125
+ });
126
+ const fullOutputPath = path.join(context.workspaceRoot, options.outputPath, outFileName);
127
+ fs.copyFileSync(cachedFile, fullOutputPath);
128
+ copySrcMapIfExists(cachedFile, fullOutputPath);
129
+ }
130
+ return result;
131
+ });
132
+ }
133
+ function copySrcMapIfExists(cachedFile, fullOutputPath) {
134
+ const mapSrc = cachedFile + '.map';
135
+ const mapDest = fullOutputPath + '.map';
136
+ if (fs.existsSync(mapSrc)) {
137
+ fs.copyFileSync(mapSrc, mapDest);
138
+ }
139
+ }
140
+ function bundleSharedMappings(config, options, context, externals) {
141
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
142
+ const result = [];
143
+ for (const m of config.sharedMappings) {
144
+ const key = m.key.replace(/[^A-Za-z0-9]/g, '_');
145
+ const outFileName = key + '.js';
146
+ const outFilePath = path.join(options.outputPath, outFileName);
147
+ console.info('Bundling shared mapping', m.key, '...');
148
+ try {
149
+ yield (0, build_utils_1.bundle)({
150
+ entryPoint: m.path,
151
+ tsConfigPath: options.tsConfig,
152
+ external: externals,
153
+ outfile: outFilePath,
154
+ mappedPaths: config.sharedMappings,
155
+ useSharedMappingPlugin: false,
156
+ });
157
+ const hash = (0, hash_file_1.hashFile)(outFilePath);
158
+ const hashedOutFileName = `${key}-${hash}.js`;
159
+ const hashedOutFilePath = path.join(options.outputPath, hashedOutFileName);
160
+ fs.renameSync(outFilePath, hashedOutFilePath);
161
+ result.push({
162
+ packageName: m.key,
163
+ outFileName: hashedOutFileName,
164
+ requiredVersion: '',
165
+ singleton: true,
166
+ strictVersion: false,
167
+ version: '',
168
+ });
169
+ }
170
+ catch (e) {
171
+ context.logger.error('Error bundling shared mapping ' + m.key);
172
+ context.logger.error(` >> If you don't need this mapping to shared, you can explicity configure the sharedMappings property in your federation.config.js`);
173
+ if (options.verbose) {
174
+ console.error(e);
175
+ }
176
+ }
177
+ }
178
+ return result;
179
+ });
180
+ }
181
+ function bundleExposed(config, options, externals) {
182
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
183
+ const result = [];
184
+ for (const key in config.exposes) {
185
+ const outFileName = key + '.js';
186
+ const outFilePath = path.join(options.outputPath, outFileName);
187
+ const entryPoint = config.exposes[key];
188
+ console.info('Bundle exposed file', entryPoint, '...');
189
+ yield (0, build_utils_1.bundle)({
190
+ entryPoint,
191
+ tsConfigPath: options.tsConfig,
192
+ external: externals,
193
+ outfile: outFilePath,
194
+ mappedPaths: config.sharedMappings,
195
+ useSharedMappingPlugin: true,
196
+ });
197
+ const hash = (0, hash_file_1.hashFile)(outFilePath);
198
+ const hashedOutFileName = `${key}-${hash}.js`;
199
+ const hashedOutFilePath = path.join(options.outputPath, hashedOutFileName);
200
+ fs.renameSync(outFilePath, hashedOutFilePath);
201
+ result.push({ key, outFileName: hashedOutFileName });
202
+ }
203
+ return result;
204
+ });
205
+ }
206
+ function getExternals(config) {
207
+ const shared = Object.keys(config.shared);
208
+ const sharedMappings = config.sharedMappings.map((m) => m.key);
209
+ const externals = [...shared, ...sharedMappings];
210
+ return externals.filter((p) => !DEFAULT_SKIP_LIST.has(p));
211
+ }
212
+ function loadFederationConfig(options, context) {
213
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
214
+ const relProjectPath = path.dirname(options.tsConfig);
215
+ const fullProjectPath = path.join(context.workspaceRoot, relProjectPath);
216
+ const fullConfigPath = path.join(fullProjectPath, 'federation.config.js');
217
+ if (!fs.existsSync(fullConfigPath)) {
218
+ throw new Error('Expected ' + fullConfigPath);
219
+ }
220
+ const config = (yield Promise.resolve().then(() => require(fullConfigPath)));
221
+ return config;
222
+ });
223
+ }
224
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../../../../libs/native-federation/src/builders/build/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { JsonObject } from '@angular-devkit/core';
2
+
3
+ export interface BuildBuilderSchema extends JsonObject {} // eslint-disable-line