Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
@angular-architects/native-federation
Advanced tools
Native Federation is a "browser-native" implementation of the successful mental model behind webpack Module Federation for building Micro Frontends (Plugins, etc.).
Native Federation is a "browser-native" implementation of the successful mental model behind webpack Module Federation for building Micro Frontends (Plugins, etc.).
Angular & Angular CLI 16.1 or higher
This package was successfully tested with Angular CLI projects and with Nx projects.
We will at least provide a new version of this package per Angular major. If necessary, we will also provide packages to adapt to Angular minors. To make the relationship between Angular versions and versions of this package easy for all of us, we follow Angular's version numbers. E. g., @angular-architects/native-federation
16.1 is intended for Angular 16.1 and upwards.
If you currently use Angular with Module Federation, you can follow our Migration Guide to migrate to Native Federation and Angular's new fast esbuild-based build system.
In this article we describe, how to use both technologies side-by-side.
You can use ng update
for updating Native Federation.
Notes for updating to version 18
Since 17.1, Native Federation for Angular uses the Angular CLI's esbuild
-based Application Builder and the CLI's Dev Server to keep track with all the innovations and performance-improvements provided by the Angular CLI team.
Please find some information for upgrading to 17.1. here.
Big thanks to:
We migrated our webpack Module Federation example to Native Federation:
Please find the example here (branch: nf-standalone-solution):
git clone https://github.com/manfredsteyer/module-federation-plugin-example.git --branch nf-standalone-solution
cd module-federation-plugin-example
npm i
Start the Micro Frontend:
ng serve mfe1 -o
(In the case of an error, see this information below)
Wait until the Micro Frontend is started.
Open another console and start the shell:
ng serve shell -o
The example loads a Micro Frontends into a shell:
This package, @angular-architects/native-federation
, uses the same API as @angular-architects/module-federation
. To switch over, just make sure you import everything from the former package. Don't mix these packages.
The underlying mental model allows for runtime integration: Loading a part of a separately built and deployed application into yours. This is needed for Micro Frontend architectures but also for plugin-based solutions.
For this, the mental model introduces several concepts:
You can checkout the nf-standalone-starter branch to try out Native Federation:
git clone https://github.com/manfredsteyer/module-federation-plugin-example.git --branch nf-standalone-starter
cd module-federation-plugin-example
npm i
This repository consists of two Angular applications: a shell
and a Micro Frontend called mfe1
. During this tutorial, you will load mfe1
into the shell
:
npm i @angular-architects/native-federation -D
Making an application a remote (Micro Frontend):
ng g @angular-architects/native-federation:init --project mfe1 --port 4201 --type remote
Making an application a host (shell):
ng g @angular-architects/native-federation:init --project shell --port 4200 --type dynamic-host
A dynamic host reads the configuration data at runtime from a .json
file.
The schematics called here automate most steps of this tutorial, esp. adding configuration files and bootstrapping Native Federation. Hence, the following sections primarily discuss these changes. You just need to add a lazy route (see below) and make sure the correct ports are configured in the federation manifest (see below too).
The host configuration (projects/shell/federation.config.js
) looks like what you know from our Module Federation plugin:
const {
withNativeFederation,
shareAll,
} = require('@angular-architects/native-federation/config');
module.exports = withNativeFederation({
shared: {
...shareAll({
singleton: true,
strictVersion: true,
requiredVersion: 'auto',
}),
},
skip: [
'rxjs/ajax',
'rxjs/fetch',
'rxjs/testing',
'rxjs/webSocket',
// Add further packages you don't need at runtime
],
});
Our
init
schematic shown above generates this file for you.
Also, the remote configuration (projects/mfe1/federation.config.js
) looks familiar:
const {
withNativeFederation,
shareAll,
} = require('@angular-architects/native-federation/config');
module.exports = withNativeFederation({
name: 'mfe1',
exposes: {
'./Component': './projects/mfe1/src/app/app.component.ts',
},
shared: {
...shareAll({
singleton: true,
strictVersion: true,
requiredVersion: 'auto',
}),
},
skip: [
'rxjs/ajax',
'rxjs/fetch',
'rxjs/testing',
'rxjs/webSocket',
// Add further packages you don't need at runtime
],
});
Our
init
schematic shown above generates this file for you.
When bootstrapping the host (shell), Native Federation (projects\shell\src\main.ts
) is initialized:
import { initFederation } from '@angular-architects/native-federation';
initFederation('/assets/federation.manifest.json')
.catch((err) => console.error(err))
.then((_) => import('./bootstrap'))
.catch((err) => console.error(err));
This file is generated by the schematic described above.
The function points to a federation manifest. This manifest lists the individual remotes. It can be exchanged when deploying the solution. Hence, you can adapt the build to the respective environment.
Credits: The Nx team originally came up with the idea for the manifest.
This is what the (also generated) federation manifest (projects\shell\src\assets\federation.manifest.json
) looks like:
{
"mfe1": "http://localhost:4201/remoteEntry.json"
}
Native Federation generates the remoteEntry.json
. It contains metadata about the individual remote.
If you follow this tutorial, ensure this entry points to port 4201
(!).
When bootstrapping your remote (projects\mfe1\src\main.ts
), Native Federation is initialized too:
import { initFederation } from '@angular-architects/native-federation';
initFederation()
.catch((err) => console.error(err))
.then((_) => import('./bootstrap'))
.catch((err) => console.error(err));
Our
init
schematic shown above also generates this file.
After the initialization, it loads the file bootstrap.ts
starting your Angular application.
For loading a component (or any other building block) exposed by a remote into the host, use Native Federation's loadRemoteModule
function together with lazy loading (projects\shell\src\app\app.routes.ts
):
import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { NotFoundComponent } from './not-found/not-found.component';
// Add this import:
import { loadRemoteModule } from '@angular-architects/native-federation';
export const APP_ROUTES: Routes = [
{
path: '',
component: HomeComponent,
pathMatch: 'full',
},
// Add this route:
{
path: 'flights',
loadComponent: () =>
loadRemoteModule('mfe1', './Component').then((m) => m.AppComponent),
},
{
path: '**',
component: NotFoundComponent,
},
// DO NOT insert routes after this one.
// { path:'**', ...} needs to be the LAST one.
];
Start the remote:
ng serve mfe1 -o
(In the case of an error, see this information below)
Once the remote is started, start the shell:
ng serve shell -o
Now, by clicking at the 2nd menu item, you can load the remote directly into the host.
If you like the idea of webpack Module Federation but want to switch over to Angular's new esbuild builder, you can use this package.
Native Federation needs to prepare all your shared packages so that it can load them on demand as EcmaScript modules. This only happens once for development and once for production builds. The result of this is cached.
If the preparation of one of these packages fails, you get an error like this one:
For this, there are several reasons:
Perhaps you try to share a package intended for NodeJS/ a package that cannot be converted to EcmaScript modules. This happens if you use shareAll
in the federation.config.js
and when the package in question is part of your dependencies in package.json
. If you don't need (to share) this package at runtime, move it to devDependencies
or add it to the skip
section of your federation.config.js
.
Perhaps your shared packages contain some code esbuild cannot transfer to EcmaScript modules. This should not be the case for packages, built with the Angular CLI or Nx and the underlying package ng-packagr. If this happens, please let us know about the package causing troubles.
The good message is, that the official Angular Package Format defines the usage of ECMA Script Modules (ESM) for years. This is the future-proof standard, Native Federation is built upon and all npm packages created with the Angular CLI follow. If you use older CommonJS-based packages, Native Federation automatically converts them to ESM. Depending on the package, this might change some details. Here, you find some information for dealing with CommonJS packages.
Since version 18@latest, also transitive dependencies are shared. For instance, primeng
uses a lib @primeuix/styled
for theming. The latter one is now shared too if primeng
is. This prevents possible challanges but also results in more bundles. If you don't want to share such a transitive dependency, just put it into the skip
list.
Usually, Native Federation automatically detects entry points into shared packages. If the packages neither align with the official standard nor with typical conventions beyond these standards, you can also directly provide the entry point:
module.exports = withNativeFederation({
shared: {
...shareAll({
singleton: true,
strictVersion: true,
requiredVersion: 'auto',
}),
'test-pkg': {
packageInfo: {
entryPoint: '/path/to/test-pkg/entry.mjs',
version: '1.0.0',
esm: true,
},
},
},
});
As in such cases, we cannot expect to find a package.json
nearby, you also have to specifiy the version
and the esm
flag by hand.
The already prepared packages are cached in node_modules/.cache
. Make sure, this folder is reused across subsequent build process runs.
We use Import Maps at runtime. In addition to Import Maps, we use some code at build time and at runtime to provide the Mental Model of Module Federation.
Please have a look at this article series.
Even though these articles were written for Module Federation, thanks to the same API, they also apply to Native Federation.
In our Angular Architecture Workshop, we cover all these topics and far more. We provide different options and alternatives and show up their consequences.
FAQs
Native Federation is a "browser-native" implementation of the successful mental model behind webpack Module Federation for building Micro Frontends (Plugins, etc.).
The npm package @angular-architects/native-federation receives a total of 15,260 weekly downloads. As such, @angular-architects/native-federation popularity was classified as popular.
We found that @angular-architects/native-federation demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.