@angular-architects/native-federation-v4 21.1.6 → 21.1.8

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 (55) hide show
  1. package/collection.json +5 -0
  2. package/migration-collection.json +6 -0
  3. package/package.json +11 -3
  4. package/src/builders/build/builder.d.ts.map +1 -1
  5. package/src/builders/build/builder.js +112 -95
  6. package/src/builders/build/schema.d.ts +3 -4
  7. package/src/builders/build/schema.json +8 -26
  8. package/src/builders/build/setup-builder-env-variables.js +3 -1
  9. package/src/config/angular-skip-list.d.ts +3 -0
  10. package/src/config/angular-skip-list.d.ts.map +1 -0
  11. package/src/config/angular-skip-list.js +13 -0
  12. package/src/config/share-utils.d.ts +9 -0
  13. package/src/config/share-utils.d.ts.map +1 -0
  14. package/src/config/share-utils.js +32 -0
  15. package/src/config.d.ts +2 -2
  16. package/src/config.d.ts.map +1 -1
  17. package/src/config.js +2 -2
  18. package/src/schematics/init/files/federation.config.js__tmpl__ +19 -7
  19. package/src/schematics/init/schema.d.ts +0 -1
  20. package/src/schematics/init/schema.json +2 -6
  21. package/src/schematics/init/schematic.d.ts.map +1 -1
  22. package/src/schematics/init/schematic.js +50 -25
  23. package/src/schematics/update-v4/schema.d.ts +4 -0
  24. package/src/schematics/update-v4/schema.json +23 -0
  25. package/src/schematics/update-v4/schematic.d.ts +4 -0
  26. package/src/schematics/update-v4/schematic.d.ts.map +1 -0
  27. package/src/schematics/update-v4/schematic.js +225 -0
  28. package/src/utils/angular-bundler.d.ts +7 -0
  29. package/src/utils/angular-bundler.d.ts.map +1 -0
  30. package/src/utils/angular-bundler.js +120 -0
  31. package/src/utils/angular-esbuild-adapter.d.ts +8 -3
  32. package/src/utils/angular-esbuild-adapter.d.ts.map +1 -1
  33. package/src/utils/angular-esbuild-adapter.js +63 -245
  34. package/src/utils/angular-locales.d.ts.map +1 -1
  35. package/src/utils/create-federation-tsconfig.d.ts +6 -0
  36. package/src/utils/create-federation-tsconfig.d.ts.map +1 -0
  37. package/src/utils/create-federation-tsconfig.js +49 -0
  38. package/src/utils/get-fallback-platform.d.ts +3 -0
  39. package/src/utils/get-fallback-platform.d.ts.map +1 -0
  40. package/src/utils/get-fallback-platform.js +13 -0
  41. package/src/utils/node-modules-bundler.d.ts +7 -0
  42. package/src/utils/node-modules-bundler.d.ts.map +1 -0
  43. package/src/utils/node-modules-bundler.js +109 -0
  44. package/src/utils/normalize-context-options.d.ts +23 -0
  45. package/src/utils/normalize-context-options.d.ts.map +1 -0
  46. package/src/utils/normalize-context-options.js +18 -0
  47. package/src/utils/shared-mappings-plugin.d.ts +2 -2
  48. package/src/utils/shared-mappings-plugin.d.ts.map +1 -1
  49. package/src/utils/shared-mappings-plugin.js +4 -4
  50. package/src/utils/create-compiler-options.d.ts +0 -6
  51. package/src/utils/create-compiler-options.d.ts.map +0 -1
  52. package/src/utils/create-compiler-options.js +0 -41
  53. package/src/utils/mem-resuts.d.ts +0 -29
  54. package/src/utils/mem-resuts.d.ts.map +0 -1
  55. package/src/utils/mem-resuts.js +0 -50
package/collection.json CHANGED
@@ -22,6 +22,11 @@
22
22
  "factory": "./src/schematics/appbuilder/schematic",
23
23
  "schema": "./src/schematics/appbuilder/schema.json",
24
24
  "description": "Migrates for using the appbuilder"
25
+ },
26
+ "update-v4": {
27
+ "factory": "./src/schematics/update-v4/schematic",
28
+ "schema": "./src/schematics/update-v4/schema.json",
29
+ "description": "Migrates from native-federation v3 to v4"
25
30
  }
26
31
  }
27
32
  }
@@ -8,6 +8,12 @@
8
8
  "factory": "./src/schematics/update18/schematic",
9
9
  "schema": "./src/schematics/update18/schema.json",
10
10
  "description": "migrating to v18"
11
+ },
12
+ "update-v4": {
13
+ "version": "21.2.0-beta.0",
14
+ "factory": "./src/schematics/update-v4/schematic",
15
+ "schema": "./src/schematics/update-v4/schema.json",
16
+ "description": "migrating from native-federation v3 to v4"
11
17
  }
12
18
  }
13
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-architects/native-federation-v4",
3
- "version": "21.1.6",
3
+ "version": "21.1.8",
4
4
  "generators": "./collection.json",
5
5
  "builders": "./builders.json",
6
6
  "schematics": "./collection.json",
@@ -9,9 +9,17 @@
9
9
  "name": "Manfred Steyer",
10
10
  "url": "http://www.angulararchitects.io"
11
11
  },
12
+ "peerDependencies": {
13
+ "@softarc/native-federation": "^4.0.0-RC9",
14
+ "@softarc/native-federation-runtime": "^4.0.0-RC9",
15
+ "@angular-devkit/architect": ">=0.2102.0",
16
+ "@angular-devkit/build-angular": ">=21.2.0",
17
+ "@angular-devkit/core": ">=21.2.0",
18
+ "@angular/build": ">=21.2.0"
19
+ },
12
20
  "dependencies": {
13
- "@softarc/native-federation": "4.0.0-RC6",
14
- "@softarc/native-federation-runtime": "4.0.0-RC6",
21
+ "@softarc/native-federation": "4.0.0-RC9",
22
+ "@softarc/native-federation-runtime": "4.0.0-RC9",
15
23
  "@angular-devkit/architect": "^0.2102.0",
16
24
  "@angular-devkit/build-angular": "^21.2.0",
17
25
  "@angular-devkit/core": "^21.2.0",
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../src/builders/build/builder.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC;AAS1C,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,aAAa,EAGnB,MAAM,2BAA2B,CAAC;AAiCnC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAyCnD,wBAAuB,UAAU,CAC/B,gBAAgB,EAAE,eAAe,EACjC,OAAO,EAAE,cAAc,GACtB,aAAa,CAAC,aAAa,CAAC,CAuW9B;wBA6C2C,GAAG;AAA/C,wBAAgD"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../src/builders/build/builder.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC;AAS1C,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,aAAa,EAGnB,MAAM,2BAA2B,CAAC;AA+BnC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AA2CnD,wBAAuB,UAAU,CAC/B,gBAAgB,EAAE,eAAe,EACjC,OAAO,EAAE,cAAc,GACtB,aAAa,CAAC,aAAa,CAAC,CA8X9B;wBA6C2C,GAAG;AAA/C,wBAAgD"}
@@ -6,15 +6,13 @@ import { buildApplication } from '@angular/build';
6
6
  import { buildApplicationInternal, serveWithVite, SourceFileCache } from '@angular/build/private';
7
7
  import { createBuilder, targetFromTargetString, } from '@angular-devkit/architect';
8
8
  import { normalizeOptions } from '@angular-devkit/build-angular/src/builders/dev-server/options.js';
9
- import { buildForFederation, rebuildForFederation, getExternals, loadFederationConfig, normalizeFederationOptions, setBuildAdapter, createFederationCache,
10
- // type FederationCache,
11
- } from '@softarc/native-federation';
9
+ import { buildForFederation, rebuildForFederation, getExternals, normalizeFederationOptions, setBuildAdapter, createFederationCache, } from '@softarc/native-federation';
12
10
  import { logger, setLogLevel, RebuildQueue, AbortedError, getDefaultCachePath, } from '@softarc/native-federation/internal';
13
11
  import { createAngularBuildAdapter } from '../../utils/angular-esbuild-adapter.js';
14
12
  import { existsSync, mkdirSync, rmSync } from 'fs';
15
13
  import { fstart } from '../../tools/fstart-as-data-url.js';
16
14
  import { getI18nConfig, translateFederationArtifacts } from '../../utils/i18n.js';
17
- import { createSharedMappingsPlugin } from '../../utils/shared-mappings-plugin.js';
15
+ // import { createSharedMappingsPlugin } from '../../utils/shared-mappings-plugin.js';
18
16
  import { updateScriptTags } from '../../utils/updateIndexHtml.js';
19
17
  import { federationBuildNotifier } from './federation-build-notifier.js';
20
18
  const originalWrite = process.stderr.write.bind(process.stderr);
@@ -38,6 +36,7 @@ const createInternalAngularBuilder = (_) => (options, context, pluginsOrExtensio
38
36
  else {
39
37
  extensions = pluginsOrExtensions;
40
38
  }
39
+ // Todo: share cache with Angular builder: https://github.com/angular/angular-cli/pull/32527
41
40
  // options.codeBundleCache = nfOptions.federationCache.bundlerCache;
42
41
  return buildApplicationInternal(options, context, extensions);
43
42
  };
@@ -71,7 +70,7 @@ export async function* runBuilder(nfBuilderOptions, context) {
71
70
  const runServer = typeof nfBuilderOptions.devServer !== 'undefined'
72
71
  ? !!nfBuilderOptions.devServer
73
72
  : target.target.includes('serve');
74
- let options = (await context.validateOptions(runServer
73
+ let ngBuilderOptions = (await context.validateOptions(runServer
75
74
  ? {
76
75
  ...targetOptions,
77
76
  port: nfBuilderOptions.port || targetOptions['port'],
@@ -79,27 +78,27 @@ export async function* runBuilder(nfBuilderOptions, context) {
79
78
  : targetOptions, builder));
80
79
  let serverOptions = null;
81
80
  const watch = nfBuilderOptions.watch;
82
- if (options['buildTarget']) {
83
- serverOptions = await normalizeOptions(context, context.target.project, options);
84
- target = targetFromTargetString(options['buildTarget']);
81
+ if (ngBuilderOptions['buildTarget']) {
82
+ serverOptions = await normalizeOptions(context, context.target.project, ngBuilderOptions);
83
+ target = targetFromTargetString(ngBuilderOptions['buildTarget']);
85
84
  targetOptions = (await context.getTargetOptions(target));
86
85
  builder = await context.getBuilderNameForTarget(target);
87
- options = (await context.validateOptions(targetOptions, builder));
86
+ ngBuilderOptions = (await context.validateOptions(targetOptions, builder));
88
87
  }
89
- options.watch = watch;
88
+ ngBuilderOptions.watch = watch;
90
89
  if (nfBuilderOptions.baseHref) {
91
- options.baseHref = nfBuilderOptions.baseHref;
90
+ ngBuilderOptions.baseHref = nfBuilderOptions.baseHref;
92
91
  }
93
92
  if (nfBuilderOptions.outputPath) {
94
- options.outputPath = nfBuilderOptions.outputPath;
93
+ ngBuilderOptions.outputPath = nfBuilderOptions.outputPath;
95
94
  }
96
- const adapter = createAngularBuildAdapter(options, context);
95
+ const adapter = createAngularBuildAdapter(ngBuilderOptions, context);
97
96
  setBuildAdapter(adapter);
98
- setLogLevel(options.verbose ? 'verbose' : 'info');
99
- if (!options.outputPath) {
100
- options.outputPath = `dist/${context.target.project}`;
97
+ setLogLevel(ngBuilderOptions.verbose ? 'verbose' : 'info');
98
+ if (!ngBuilderOptions.outputPath) {
99
+ ngBuilderOptions.outputPath = `dist/${context.target.project}`;
101
100
  }
102
- const outputPath = options.outputPath;
101
+ const outputPath = ngBuilderOptions.outputPath;
103
102
  const outputOptions = {
104
103
  browser: 'browser',
105
104
  server: 'server',
@@ -108,37 +107,37 @@ export async function* runBuilder(nfBuilderOptions, context) {
108
107
  base: typeof outputPath === 'string' ? outputPath : outputPath.base,
109
108
  };
110
109
  const i18n = await getI18nConfig(context);
111
- const localeFilter = getLocaleFilter(options, runServer);
110
+ const localeFilter = getLocaleFilter(ngBuilderOptions, runServer);
112
111
  const sourceLocaleSegment = typeof i18n?.sourceLocale === 'string'
113
112
  ? i18n.sourceLocale
114
113
  : i18n?.sourceLocale?.subPath || i18n?.sourceLocale?.code || '';
115
- const browserOutputPath = path.join(outputOptions.base, outputOptions.browser, options.localize ? sourceLocaleSegment : '');
114
+ const browserOutputPath = path.join(outputOptions.base, outputOptions.browser, ngBuilderOptions.localize ? sourceLocaleSegment : '');
116
115
  const differentDevServerOutputPath = Array.isArray(localeFilter) && localeFilter.length === 1;
117
116
  const devServerOutputPath = !differentDevServerOutputPath
118
117
  ? browserOutputPath
119
118
  : path.join(outputOptions.base, outputOptions.browser, localeFilter[0]);
120
- const entryPoint = path.join(path.dirname(options.tsConfig), 'src/main.ts');
119
+ const entryPoints = nfBuilderOptions.entryPoints && nfBuilderOptions.entryPoints.length > 0
120
+ ? nfBuilderOptions.entryPoints
121
+ : [path.join(path.dirname(ngBuilderOptions.tsConfig), 'src/main.ts')];
121
122
  const cachePath = getDefaultCachePath(context.workspaceRoot);
122
- const nfOptions = normalizeFederationOptions({
123
+ const normalized = await normalizeFederationOptions({
124
+ projectName: nfBuilderOptions.projectName,
123
125
  workspaceRoot: context.workspaceRoot,
124
126
  outputPath: browserOutputPath,
125
- federationConfig: inferConfigPath(options.tsConfig),
126
- tsConfig: options.tsConfig,
127
- verbose: options.verbose,
128
- watch: options.watch,
127
+ federationConfig: inferConfigPath(ngBuilderOptions.tsConfig),
128
+ tsConfig: ngBuilderOptions.tsConfig,
129
+ verbose: ngBuilderOptions.verbose,
130
+ watch: ngBuilderOptions.watch,
129
131
  dev: !!nfBuilderOptions.dev,
130
- chunks: !nfBuilderOptions.chunks ? false : nfBuilderOptions.chunks,
131
- entryPoint,
132
+ entryPoints,
132
133
  buildNotifications: nfBuilderOptions.buildNotifications,
133
- cacheExternalArtifacts: nfBuilderOptions.cacheExternalArtifacts,
134
+ cacheExternalArtifacts: nfBuilderOptions.cacheExternalArtifacts !== false,
134
135
  }, createFederationCache(cachePath, new SourceFileCache(cachePath)));
135
136
  const activateSsr = nfBuilderOptions.ssr && !nfBuilderOptions.dev;
136
137
  const start = process.hrtime();
137
- const config = await loadFederationConfig(nfOptions);
138
138
  logger.measure(start, 'To load the federation config.');
139
- const externals = getExternals(config);
139
+ const externals = getExternals(normalized.config);
140
140
  const plugins = [
141
- createSharedMappingsPlugin(config.sharedMappings),
142
141
  {
143
142
  name: 'externals',
144
143
  setup(build) {
@@ -150,7 +149,7 @@ export async function* runBuilder(nfBuilderOptions, context) {
150
149
  ];
151
150
  // SSR build fails when externals are provided via the plugin
152
151
  if (activateSsr) {
153
- options.externalDependencies = externals;
152
+ ngBuilderOptions.externalDependencies = externals;
154
153
  }
155
154
  const isLocalDevelopment = runServer && nfBuilderOptions.dev;
156
155
  // Initialize SSE reloader only for local development
@@ -160,12 +159,12 @@ export async function* runBuilder(nfBuilderOptions, context) {
160
159
  const middleware = [
161
160
  ...(isLocalDevelopment
162
161
  ? [
163
- federationBuildNotifier.createEventMiddleware(req => removeBaseHref(req, options.baseHref)),
162
+ federationBuildNotifier.createEventMiddleware(req => removeBaseHref(req, ngBuilderOptions.baseHref)),
164
163
  ]
165
164
  : []),
166
165
  (req, res, next) => {
167
- const url = removeBaseHref(req, options.baseHref);
168
- const fileName = path.join(nfOptions.workspaceRoot, devServerOutputPath, url);
166
+ const url = removeBaseHref(req, ngBuilderOptions.baseHref);
167
+ const fileName = path.join(normalized.options.workspaceRoot, devServerOutputPath, url);
169
168
  const exists = fs.existsSync(fileName);
170
169
  if (url !== '/' && url !== '' && exists) {
171
170
  const lookup = mrmime.lookup;
@@ -188,25 +187,22 @@ export async function* runBuilder(nfBuilderOptions, context) {
188
187
  },
189
188
  ];
190
189
  let first = true;
191
- let lastResult;
192
- if (existsSync(nfOptions.outputPath)) {
193
- rmSync(nfOptions.outputPath, { recursive: true });
190
+ if (existsSync(normalized.options.outputPath)) {
191
+ rmSync(normalized.options.outputPath, { recursive: true });
194
192
  }
195
- if (!existsSync(nfOptions.outputPath)) {
196
- mkdirSync(nfOptions.outputPath, { recursive: true });
193
+ if (!existsSync(normalized.options.outputPath)) {
194
+ mkdirSync(normalized.options.outputPath, { recursive: true });
197
195
  }
198
196
  let federationResult;
199
197
  try {
200
- const start = process.hrtime();
201
- federationResult = await buildForFederation(config, nfOptions, externals);
202
- logger.measure(start, 'To build the artifacts.');
198
+ federationResult = await buildForFederation(normalized.config, normalized.options, externals);
203
199
  }
204
200
  catch (e) {
205
201
  logger.error(e?.message ?? 'Building the artifacts failed');
206
202
  process.exit(1);
207
203
  }
208
204
  if (activateSsr) {
209
- writeFstartScript(nfOptions);
205
+ writeFstartScript(normalized.options);
210
206
  }
211
207
  const hasLocales = i18n?.locales && Object.keys(i18n.locales).length > 0;
212
208
  if (hasLocales && localeFilter) {
@@ -214,76 +210,97 @@ export async function* runBuilder(nfBuilderOptions, context) {
214
210
  translateFederationArtifacts(i18n, localeFilter, outputOptions.base, federationResult);
215
211
  logger.measure(start, 'To translate the artifacts.');
216
212
  }
217
- options.deleteOutputPath = false;
213
+ ngBuilderOptions.deleteOutputPath = false;
218
214
  const appBuilderName = '@angular/build:application';
219
215
  const builderRun = runServer
220
- ? serveWithVite(serverOptions, appBuilderName, createInternalAngularBuilder(nfOptions), context, nfBuilderOptions.skipHtmlTransform
216
+ ? serveWithVite(serverOptions, appBuilderName, createInternalAngularBuilder(normalized.options), context, nfBuilderOptions.skipHtmlTransform
221
217
  ? {}
222
218
  : { indexHtml: transformIndexHtml(nfBuilderOptions) }, {
223
219
  buildPlugins: plugins,
224
220
  middleware,
225
221
  })
226
- : buildApplication(options, context, {
222
+ : buildApplication(ngBuilderOptions, context, {
227
223
  codePlugins: plugins,
228
224
  indexHtmlTransformer: transformIndexHtml(nfBuilderOptions),
229
225
  });
230
226
  const rebuildQueue = new RebuildQueue();
227
+ const builderIterator = builderRun[Symbol.asyncIterator]();
228
+ let ngBuildStatus = { success: false };
231
229
  try {
232
- for await (const output of builderRun) {
233
- lastResult = output;
234
- if (!first && (nfBuilderOptions.dev || watch)) {
235
- rebuildQueue
236
- .enqueue(async (signal) => {
237
- if (signal?.aborted) {
238
- throw new AbortedError('Build canceled before starting');
239
- }
240
- await new Promise((resolve, reject) => {
241
- const timeout = setTimeout(resolve, Math.max(10, nfBuilderOptions.rebuildDelay));
242
- if (signal) {
243
- const abortHandler = () => {
244
- clearTimeout(timeout);
245
- reject(new AbortedError('[builder] During delay.'));
246
- };
247
- signal.addEventListener('abort', abortHandler, { once: true });
230
+ let buildResult = await builderIterator.next();
231
+ while (!buildResult.done) {
232
+ if (buildResult.value)
233
+ ngBuildStatus = buildResult.value;
234
+ if (!ngBuildStatus.success) {
235
+ logger.warn('Skipping federation artifacts because Angular build failed.');
236
+ buildResult = await builderIterator.next();
237
+ }
238
+ else if (!first && (nfBuilderOptions.dev || watch)) {
239
+ const nextOutputPromise = builderIterator.next();
240
+ const trackResult = await rebuildQueue.track(async (signal) => {
241
+ try {
242
+ if (signal?.aborted) {
243
+ throw new AbortedError('Build canceled before starting');
248
244
  }
249
- });
250
- if (signal?.aborted) {
251
- throw new AbortedError('[builder] Before federation build.');
252
- }
253
- const start = process.hrtime();
254
- // Invalidate all source files, Angular doesn't provide a way to give the invalidated files yet.
255
- const keys = new Set([...nfOptions.federationCache.bundlerCache.keys()].filter(k => !k.includes('node_modules')));
256
- nfOptions.federationCache.bundlerCache.invalidate(keys);
257
- federationResult = await rebuildForFederation(config, nfOptions, externals, [], signal);
258
- if (signal?.aborted) {
259
- throw new AbortedError('[builder] After federation build.');
260
- }
261
- if (hasLocales && localeFilter) {
262
- translateFederationArtifacts(i18n, localeFilter, outputOptions.base, federationResult);
263
- }
264
- if (signal?.aborted) {
265
- throw new AbortedError('[builder] After federation translations.');
266
- }
267
- logger.info('Done!');
268
- if (isLocalDevelopment) {
269
- federationBuildNotifier.broadcastBuildCompletion();
270
- }
271
- logger.measure(start, 'To rebuild the federation artifacts.');
272
- })
273
- .catch(error => {
274
- if (error instanceof AbortedError) {
275
- logger.verbose('Rebuild was canceled. Cancellation point: ' + error?.message);
276
- federationBuildNotifier.broadcastBuildCancellation();
245
+ await new Promise((resolve, reject) => {
246
+ const timeout = setTimeout(resolve, Math.max(10, nfBuilderOptions.rebuildDelay));
247
+ if (signal) {
248
+ const abortHandler = () => {
249
+ clearTimeout(timeout);
250
+ reject(new AbortedError('[builder] During delay.'));
251
+ };
252
+ signal.addEventListener('abort', abortHandler, { once: true });
253
+ }
254
+ });
255
+ if (signal?.aborted) {
256
+ throw new AbortedError('[builder] Before federation build.');
257
+ }
258
+ // Todo: Invalidate all source files, Angular doesn't provide a way to give the invalidated files yet.
259
+ // ref: https://github.com/angular/angular-cli/pull/32527
260
+ const keys = [...normalized.options.federationCache.bundlerCache.keys()].filter(k => !k.includes('node_modules'));
261
+ federationResult = await rebuildForFederation(normalized.config, normalized.options, externals, keys, signal);
262
+ if (signal?.aborted) {
263
+ throw new AbortedError('[builder] After federation build.');
264
+ }
265
+ if (hasLocales && localeFilter) {
266
+ translateFederationArtifacts(i18n, localeFilter, outputOptions.base, federationResult);
267
+ }
268
+ if (signal?.aborted) {
269
+ throw new AbortedError('[builder] After federation translations.');
270
+ }
271
+ logger.info('Done!');
272
+ if (isLocalDevelopment) {
273
+ federationBuildNotifier.broadcastBuildCompletion();
274
+ }
275
+ return { success: true };
277
276
  }
278
- else {
277
+ catch (error) {
278
+ if (error instanceof AbortedError) {
279
+ logger.verbose('Rebuild was canceled. Cancellation point: ' + error?.message);
280
+ federationBuildNotifier.broadcastBuildCancellation();
281
+ return { success: false, cancelled: true };
282
+ }
279
283
  logger.error('Federation rebuild failed!');
280
- if (options.verbose)
284
+ if (ngBuilderOptions.verbose)
281
285
  console.error(error);
282
286
  if (isLocalDevelopment) {
283
287
  federationBuildNotifier.broadcastBuildError(error);
284
288
  }
289
+ return { success: false };
285
290
  }
286
- });
291
+ }, nextOutputPromise);
292
+ if (trackResult.type === 'completed') {
293
+ if (!trackResult.result.cancelled) {
294
+ yield { success: trackResult.result.success };
295
+ }
296
+ buildResult = await nextOutputPromise;
297
+ }
298
+ else {
299
+ buildResult = trackResult.value;
300
+ }
301
+ }
302
+ else {
303
+ buildResult = await builderIterator.next();
287
304
  }
288
305
  first = false;
289
306
  }
@@ -295,7 +312,7 @@ export async function* runBuilder(nfBuilderOptions, context) {
295
312
  federationBuildNotifier.stopEventServer();
296
313
  }
297
314
  }
298
- yield lastResult || { success: false };
315
+ yield ngBuildStatus;
299
316
  }
300
317
  function removeBaseHref(req, baseHref) {
301
318
  let url = req.url ?? '';
@@ -6,17 +6,16 @@ export interface NfBuilderSchema extends JsonObject {
6
6
  target: string;
7
7
  dev: boolean;
8
8
  port: number;
9
- open: boolean;
10
9
  rebuildDelay: number;
11
10
  buildNotifications?: BuildNotificationOptions;
12
- shell: string;
13
11
  watch: boolean;
14
12
  skipHtmlTransform: boolean;
15
13
  esmsInitOptions: ESMSInitOptions;
16
14
  baseHref?: string;
17
15
  outputPath?: string;
16
+ projectName?: string;
18
17
  ssr: boolean;
19
18
  devServer?: boolean;
20
- chunks?: { enable: boolean; dense: true };
19
+ entryPoints?: string[];
21
20
  cacheExternalArtifacts?: boolean;
22
- } // eslint-disable-line
21
+ }
@@ -23,22 +23,14 @@
23
23
  "type": "number",
24
24
  "default": 0
25
25
  },
26
- "open": {
27
- "type": "boolean",
28
- "default": true,
29
- "description": "Open browser?",
30
- "alias": "o"
26
+ "entryPoints": {
27
+ "type": "array"
31
28
  },
32
29
  "rebuildDelay": {
33
30
  "type": "number",
34
31
  "default": 2000,
35
32
  "description": "The delay for rebuilding federation artifacts. This allows to have more resources for refreshing your micro frontend in the browser."
36
33
  },
37
- "shell": {
38
- "type": "string",
39
- "description": "Experimental",
40
- "default": ""
41
- },
42
34
  "skipHtmlTransform": {
43
35
  "type": "boolean",
44
36
  "default": false
@@ -46,6 +38,9 @@
46
38
  "baseHref": {
47
39
  "type": "string"
48
40
  },
41
+ "projectName": {
42
+ "type": "string"
43
+ },
49
44
  "outputPath": {
50
45
  "type": "string"
51
46
  },
@@ -67,22 +62,9 @@
67
62
  },
68
63
  "cacheExternalArtifacts": {
69
64
  "type": "boolean",
70
- "description": "Will cache the shared externals so they can be re-used between builds"
71
- },
72
- "chunks": {
73
- "type": "object",
74
- "properties": {
75
- "enable": {
76
- "type": "boolean",
77
- "default": true,
78
- "description": "Enable chunking (code splitting)."
79
- },
80
- "dense": {
81
- "type": "boolean",
82
- "default": false,
83
- "description": "Allows for a more compact remoteEntry.json."
84
- }
85
- }
65
+ "default": true,
66
+ "description": "Will cache the shared externals so they can be re-used between builds",
67
+ "alias": "cache"
86
68
  },
87
69
  "buildNotifications": {
88
70
  "type": "object",
@@ -3,5 +3,7 @@
3
3
  * a shared cache between the compilation steps which
4
4
  * improves performance dramatically.
5
5
  */
6
- process.env['NG_BUILD_PARALLEL_TS'] = '0';
6
+ if (!process.env['NG_BUILD_PARALLEL_TS']) {
7
+ process.env['NG_BUILD_PARALLEL_TS'] = '0';
8
+ }
7
9
  export {};
@@ -0,0 +1,3 @@
1
+ import { type SkipList } from '@softarc/native-federation/config';
2
+ export declare const NG_SKIP_LIST: SkipList;
3
+ //# sourceMappingURL=angular-skip-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular-skip-list.d.ts","sourceRoot":"","sources":["../../../src/config/angular-skip-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAqB,MAAM,mCAAmC,CAAC;AAErF,eAAO,MAAM,YAAY,EAAE,QAW1B,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { DEFAULT_SKIP_LIST } from '@softarc/native-federation/config';
2
+ export const NG_SKIP_LIST = [
3
+ ...DEFAULT_SKIP_LIST,
4
+ '@angular-architects/native-federation',
5
+ 'zone.js',
6
+ '@angular/localize',
7
+ '@angular/localize/init',
8
+ '@angular/localize/tools',
9
+ '@angular/router/upgrade',
10
+ '@angular/common/upgrade',
11
+ /^@nx\/angular/,
12
+ pkg => pkg.startsWith('@angular/') && !!pkg.match(/\/testing(\/|$)/),
13
+ ];
@@ -0,0 +1,9 @@
1
+ import type { ShareAllExternalsOptions, ShareExternalsOptions, SkipList, FederationConfig } from '@softarc/native-federation/domain';
2
+ export declare function shareAll(config: ShareAllExternalsOptions, opts?: {
3
+ skipList?: SkipList;
4
+ projectPath?: string;
5
+ overrides?: ShareExternalsOptions;
6
+ }): ShareExternalsOptions | null;
7
+ export declare function share(configuredShareObjects: ShareExternalsOptions, projectPath?: string, skipList?: SkipList): ShareExternalsOptions;
8
+ export declare function withNativeFederation(cfg: FederationConfig): import("@softarc/native-federation/internal").NormalizedFederationConfig;
9
+ //# sourceMappingURL=share-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share-utils.d.ts","sourceRoot":"","sources":["../../../src/config/share-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,qBAAqB,EACrB,QAAQ,EACR,gBAAgB,EACjB,MAAM,mCAAmC,CAAC;AAS3C,wBAAgB,QAAQ,CACtB,MAAM,EAAE,wBAAwB,EAChC,IAAI,GAAE;IACJ,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,qBAAqB,CAAC;CAC9B,GACL,qBAAqB,GAAG,IAAI,CAG9B;AAED,wBAAgB,KAAK,CACnB,sBAAsB,EAAE,qBAAqB,EAC7C,WAAW,SAAK,EAChB,QAAQ,WAAe,GACtB,qBAAqB,CAEvB;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,4EAWzD"}
@@ -0,0 +1,32 @@
1
+ import { share as coreShare, shareAll as coreShareAll, withNativeFederation as coreWithNativeFederation, } from '@softarc/native-federation/config';
2
+ import { NG_SKIP_LIST } from './angular-skip-list.js';
3
+ export function shareAll(config, opts = {}) {
4
+ if (!opts.skipList)
5
+ opts.skipList = NG_SKIP_LIST;
6
+ return coreShareAll(config, opts);
7
+ }
8
+ export function share(configuredShareObjects, projectPath = '', skipList = NG_SKIP_LIST) {
9
+ return coreShare(configuredShareObjects, projectPath, skipList);
10
+ }
11
+ export function withNativeFederation(cfg) {
12
+ if (!cfg.platform)
13
+ cfg.platform = getDefaultPlatform(Object.keys(cfg.shared ?? {}));
14
+ const normalized = coreWithNativeFederation(cfg);
15
+ // This is for being backwards compatible
16
+ if (!normalized.features.ignoreUnusedDeps) {
17
+ normalized.shared = removeNgLocales(normalized.shared);
18
+ }
19
+ return normalized;
20
+ }
21
+ function getDefaultPlatform(deps) {
22
+ const server = deps.find(e => ['@angular/platform-server', '@angular/ssr'].find(f => e.startsWith(f)));
23
+ return server ? 'node' : 'browser';
24
+ }
25
+ function removeNgLocales(shared) {
26
+ const keys = Object.keys(shared).filter(k => !k.startsWith('@angular/common/locales'));
27
+ const filtered = keys.reduce((acc, curr) => ({
28
+ ...acc,
29
+ [curr]: shared[curr],
30
+ }), {});
31
+ return filtered;
32
+ }
package/src/config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from '@softarc/native-federation/config';
2
- export { DEFAULT_SKIP_LIST } from '@softarc/native-federation/config';
1
+ export { share, shareAll, withNativeFederation } from './config/share-utils.js';
2
+ export { NG_SKIP_LIST } from './config/angular-skip-list.js';
3
3
  export { shareAngularLocales } from './utils/angular-locales.js';
4
4
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
package/src/config.js CHANGED
@@ -1,3 +1,3 @@
1
- export * from '@softarc/native-federation/config';
2
- export { DEFAULT_SKIP_LIST } from '@softarc/native-federation/config';
1
+ export { share, shareAll, withNativeFederation } from './config/share-utils.js';
2
+ export { NG_SKIP_LIST } from './config/angular-skip-list.js';
3
3
  export { shareAngularLocales } from './utils/angular-locales.js';
@@ -1,6 +1,6 @@
1
- const { withNativeFederation, shareAll } = require('@angular-architects/native-federation/config');
1
+ import { withNativeFederation, shareAll } from '@angular-architects/native-federation-v4/config';
2
2
 
3
- module.exports = withNativeFederation({
3
+ export default withNativeFederation({
4
4
  name: '<%=project%>',
5
5
 
6
6
  <% if (type === 'remote') { %>
@@ -10,7 +10,18 @@ module.exports = withNativeFederation({
10
10
  },
11
11
  <% } %>
12
12
  shared: {
13
- ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
13
+ ...shareAll({
14
+ singleton: true, strictVersion: true, requiredVersion: 'auto'
15
+ }, {
16
+ overrides: {
17
+ '@angular/core': {
18
+ singleton: true, strictVersion: true, requiredVersion: 'auto', build: 'package', chunks: true, includeSecondaries: {keepAll: true},
19
+ },
20
+ '@angular/common': {
21
+ singleton: true, strictVersion: true, requiredVersion: 'auto', build: 'package',chunks: true, includeSecondaries: {keepAll: true},
22
+ }
23
+ }
24
+ }),
14
25
  },
15
26
 
16
27
  skip: [
@@ -25,9 +36,10 @@ module.exports = withNativeFederation({
25
36
  // https://shorturl.at/jmzH0
26
37
 
27
38
  features: {
28
- // New feature for more performance and avoiding
29
- // issues with node libs. Comment this out to
30
- // get the traditional behavior:
31
- ignoreUnusedDeps: true
39
+ // ignoreUnusedDeps is enabled by default now
40
+ // ignoreUnusedDeps: true,
41
+
42
+ // Opt-in: groups chunks in remoteEntry.json for smaller metadata file
43
+ denseChunking: true
32
44
  }
33
45
  });
@@ -1,6 +1,5 @@
1
1
  export interface NfSchematicSchema {
2
2
  project: string;
3
3
  port: string;
4
- nxBuilders: boolean | undefined;
5
4
  type: 'host' | 'dynamic-host' | 'remote';
6
5
  }