-
Notifications
You must be signed in to change notification settings - Fork 13
feat(dashboards-ng): support native federation #1265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Documentation. Coverage Reports: |
24d0951 to
0da8542
Compare
📝 WalkthroughWalkthroughThis PR introduces Native Federation (ESM-based module federation) as an alternative to the existing Webpack-based Module Federation approach. It adds new ESM build targets across multiple projects, introduces native-federation configuration files, creates widget loader registries for both native-federation and mf-bridge federation types, adds environment-specific configurations for ESM builds, and modifies the bootstrap flow to conditionally initialize either Module Federation or Native Federation based on environment configuration. The changes include new federation.config.js files, environment files, build configurations in angular.json, and integration of Sequence Diagram(s)sequenceDiagram
participant App as App Bootstrap
participant Env as Environment Config
participant NF as Native Federation Init
participant MF as Module Federation Instance
participant WL as Widget Loader Registry
participant RW as Remote Widget
App->>Env: Check useModuleFederation
alt useModuleFederation = true (Module Federation Path)
App->>WL: Load module-federation package
App->>WL: Register widget loader
App->>App: Bootstrap with appConfig
else useModuleFederation = false (Native Federation Path)
App->>NF: Call initFederation()
NF-->>App: Federation initialized
App->>NF: Get shared config
App->>MF: Create ModuleFederation instance
MF-->>App: mfInstance ready
App->>WL: Load native-federation package
App->>WL: Load mf-bridge package
App->>WL: Register native-federation loader
App->>WL: Register mf-bridge loader
App->>App: Bootstrap with appConfig
end
App->>RW: Load remote widget via factory
RW-->>App: Widget component loaded
sequenceDiagram
participant WF as Widget Factory
participant NL as Native Federation Loader
participant NF as Native Federation Runtime
participant RM as Remote Module
participant VCR as View Container Ref
WF->>NL: setupRemoteComponent(config)
NL->>NF: loadRemoteModule(config)
NF->>RM: Fetch remote module
RM-->>NF: Module loaded
NF-->>NL: Module content
NL->>NL: Resolve component type
NL->>VCR: Create component instance
VCR-->>NL: ComponentRef<T>
NL-->>WF: Observable<ComponentRef<T>>
Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
projects/dashboards-demo/tsconfig.app.prod.json (1)
4-11: Fix type-whitelist inconsistency in prod tsconfig: restorelocalize-types.The
types: ["node"]override removes@siemens/element-translate-ng/localize-types, creating an inconsistency with the non-prod variant (tsconfig.app.json) which includes both. Since the codebase uses@siemens/element-translate-ngmodules (e.g., provideNgxTranslateForElement, SiTranslatePipe), the prod config should match the non-prod setup to avoid type-checking failures.Recommended fix
"compilerOptions": { "outDir": "../../out-tsc/app", - "types": ["node"] + "types": ["@siemens/element-translate-ng/localize-types", "node"] },
🤖 Fix all issues with AI agents
In @.github/workflows/build-and-test.yaml:
- Around line 44-50: Update the two CI steps that run the ESM dashboard builds
to add the --progress=false flag for consistency: modify the run steps that
invoke "npm run dashboards-demo:build:esm" and "npm run
dashboards-demo:build:esm:mfe" so they include "-- --progress=false" like the
other dashboard build steps, ensuring quieter logs and consistent behavior
across builds.
In @playwright/e2e/dashboards-demo/dashboard.spec.ts:
- Around line 37-38: The detection of ESM build via
test.info().project.name.includes('esm') is brittle; update the logic that sets
stepName (currently using stepName = test.info().project.name.includes('esm') ?
'esm-edit' : 'edit') to read an explicit flag instead — either check a dedicated
environment variable (e.g., process.env.PLAYWRIGHT_BUILD === 'esm') or add a
custom property on the Playwright project config (e.g.,
test.info().project.metadata?.build === 'esm'), then pass that flag to determine
stepName and call si.runVisualAndA11yTests(stepName) accordingly.
In @projects/dashboards-demo/federation.config.js:
- Around line 31-32: Replace the shortened link "https://shorturl.at/jmzH0" in
the comment line "// Please read our FAQ about sharing libs:" with the full
direct URL to the FAQ documentation so the comment reads with a clear, permanent
destination (keep the existing comment text and simply swap the short URL for
the direct FAQ link).
In @projects/dashboards-demo/mfe/src/environments/environment.esm.ts:
- Around line 9-13: The exported environment object is missing the mfeEsmBaseUrl
property used by native federation; update the environment object in
environment.esm.ts (the exported "environment") to include mfeEsmBaseUrl:
'http://localhost:4205' alongside the existing mfeBaseUrl, webComponentsBaseUrl
and useModuleFederation entries so callers can safely read
environment.mfeEsmBaseUrl at runtime.
In @projects/dashboards-demo/mfe/src/main.esm.ts:
- Around line 7-9: initFederation() is being awaited only via .then(...) so
errors thrown by initFederation are not caught; change the chain to handle
failures from both initFederation and the dynamic bootstrap import by attaching
a .catch to the initFederation promise (or convert to an async IIFE with
try/catch) and log the error via console.error (or the project logger) including
context; specifically update the call site that currently calls
initFederation().then(() => { import('./bootstrap').catch(err =>
console.error(err)); }); to ensure any rejection from initFederation or from
import('./bootstrap') is caught and reported.
In @projects/dashboards-demo/mfe/tsconfig.app.json:
- Line 5: Remove the "node" entry from the tsconfig app's "types" array (i.e.,
delete "types": ["node"] or remove only the "node" element) in tsconfig.app.json
so the project no longer includes Node type definitions that conflict with
browser/DOM types; if the "types" array becomes empty you can remove the entire
"types" property.
In @projects/dashboards-demo/src/main.ts:
- Around line 40-48: The Promise.all(...).then(...) block should be converted to
async/await for consistency: await the two dynamic imports using const [m,
bridge] = await Promise.all([...]); then call
m.registerNativeFederatedWidgetLoader() and
bridge.registerModuleFederatedWidgetLoader(mfInstance) before awaiting the
dynamic bootstrap import (await import('./bootstrap')); ensure this code runs
inside an async context (or use top-level await if supported) so the awaited
operations behave the same as the original .then chain.
- Around line 8-49: Wrap the entire top-level async IIFE body in a try/catch and
add specific catches for the dynamic import and federation init steps so
failures don't silently prevent bootstrapping: catch errors from imports and
calls like import('@siemens/dashboards-ng/module-federation'), initFederation(),
createInstance(), mfInstance.initializeSharing(), Promise.all([...]).then(...),
and the final import('./bootstrap'), log a clear error (e.g., console.error or
the app logger) with the thrown error details and avoid calling
import('./bootstrap') when an upstream step failed so the app fails loudly and
predictably.
- Around line 8-14: The async IIFE currently mixes await style with .then()
chaining when loading the module federation package; change the .then() chain to
use await: inside the async IIFE, use const m = await
import('@siemens/dashboards-ng/module-federation'), call
m.registerModuleFederatedWidgetLoader() directly, and then await
import('./bootstrap') so the module loading is consistent with the rest of the
file and uses async/await throughout (references: the anonymous async IIFE,
environment.useModuleFederation,
import('@siemens/dashboards-ng/module-federation'),
registerModuleFederatedWidgetLoader, import('./bootstrap')).
In @projects/dashboards-demo/tsconfig.app.json:
- Around line 5-8: In tsconfig.app.json remove the `"node"` entry from the
"compilerOptions"."types" array (currently
["@siemens/element-translate-ng/localize-types", "node"]) so browser Angular
build does not require @types/node; update the array to only include
"@siemens/element-translate-ng/localize-types" and save the file (ensure JSON
remains valid after removal).
In @projects/dashboards-demo/webcomponents/concat.cjs:
- Line 2: The file imports the Node 'path' module into the variable path via
require('path') but never uses it; remove the unused import by deleting the var
path = require('path'); statement (or, if path is intended to be used later, use
it where needed in the relevant function), ensuring no other code references the
symbol path before removal.
In @projects/dashboards-ng/native-federation/index.ts:
- Around line 31-39: The error construction uses
JSON.stringify(rejection.toString()) which adds quotes/escaping; change it to
use the raw string instead (e.g., use rejection?.toString() or
String(rejection)) when building the message for factory.exposedModule, and pass
that to result.error followed by result.complete(); update the rejection branch
so the message is `Loading widget module ${factory.exposedModule} failed with
${rejection?.toString()}` (or String(rejection)) to keep output readable.
In @projects/dashboards-ng/native-federation/mf-bridge/index.ts:
- Around line 23-44: The promise resolution handler for loadRemote should handle
the case when module is falsy and avoid calling result.complete() after
result.error(); update the then callback that receives module (from
loadRemote<Type<T>[]>(factory.id, factory.options)) so that if module is falsy
you call result.error(...) with an informative message (e.g., include
factory.exposedModule) and return (or otherwise terminate), and remove the
subsequent result.complete() in the rejection handler (since result.error()
already terminates the Subject); ensure references are to factory,
componentName, host.createComponent, and result to locate the changes.
In @projects/dashboards-ng/src/model/widgets.model.ts:
- Around line 375-386: The JSDoc claim that LoadRemoteBridgeOptions is "Based on
`@module-federation/enhanced` loadRemote options" is misleading because the
library's loadRemote(id: string) API takes only an id; update the comment to
either remove the "Based on..." line or replace it with a clear note that
LoadRemoteBridgeOptions is a custom bridge/wrapper around the library's
loadRemote and documents the wrapper-specific fields (options.loadFactory and
options.from). Ensure the updated comment directly references the type name
LoadRemoteBridgeOptions and states that the shape diverges from
`@module-federation/enhanced`'s loadRemote API.
In @projects/dashboards-ng/tsconfig.lib.json:
- Line 7: Remove the unnecessary "node" type from the "types" array in
tsconfig.lib.json: edit the "types" entry so it only contains
"@siemens/element-translate-ng/localize-types" (remove the "node" string) to
avoid exposing Node.js globals to the browser library and align with other
libraries.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (27)
package-lock.jsonis excluded by!**/package-lock.jsonplaywright/snapshots/dashboard.spec.ts-snapshots/custom-catalog--custom-catalog-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/custom-catalog--custom-catalog-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--contact-editor-step-1-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--contact-editor-step-1-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--contact-editor-step-2-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--contact-editor-step-2-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--contact-widget-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--contact-widget-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--delete-confirmation-dialog-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--delete-confirmation-dialog-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--delete-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--delete-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--empty-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--empty-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--esm-edit-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--esm-edit-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--hello-world-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--hello-world-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--hello-world-editor-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--hello-world-editor-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--mobile-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--mobile-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--normal-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--normal-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--tablet-dashboards-demo-esm-chromium-dark-linux.pngis excluded by!**/*.pngplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--tablet-dashboards-demo-esm-chromium-light-linux.pngis excluded by!**/*.png
📒 Files selected for processing (40)
.github/workflows/build-and-test.yaml.gitignoreangular.jsonapi-goldens/dashboards-ng/index.api.mdapi-goldens/dashboards-ng/native-federation/index.api.mdapi-goldens/dashboards-ng/native-federation/mf-bridge/index.api.mdpackage.jsonplaywright.config.tsplaywright/e2e/dashboards-demo/dashboard.spec.tsplaywright/snapshots/dashboard.spec.ts-snapshots/dashboard--esm-edit.yamlprojects/dashboards-demo/eslint.config.jsprojects/dashboards-demo/federation.config.jsprojects/dashboards-demo/mfe/federation.config.jsprojects/dashboards-demo/mfe/src/environments/environment.esm.prod.tsprojects/dashboards-demo/mfe/src/environments/environment.esm.tsprojects/dashboards-demo/mfe/src/environments/environment.prod.tsprojects/dashboards-demo/mfe/src/environments/environment.tsprojects/dashboards-demo/mfe/src/main.esm.tsprojects/dashboards-demo/mfe/src/main.tsprojects/dashboards-demo/mfe/tsconfig.app.jsonprojects/dashboards-demo/package.jsonprojects/dashboards-demo/src/app/widgets/module-federation-widgets.tsprojects/dashboards-demo/src/bootstrap.tsprojects/dashboards-demo/src/environments/environment.esm.prod.tsprojects/dashboards-demo/src/environments/environment.esm.tsprojects/dashboards-demo/src/environments/environment.prod.tsprojects/dashboards-demo/src/environments/environment.tsprojects/dashboards-demo/src/main.tsprojects/dashboards-demo/src/styles-esm.scssprojects/dashboards-demo/tsconfig.app.jsonprojects/dashboards-demo/tsconfig.app.prod.jsonprojects/dashboards-demo/webcomponents/concat.cjsprojects/dashboards-demo/webcomponents/eslint.config.jsprojects/dashboards-demo/webpack.config.cjsprojects/dashboards-ng/native-federation/index.tsprojects/dashboards-ng/native-federation/mf-bridge/index.tsprojects/dashboards-ng/native-federation/mf-bridge/ng-package.jsonprojects/dashboards-ng/native-federation/ng-package.jsonprojects/dashboards-ng/src/model/widgets.model.tsprojects/dashboards-ng/tsconfig.lib.json
💤 Files with no reviewable changes (2)
- projects/dashboards-demo/package.json
- projects/dashboards-demo/src/bootstrap.ts
🧰 Additional context used
🧠 Learnings (17)
📚 Learning: 2025-12-17T04:34:55.597Z
Learnt from: chintankavathia
Repo: siemens/element PR: 1173
File: src/app/examples/si-charts/interactive/interactive.ts:5-5
Timestamp: 2025-12-17T04:34:55.597Z
Learning: Guideline: In Angular projects using OnPush change detection (zoneless mode), you only need to call ChangeDetectorRef.markForCheck() for asynchronous operations (e.g., setTimeout, setInterval, Promises, Observables) where a change is not automatically detected. Event handlers triggered by Angular template bindings (click, input, etc.) will trigger change detection automatically and do not require explicit markForCheck() calls. Apply this broadly to TS files within Angular components/services that use OnPush; use markForCheck() selectively for async work where change detection wouldn’t run otherwise.
Applied to files:
projects/dashboards-demo/mfe/src/main.esm.tsprojects/dashboards-demo/mfe/src/environments/environment.esm.prod.tsprojects/dashboards-demo/src/environments/environment.esm.prod.tsprojects/dashboards-demo/mfe/src/environments/environment.tsprojects/dashboards-demo/mfe/src/environments/environment.esm.tsprojects/dashboards-demo/mfe/src/environments/environment.prod.tsprojects/dashboards-demo/src/environments/environment.esm.tsprojects/dashboards-ng/native-federation/index.tsprojects/dashboards-demo/src/environments/environment.prod.tsprojects/dashboards-ng/src/model/widgets.model.tsprojects/dashboards-demo/src/app/widgets/module-federation-widgets.tsplaywright/e2e/dashboards-demo/dashboard.spec.tsprojects/dashboards-demo/src/environments/environment.tsplaywright.config.tsprojects/dashboards-demo/mfe/src/main.tsprojects/dashboards-demo/src/main.tsprojects/dashboards-ng/native-federation/mf-bridge/index.ts
📚 Learning: 2025-12-12T11:44:21.060Z
Learnt from: spike-rabbit
Repo: siemens/element PR: 1188
File: projects/maps-ng/tsconfig.lib.json:16-18
Timestamp: 2025-12-12T11:44:21.060Z
Learning: Maintain broad include patterns in tsconfig.lib.json files. Do not narrow include from "./**/*.ts" to "./src/**/*.ts" unless there is a strong, project-wide reason. This ensures library code outside src (e.g., folders like translate/) remains part of the compilation in solution-style TypeScript configurations. When reviewing, verify that each tsconfig.lib.json retains a broad include pattern that covers all TypeScript sources intended for the library, not just those under src.
Applied to files:
projects/dashboards-ng/tsconfig.lib.json
📚 Learning: 2025-12-17T06:59:51.485Z
Learnt from: chintankavathia
Repo: siemens/element PR: 1036
File: projects/dashboards-ng/src/widget-loader.ts:176-182
Timestamp: 2025-12-17T06:59:51.485Z
Learning: In projects/dashboards-ng/src/widget-loader.ts, when checking `factory.moduleName`, there's no need to also check for `factory.moduleLoader` because the TypeScript type system (ModuleOptions type) enforces that `moduleLoader` must be present whenever `moduleName` is provided.
Applied to files:
projects/dashboards-ng/tsconfig.lib.jsonprojects/dashboards-ng/native-federation/index.tsprojects/dashboards-ng/src/model/widgets.model.tsprojects/dashboards-demo/src/app/widgets/module-federation-widgets.tsprojects/dashboards-demo/mfe/src/main.tsprojects/dashboards-ng/native-federation/mf-bridge/index.ts
📚 Learning: 2025-12-12T11:44:30.712Z
Learnt from: spike-rabbit
Repo: siemens/element PR: 1188
File: projects/maps-ng/tsconfig.lib.json:16-18
Timestamp: 2025-12-12T11:44:30.712Z
Learning: In projects/maps-ng/tsconfig.lib.json, the include pattern "./**/*.ts" should remain broad and not be restricted to "./src/**/*.ts", as files outside src/ (like those in translate/) are intentionally part of the library compilation in the solution-style TypeScript configuration.
Applied to files:
projects/dashboards-ng/native-federation/mf-bridge/ng-package.jsonprojects/dashboards-ng/native-federation/ng-package.jsonprojects/dashboards-demo/tsconfig.app.json.gitignoreprojects/dashboards-demo/eslint.config.jsprojects/dashboards-demo/tsconfig.app.prod.jsonprojects/dashboards-demo/mfe/tsconfig.app.jsonprojects/dashboards-demo/webcomponents/eslint.config.js
📚 Learning: 2025-12-22T13:26:40.908Z
Learnt from: spike-rabbit
Repo: siemens/element PR: 1237
File: tools/api-goldens/test_api_report.ts:19-23
Timestamp: 2025-12-22T13:26:40.908Z
Learning: In the siemens/element repository, the team intentionally uses internal APIs from `microsoft/api-extractor` (such as `AstDeclaration`, `AstModule`, `ExportAnalyzer`, `ApiItemMetadata`, and `Collector` from `/lib/analyzer` and `/lib/collector` paths) in `tools/api-goldens/test_api_report.ts` to customize API extraction behavior (e.g., marking protected members as internal). This is an accepted practice because the required functionality is not available through the public API, and the version is pinned to mitigate risks.
Applied to files:
api-goldens/dashboards-ng/native-federation/index.api.mdapi-goldens/dashboards-ng/native-federation/mf-bridge/index.api.md
📚 Learning: 2025-12-23T09:24:35.163Z
Learnt from: spike-rabbit
Repo: siemens/element PR: 1235
File: api-goldens/dashboards-ng/translate/index.api.md:12-84
Timestamp: 2025-12-23T09:24:35.163Z
Learning: In the siemens/element repository, do not review files under the api-goldens/ directory (e.g., api-goldens/**/index.api.md) since they are auto-generated by API Extractor. Exclude these from review checks and focus on source files that are not auto-generated.
Applied to files:
api-goldens/dashboards-ng/native-federation/index.api.mdapi-goldens/dashboards-ng/native-federation/mf-bridge/index.api.mdapi-goldens/dashboards-ng/index.api.md
📚 Learning: 2025-12-23T09:24:57.843Z
Learnt from: spike-rabbit
Repo: siemens/element PR: 1235
File: api-goldens/dashboards-ng/index.api.md:324-325
Timestamp: 2025-12-23T09:24:57.843Z
Learning: Do not review files in the api-goldens directory, as they are auto-generated API reports produced by API Extractor.
Applied to files:
api-goldens/dashboards-ng/native-federation/index.api.mdapi-goldens/dashboards-ng/native-federation/mf-bridge/index.api.mdapi-goldens/dashboards-ng/index.api.md
📚 Learning: 2025-12-23T09:24:40.395Z
Learnt from: spike-rabbit
Repo: siemens/element PR: 1235
File: api-goldens/dashboards-ng/module-federation/index.api.md:7-11
Timestamp: 2025-12-23T09:24:40.395Z
Learning: In the siemens/element repository, do not review any files under the api-goldens directory, as they are auto-generated API reports produced by API Extractor. These MD files should be excluded from review unless explicitly overridden.
Applied to files:
api-goldens/dashboards-ng/native-federation/index.api.mdapi-goldens/dashboards-ng/native-federation/mf-bridge/index.api.mdapi-goldens/dashboards-ng/index.api.md
📚 Learning: 2025-12-16T16:19:17.950Z
Learnt from: spike-rabbit
Repo: siemens/element PR: 1207
File: playwright/snapshots/si-filtered-search.spec.ts-snapshots/si-filtered-search--si-filtered-search-playground--data-entered.yaml:38-38
Timestamp: 2025-12-16T16:19:17.950Z
Learning: Do not review files in the playwright/snapshots directory, as they contain auto-generated test artifacts. Exclude any YAML snapshot files under playwright/snapshots from code reviews in the siemens/element repository. If a YAML file is not an auto-generated snapshot, verify its origin before skipping.
Applied to files:
playwright/snapshots/dashboard.spec.ts-snapshots/dashboard--esm-edit.yaml
📚 Learning: 2025-12-15T07:17:06.981Z
Learnt from: chintankavathia
Repo: siemens/element PR: 1191
File: projects/dashboards-ng/src/components/widget-instance-editor-dialog/si-widget-instance-editor-dialog.component.spec.ts:37-49
Timestamp: 2025-12-15T07:17:06.981Z
Learning: In widget-instance-editor-dialog component tests (projects/dashboards-ng/src/components/widget-instance-editor-dialog/si-widget-instance-editor-dialog.component.spec.ts), real setTimeout waits (e.g., `await new Promise(resolve => setTimeout(resolve, 0))`) must be used instead of `fixture.whenStable()` when testing component initialization. This is likely due to the component's lifecycle behavior or modal initialization timing that fixture.whenStable() cannot properly wait for in zoneless mode.
Applied to files:
playwright/e2e/dashboards-demo/dashboard.spec.ts
📚 Learning: 2025-12-15T07:16:53.762Z
Learnt from: chintankavathia
Repo: siemens/element PR: 1191
File: projects/dashboards-ng/src/components/gridstack-wrapper/si-gridstack-wrapper.component.spec.ts:92-105
Timestamp: 2025-12-15T07:16:53.762Z
Learning: In gridstack-wrapper component tests (projects/dashboards-ng/src/components/gridstack-wrapper/si-gridstack-wrapper.component.spec.ts), real setTimeout waits must be used instead of fixture.whenStable() to avoid injector destroyed errors during mount/unmount operations in zoneless mode. The GridStack timing-dependent operations require actual async delays.
Applied to files:
playwright/e2e/dashboards-demo/dashboard.spec.ts
📚 Learning: 2025-12-15T07:16:32.082Z
Learnt from: chintankavathia
Repo: siemens/element PR: 1191
File: projects/dashboards-ng/src/components/gridstack-wrapper/si-gridstack-wrapper.component.spec.ts:69-80
Timestamp: 2025-12-15T07:16:32.082Z
Learning: In gridstack-wrapper component tests (projects/dashboards-ng/src/components/gridstack-wrapper/si-gridstack-wrapper.component.spec.ts), real setTimeout waits (e.g., `await new Promise(resolve => setTimeout(resolve, 0))`) must be used instead of `fixture.whenStable()` when testing grid item rendering and initialization. This is likely due to gridstack library's initialization timing or lifecycle behavior that fixture.whenStable() cannot properly wait for in zoneless mode.
Applied to files:
playwright/e2e/dashboards-demo/dashboard.spec.ts
📚 Learning: 2025-12-15T10:05:59.100Z
Learnt from: chintankavathia
Repo: siemens/element PR: 1193
File: projects/element-ng/search-bar/si-search-bar.component.spec.ts:21-28
Timestamp: 2025-12-15T10:05:59.100Z
Learning: In tests that rely on Jasmine's fake clock to control time-based RxJS operators (e.g., debounceTime), use jasmine.clock().install() together with jasmine.clock().mockDate() to enable precise timing control. Without mockDate, scheduler-based operators may not respond to the fake clock. Apply this guidance to spec files (e.g., any file named *.spec.ts or *.spec.js) that test time-sensitive behavior, ensuring you install and mockDate before advancing time in tests.
Applied to files:
playwright/e2e/dashboards-demo/dashboard.spec.ts
📚 Learning: 2026-01-07T12:19:38.754Z
Learnt from: chintankavathia
Repo: siemens/element PR: 1240
File: projects/dashboards-ng/package.json:21-22
Timestamp: 2026-01-07T12:19:38.754Z
Learning: In the siemens/element repository, Angular peer dependencies are intentionally pinned to exact major versions (e.g., "angular/core": "21") rather than ranges in package.json files for published packages like siemens/dashboards-ng, siemens/element-ng, and siemens/element-translate-ng. This is a deliberate strategy to ensure strict version alignment.
Applied to files:
package.json
📚 Learning: 2025-12-09T14:19:26.605Z
Learnt from: Killusions
Repo: siemens/element PR: 967
File: package.json:153-153
Timestamp: 2025-12-09T14:19:26.605Z
Learning: In library projects (e.g., element-ng), do not list implementation dependencies for optional features in the main dependencies. Move those into devDependencies (used for demos/examples) and have consuming apps install them separately if they enable the feature. This avoids bloating library consumers with unnecessary packages and clarifies that optional features are not guaranteed to work without extra installs. If a feature is truly optional, consider documenting it and, if appropriate, using optionalDependencies to reflect optional runtime usage.
Applied to files:
package.json
📚 Learning: 2026-01-07T19:44:24.336Z
Learnt from: spliffone
Repo: siemens/element PR: 453
File: projects/element-translate-ng/package.json:26-26
Timestamp: 2026-01-07T19:44:24.336Z
Learning: In this repository, peerDependencies in package.json should use hyphen-major-version ranges (e.g., '16 - 17', '22 - 25') instead of standard semver ranges like '>=16.0.0 <18.0.0' or '^16.0.0 || ^17.0.0'. This convention is applied across all packages for consistency. During reviews, verify that each package.json lists peerDependencies using a hyphen-range format, and update any that use conventional semver expressions. If needed, adjust to the correct major-version bounds (e.g., '16 - 17' for 16.x/17.x).
Applied to files:
package.json
📚 Learning: 2025-12-01T04:01:27.365Z
Learnt from: chintankavathia
Repo: siemens/element PR: 1099
File: projects/element-ng/accordion/si-accordion.component.spec.ts:39-43
Timestamp: 2025-12-01T04:01:27.365Z
Learning: With Angular 20 and esbuild, synchronous `TestBed.configureTestingModule(...).compileComponents()` calls work correctly even when components use external templates (templateUrl), because esbuild pre-compiles templates at build time. The async/await pattern is not required in this scenario.
Applied to files:
projects/dashboards-demo/webcomponents/concat.cjsangular.json
🧬 Code graph analysis (9)
projects/dashboards-demo/mfe/src/environments/environment.ts (5)
projects/dashboards-demo/mfe/src/environments/environment.esm.prod.ts (1)
environment(9-13)projects/dashboards-demo/mfe/src/environments/environment.esm.ts (1)
environment(9-13)projects/dashboards-demo/mfe/src/environments/environment.prod.ts (1)
environment(6-10)projects/dashboards-demo/src/environments/environment.esm.ts (1)
environment(9-14)projects/dashboards-demo/src/environments/environment.ts (1)
environment(10-15)
projects/dashboards-demo/mfe/src/environments/environment.esm.ts (6)
projects/dashboards-demo/mfe/src/environments/environment.esm.prod.ts (1)
environment(9-13)projects/dashboards-demo/mfe/src/environments/environment.prod.ts (1)
environment(6-10)projects/dashboards-demo/mfe/src/environments/environment.ts (1)
environment(10-14)projects/dashboards-demo/src/environments/environment.esm.ts (1)
environment(9-14)projects/dashboards-demo/src/environments/environment.prod.ts (1)
environment(6-11)projects/dashboards-demo/src/environments/environment.ts (1)
environment(10-15)
projects/dashboards-demo/mfe/src/environments/environment.prod.ts (3)
projects/dashboards-demo/mfe/src/environments/environment.esm.prod.ts (1)
environment(9-13)projects/dashboards-demo/src/environments/environment.esm.prod.ts (1)
environment(9-14)projects/dashboards-demo/src/environments/environment.prod.ts (1)
environment(6-11)
projects/dashboards-demo/federation.config.js (2)
projects/dashboards-demo/mfe/federation.config.js (1)
require(1-1)projects/dashboards-demo/webpack.config.cjs (1)
require(1-4)
projects/dashboards-ng/native-federation/index.ts (2)
projects/dashboards-ng/src/model/widgets.model.ts (1)
FederatedModule(84-88)projects/dashboards-ng/src/widget-loader.ts (2)
widgetFactoryRegistry(32-46)SetupComponentFn(24-30)
projects/dashboards-demo/src/app/widgets/module-federation-widgets.ts (9)
projects/dashboards-ng/src/model/widgets.model.ts (1)
Widget(16-44)projects/dashboards-demo/mfe/src/environments/environment.esm.prod.ts (1)
environment(9-13)projects/dashboards-demo/mfe/src/environments/environment.esm.ts (1)
environment(9-13)projects/dashboards-demo/mfe/src/environments/environment.prod.ts (1)
environment(6-10)projects/dashboards-demo/mfe/src/environments/environment.ts (1)
environment(10-14)projects/dashboards-demo/src/environments/environment.esm.prod.ts (1)
environment(9-14)projects/dashboards-demo/src/environments/environment.esm.ts (1)
environment(9-14)projects/dashboards-demo/src/environments/environment.prod.ts (1)
environment(6-11)projects/dashboards-demo/src/environments/environment.ts (1)
environment(10-15)
playwright/e2e/dashboards-demo/dashboard.spec.ts (1)
playwright/support/test-helpers.ts (1)
test(286-296)
projects/dashboards-demo/src/main.ts (8)
projects/dashboards-demo/mfe/src/environments/environment.esm.prod.ts (1)
environment(9-13)projects/dashboards-demo/mfe/src/environments/environment.esm.ts (1)
environment(9-13)projects/dashboards-demo/mfe/src/environments/environment.prod.ts (1)
environment(6-10)projects/dashboards-demo/mfe/src/environments/environment.ts (1)
environment(10-14)projects/dashboards-demo/src/environments/environment.esm.prod.ts (1)
environment(9-14)projects/dashboards-demo/src/environments/environment.esm.ts (1)
environment(9-14)projects/dashboards-demo/src/environments/environment.prod.ts (1)
environment(6-11)projects/dashboards-demo/src/environments/environment.ts (1)
environment(10-15)
projects/dashboards-ng/native-federation/mf-bridge/index.ts (2)
projects/dashboards-ng/src/model/widgets.model.ts (1)
FederatedBridgeModule(90-94)projects/dashboards-ng/src/widget-loader.ts (2)
widgetFactoryRegistry(32-46)SetupComponentFn(24-30)
🪛 markdownlint-cli2 (0.18.1)
api-goldens/dashboards-ng/native-federation/index.api.md
1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
api-goldens/dashboards-ng/native-federation/mf-bridge/index.api.md
1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🔇 Additional comments (42)
projects/dashboards-demo/eslint.config.js (1)
8-12: ✅ ESLint ignores correctly updated for ESM environment files.The expansion of the ignores array to include the new ESM environment variants (
environment.esm.tsandenvironment.esm.prod.ts) aligns with the native federation setup introduced in this PR. The glob patterns are correct and consistent with the existing approach of excluding generated/build-time environment configurations..gitignore (1)
71-74: The gitignore entries for Native Federation tsconfig files are correct and complete.The added entries properly ignore the generated federation tsconfig files. Verification confirms that:
/projects/dashboards-demo/mfe/correctly references a subdirectory (not a separate project)- Both federation build targets (main app and mfe) are covered
- The webcomponents directory does not use Native Federation and requires no additional ignore entries
No changes needed.
projects/dashboards-demo/tsconfig.app.json (1)
9-16: The configuration is correct and no changes are needed. The baseenvironment.tsis properly included for compilation, and Angular'sfileReplacementsinangular.jsoncorrectly handle swapping environment variants during the build process (e.g.,environment.prod.tsfor production,environment.esm.tsfor ESM builds). Excluding the variant files is a standard Angular pattern—these files are applied at build time viafileReplacements, not through TypeScript's module resolution.Likely an incorrect or invalid review comment.
projects/dashboards-demo/mfe/tsconfig.app.json (1)
7-8: Remove the explicit environment files inclusion from the include array.The addition of
"src/main.esm.ts"to the files array is correct for native federation support.However, the explicit
"src/environments/*.ts"inclusion in the include array is unnecessary. These environment files are not imported anywhere in the mfe codebase (main.ts, main.esm.ts, bootstrap.ts, or any other component files). Since TypeScript automatically includes imported files through dependency resolution, explicitly listing unused files adds unnecessary configuration. Remove"src/environments/*.ts"from the include array on line 8.⛔ Skipped due to learnings
Learnt from: spike-rabbit Repo: siemens/element PR: 1188 File: projects/maps-ng/tsconfig.lib.json:16-18 Timestamp: 2025-12-12T11:44:30.712Z Learning: In projects/maps-ng/tsconfig.lib.json, the include pattern "./**/*.ts" should remain broad and not be restricted to "./src/**/*.ts", as files outside src/ (like those in translate/) are intentionally part of the library compilation in the solution-style TypeScript configuration.projects/dashboards-ng/native-federation/ng-package.json (1)
1-6:index.tsexists and correctly exports the native federation widget loader.The file
projects/dashboards-ng/native-federation/index.tsis present and exportsregisterNativeFederatedWidgetLoader, the intended public API for this secondary entrypoint. The ng-package.json configuration is valid.projects/dashboards-demo/webcomponents/eslint.config.js (1)
4-13: The ESLint configuration change is safe. No*.spec.tsor*.test.tsfiles exist in this directory, andtsconfig.spec.jsondoes not exist. The narrowedparserOptions.projectpointing only totsconfig.app.jsonis appropriate and does not require the proposed spec override block..github/workflows/build-and-test.yaml (1)
267-270: No action needed —dist/dashboards-demo-esm/is a stable, consistently-named output directory.The output path is explicitly configured in
angular.jsonwith a fixed value ("base": "dist/dashboards-demo-esm"), not a variable or configuration-dependent setting. Thenpm run dashboards-demo:build:esmbuild step executes unconditionally in the workflow and always produces this directory. The path is also consistently referenced throughout the codebase (federation config, npm scripts, and Playwright tests), confirming its stability.projects/dashboards-demo/mfe/src/environments/environment.esm.prod.ts (1)
5-13: ThemfeBaseUrlvalue is correct for the deployed folder structure. The relative path./mfe-esmproperly resolves to the MFE's output directory during native federation setup. No changes needed.Regarding the empty
/** */comment: this is a codebase-wide convention (found in 40+ files) that precedes exported entities after SPDX headers. Removing it from this file alone would be inconsistent; any cleanup should be addressed as a bulk refactoring across the codebase if desired.projects/dashboards-demo/src/styles-esm.scss (1)
1-20: Remove direct/src/imports from @siemens/element-theme—package lacks proper export configuration.The file is correctly wired into the ESM build (angular.json:510), but the imports from
@siemens/element-theme/src/themeand@siemens/element-theme/src/styles/themeswill likely fail to resolve. The local@siemens/element-themeworkspace package has no"main","exports", or"sass"field defined in its package.json, and it's not mapped in tsconfig.json. Either add a tsconfig path mapping for@siemens/element-theme, configure proper exports in the package.json, or use the built output path if available.⛔ Skipped due to learnings
Learnt from: spike-rabbit Repo: siemens/element PR: 1188 File: projects/maps-ng/tsconfig.lib.json:16-18 Timestamp: 2025-12-12T11:44:30.712Z Learning: In projects/maps-ng/tsconfig.lib.json, the include pattern "./**/*.ts" should remain broad and not be restricted to "./src/**/*.ts", as files outside src/ (like those in translate/) are intentionally part of the library compilation in the solution-style TypeScript configuration.Learnt from: mistrykaran91 Repo: siemens/element PR: 1234 File: projects/element-ng/ag-grid/parts/radio-style.part.ts:15-61 Timestamp: 2025-12-31T07:16:13.451Z Learning: In the AG Grid theme package (projects/element-ng/ag-grid), styling should maintain consistency with the base Element design system components rather than adding enhancements or extra CSS. If accessibility improvements like focus-visible indicators are needed, they should be implemented at the Element design system level first.Learnt from: spike-rabbit Repo: siemens/element PR: 1207 File: playwright/snapshots/si-filtered-search.spec.ts-snapshots/si-filtered-search--si-filtered-search-playground--data-entered.yaml:38-38 Timestamp: 2025-12-16T16:19:24.628Z Learning: Do not review files in the `playwright/snapshots/` directory in the siemens/element repository as they are auto-generated test artifacts.projects/dashboards-demo/webcomponents/concat.cjs (1)
18-33: LGTM!The IIFE wrapping pattern effectively isolates scope and prevents variable conflicts across concatenated files. The multi-target output strategy (module federation, native federation ESM, and webcomponents) aligns well with the PR's federation approach.
projects/dashboards-demo/mfe/src/environments/environment.ts (1)
10-14: LGTM!The environment configuration is well-structured and consistent with the pattern used across other environment files. The
useModuleFederationflag enables clean runtime switching between Module Federation and Native Federation modes.projects/dashboards-ng/native-federation/index.ts (2)
44-46: LGTM!The registration function correctly wires the native federation loader into the widget factory registry, enabling runtime widget loading for native federation scenarios.
22-22: No change needed. The double property access patternmodule[factory[componentName]]is intentional and type-safe. TheFederatedModuletype explicitly allows arbitrary string keys via[index: string]: any, enabling a standard dictionary-to-array lookup pattern wherefactory[componentName]retrieves a mapped value that indexes into the component array. This pattern is consistently implemented across all federation loaders (native-federation, module-federation, and mf-bridge) and is part of the deliberate module federation design.projects/dashboards-demo/webpack.config.cjs (1)
6-20: LGTM!The webpack configuration correctly excludes ESM-only native federation packages from webpack processing. The use of
commonjsexternals prevents build errors while maintaining compatibility with the module federation setup. The comment clearly documents the rationale.projects/dashboards-ng/src/model/widgets.model.ts (3)
47-51: LGTM: Union type expansion is correct.The addition of
FederatedBridgeModuleto theWidgetComponentFactoryunion properly supports the new native-federation bridge scenario described in the PR objectives.
84-88: Verify the addition of the index signature to FederatedModule.The
factoryTypeexpansion to include'native-federation'aligns with the PR's native federation support. However, the addition of[index: string]: anyallows arbitrary properties onFederatedModule, which could weaken type safety.Could you clarify whether the index signature is intentional and necessary? If it's meant to accommodate federation-specific configuration properties, consider documenting this or using a more constrained type like
[key: string]: unknownto maintain better type discipline.
90-94: LGTM: FederatedBridgeModule type definition is well-structured.The new type correctly combines
CommonFactoryFields,LoadRemoteBridgeOptions, and a specificfactoryTypediscriminator for the module-federation bridge scenario.api-goldens/dashboards-ng/index.api.md (1)
1-430: Skipping review: Auto-generated API report.This file is auto-generated by API Extractor and should not be manually reviewed. Based on learnings, API golden files are excluded from review as they reflect the public API surface extracted from source files.
projects/dashboards-ng/native-federation/mf-bridge/ng-package.json (1)
1-6: LGTM: Standard ng-packagr configuration.The configuration correctly sets up the native-federation mf-bridge subpackage with a standard entry file reference. This aligns with Angular library packaging conventions.
projects/dashboards-demo/mfe/src/main.ts (1)
6-7: LGTM: Clear documentation of entry point purpose.The comments effectively clarify the distinction between webpack-based Module Federation (this file) and Native Federation ESM builds (main.esm.ts), helping developers choose the correct entry point for their build configuration.
projects/dashboards-demo/src/environments/environment.esm.prod.ts (1)
9-14: LGTM!The environment configuration is complete and correct for ESM production builds. All required properties are present (
mfeBaseUrl,mfeEsmBaseUrl,webComponentsBaseUrl,useModuleFederation), and the values are appropriate for a production deployment using native federation.projects/dashboards-demo/mfe/src/environments/environment.prod.ts (1)
6-10: LGTM!The environment configuration is correct for the MFE (remote) production build using module federation. The properties are appropriate, and the
useModuleFederation: trueflag correctly indicates this is a module federation configuration.package.json (2)
67-81: LGTM!The new npm scripts are well-organized and provide comprehensive support for ESM/native federation workflows, including separate commands for development (
start:esm,start:mfe:esm) and production builds (build:esm,build:esm:mfe,build:bridge:mfe).
108-109: Update @angular-architects/native-federation to 21.0.3 and review @module-federation/enhanced version compatibility.@angular-architects/native-federation 21.0.0 is outdated; version 21.0.3 is the latest stable release for Angular 21.x and should be used instead.
@module-federation/enhanced 0.22.0 exceeds the typical 0.15–0.21 version range used in Angular 21.x/22.x workflows; verify this version is intentional and compatible with your webpack and @Angular-devkit setup.
@softarc/native-federation-node ^3.3.4 is acceptable (3.3.5 is available but patch-level).
es-module-shims ^1.5.12 is significantly outdated (v2.6.2+ is current), but Angular 21's ESM-first architecture typically does not require this polyfill unless supporting older browsers or unbundled ESM with import maps.
⛔ Skipped due to learnings
Learnt from: chintankavathia Repo: siemens/element PR: 1240 File: projects/dashboards-ng/package.json:21-22 Timestamp: 2026-01-07T12:19:38.754Z Learning: In the siemens/element repository, Angular peer dependencies are intentionally pinned to exact major versions (e.g., "angular/core": "21") rather than ranges in package.json files for published packages like siemens/dashboards-ng, siemens/element-ng, and siemens/element-translate-ng. This is a deliberate strategy to ensure strict version alignment.Learnt from: spliffone Repo: siemens/element PR: 453 File: projects/element-translate-ng/ngx-translate/si-translate-ngxt.service.ts:42-44 Timestamp: 2026-01-05T16:46:16.913Z Learning: In projects/element-translate-ng, the peer dependency range for ngx-translate/core includes both v16 and v17, requiring use of APIs compatible with both versions. The deprecated properties `currentLang`, `getDefaultLang()`, and `setDefaultLang()` must be used instead of their v17 replacements (`getCurrentLang()`, `getFallbackLang()`, `setFallbackLang()`) until v16 support is dropped in v49.Learnt from: spliffone Repo: siemens/element PR: 453 File: projects/element-translate-ng/package.json:26-26 Timestamp: 2026-01-07T19:44:24.336Z Learning: In the siemens/element repository, peer dependencies in package.json files use hyphen range syntax (e.g., "16 - 17", "22 - 25") to specify support for multiple major versions, rather than standard semver range syntax like ">=16.0.0 <18.0.0" or "^16.0.0 || ^17.0.0". This is an intentional project convention for consistency across all packages.projects/dashboards-demo/src/environments/environment.ts (1)
10-15: LGTM!The new
mfeEsmBaseUrlanduseModuleFederationproperties are correctly added and align with the other environment configurations in the PR. TheuseModuleFederation: truesetting correctly indicates this is the default module federation environment.api-goldens/dashboards-ng/native-federation/mf-bridge/index.api.md (1)
1-14: Skipping review of auto-generated API golden file.Based on learnings, files under
api-goldens/are auto-generated by API Extractor and should not be reviewed.playwright.config.ts (3)
10-17: LGTM!The ESM port configuration and server command are correctly set up, with port 4204 for the ESM host app and the server command pointing to
dist/dashboards-demo-esm.
169-184: LGTM!The new ESM project definitions correctly mirror the existing dashboards-demo projects, using the ESM port and sharing the same test directory. This enables running the same E2E tests against both module federation and native federation builds.
206-214: LGTM!The conditional web server startup for ESM projects follows the same pattern as the existing dashboards-demo server configuration.
projects/dashboards-demo/src/environments/environment.esm.ts (1)
1-14: LGTM!The ESM environment configuration correctly sets
useModuleFederation: falseto trigger the native federation initialization path and includes both federation URLs to support the mf-bridge hybrid scenario.projects/dashboards-demo/src/environments/environment.prod.ts (1)
6-11: LGTM!The production environment correctly adds
mfeEsmBaseUrlwith a relative path and setsuseModuleFederation: truefor the standard production build using module federation.projects/dashboards-demo/federation.config.js (1)
1-39: LGTM overall!The native federation configuration is well-structured with appropriate shared settings, skip patterns for problematic packages, and clear comments explaining the configuration choices.
projects/dashboards-demo/mfe/federation.config.js (1)
1-24: LGTM! Standard native federation configuration.The configuration correctly:
- Exposes the Download and Upload components for remote consumption
- Skips browser-incompatible packages (rxjs submodules, flag-icons)
- Uses
shareAllwith appropriate settings for singleton shared dependenciesprojects/dashboards-ng/native-federation/mf-bridge/index.ts (1)
48-56: LGTM! Clean registration pattern.The function properly binds the
ModuleFederationinstance and registers under the correct factory type key (nf-module-federation) matching theFederatedBridgeModuletype definition.playwright/snapshots/dashboard.spec.ts-snapshots/dashboard--esm-edit.yaml (1)
1-44: Skipping review of auto-generated Playwright snapshot.Based on learnings, files in
playwright/snapshotsare auto-generated test artifacts and should not be reviewed.projects/dashboards-demo/src/app/widgets/module-federation-widgets.ts (2)
9-31: LGTM! Clean environment-based widget configuration.The
DOWNLOAD_WIDGETcorrectly branches between module-federation (.jsremote entry) and native-federation (.jsonremote entry) configurations based on the environment flag.
45-53: No action required. Thenf-module-federationconfiguration is correct and has all required fields as defined by theFederatedBridgeModuletype:factoryType,id, andcomponentName. The fields present in themodule-federationvariant (type,remoteEntry,exposedModule) are not part of thenf-module-federationcontract—they belong to different module federation approaches. The bridge module uses theidfield to identify the remote, while classic module federation uses remoteEntry and exposedModule paths. The TypeScript type system ensures type safety for required fields.Likely an incorrect or invalid review comment.
angular.json (5)
479-556: LGTM! Well-structured esbuild configuration for native federation.The
esbuildtarget correctly configures:
- ESM-specific environment file replacements
es-module-shimspolyfill for import map support- Separate styles file (
styles-esm.scss)- Appropriate CommonJS dependency allowlist including
@module-federation/runtimeProduction configuration has proper optimization, hashing, and budget settings.
558-597: LGTM! Native federation serve chain properly configured.The three-target chain (
serve-esm→serve-esm-original→build-esm→esbuild) follows the recommended pattern from@angular-architects/native-federation. TherebuildDelay: 500andcacheExternalArtifacts: falseare appropriate for development.
611-665: LGTM! Clean migration to@angular/build:applicationbuilder.The webcomponents project correctly migrates to the new Angular application builder with:
- Object-based
outputPathconfigurationbrowserentry point (renamed frommain)- Matching
@angular/build:dev-serverfor serve
726-728: Confirmbridgeconfiguration intent.The
bridgeconfiguration only overridesoutputPathtodist/dashboards-demo-esm/mfe. This places the module-federation build output alongside the native-federation shell, which aligns with the mf-bridge use case (NF shell loading MF remotes).
759-852: LGTM! MFE esbuild and native federation targets properly configured.The configuration correctly:
- Uses
main.esm.tsas browser entry point for ESM builds- Outputs to
dist/dashboards-demo-esm/mfe-esm- Includes
es-module-shimspolyfill- Serves on port 4205 (matching
environment.mfeEsmBaseUrl)
projects/dashboards-demo/mfe/src/environments/environment.esm.ts
Outdated
Show resolved
Hide resolved
4ee9421 to
ecf9557
Compare
ecf9557 to
7c57c45
Compare
473580f to
6dd85b0
Compare
|
Adding Upload (module-federation on native-federation shell) to the ESM version on the online demo at https://d33c9dcnqinn2a.cloudfront.net/pr-1265/pages/dashboards-demo-esm/#/dashboard does not work. Is an empty widget |
timowolf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fantastic work. Just a bit of documentation. You started in the PR already. I think this should go into a README. The upload widget does not work online in the PR demo for esm.
projects/dashboards-demo/mfe/src/environments/environment.prod.ts
Outdated
Show resolved
Hide resolved
082fee1 to
d29617c
Compare
fff4b85 to
71108b4
Compare
This is fixed. |
f06761c to
ec07310
Compare
46b29bd to
863435b
Compare
timowolf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
863435b to
5847f2f
Compare
43222ce to
ec0d42a
Compare
added `registerNativeFederatedWidgetLoader` for pure native federation setup and `registerModuleFederatedWidgetLoader` for remote using module federation and shell on native federation.
ec0d42a to
399356c
Compare
spike-rabbit
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Existing module federation remains unchanged.
Additionally there are now two other entry point options introduced:
Host App on native federation and all remote apps using native federation
registerNativeFederatedWidgetLoadershall be used from@siemens/dashboards-ng/native-federationHost app on native federation and some remote apps using module federation and some native federation
registerModuleFederatedWidgetLoaderfrom@siemens/dashboards-ng/native-federation/mf-bridgeDemo:
To run demo with native federation
npm run dashboards-demo:start:esm(starts host app)npm run dashboards-demo:start:mfe:esm(starts remote app in native federation configuration)npm run dashboards-demo:start:mfe(startes remote app in module federation configuration)Build
Build pipeline is updated to also build dashboards-demo with native federation configuration
Artifacts will be generated under
dashboards-demo-esmE2E
Playwirght config is updated to run dashboards e2e in module federation as well as native federation environment
Setup motivation
https://www.angulararchitects.io/blog/combining-native-federation-and-module-federation/
Illustration
Summary
This PR adds native federation support to @siemens/dashboards-ng, enabling applications to leverage native ES modules for federation alongside existing module federation capabilities.
Key Features
New Public APIs:
registerNativeFederatedWidgetLoader()– Registers widget loading for pure native federation setups across host and remotesregisterModuleFederatedWidgetLoader(mfInstance)– Bridges native federation hosts with module federation remotesWidget Configuration:
FederatedModuletype to support'native-federation'factory typeFederatedBridgeModuleandLoadRemoteBridgeOptionstypes for hybrid federation scenariosuseModuleFederationenvironment flagBuild & Development
New NPM Scripts:
dashboards-demo:start:esm/dashboards-demo:start:esm:prod– Start host in native federation modedashboards-demo:start:mfe:esm– Start remote in native federation modedashboards-demo:build:esm/dashboards-demo:build:esm:mfe/dashboards-demo:build:bridge:mfe– Build variantsAngular Configuration:
federation.config.jsfor both host and remote MFE with shared dependency configurationEnvironment Management:
.esm.tsand.esm.prod.tsenvironment files configuring federation base URLs and feature flagsmain.ts) with dual-path initialization supporting both federation modesTesting
Dependencies
Added:
@angular-architects/native-federation,@module-federation/enhanced,@softarc/native-federation-node,es-module-shims