I have a Monorepo Angular Workspace and I'm using @angular-architects/module-federation
14.13.14 and have been following the documentation to create a POC.
I've been trying to run a single instance of a local shared library across my micro frontends but no cigar.
Here's the structure of my workspace:
Workspace
|- Projects
|- shell
|- app1
|- lib1
|- service
|- name: BehaviorSubject<string>
I've used dependency injection to subscribe to name
on both shell
and app1
. I've created a method on shell
to pass a new value to name
(this.lib1Service.name.next('some other thing')
. But this doesn't reflect on app1
, only on shell
.
I've added path mapping to tsconfig.json
as instructed by the author:
"paths": {
"lib1": [
"projects/lib1/src/public-api.ts"
]
},
According to the documentation, this would be enough in the new version of the plugin:
New streamlined configuration in version 14+
Beginning with version 14, we use a more steamlined configuration, when using the above mentioned --type switch with one of the following options: remote, host, dynamic-host. This new configuration automatically shares all local libraries. Hence, you don't need to do a thing.
I've also tried to add the library to the sharedMappings
array on both shell
and app1
webpack.config.js
files:
sharedMappings: ['lib1'],
This is my shell
's webpack.config.js
:
const { shareAll, share, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
module.exports = withModuleFederationPlugin({
shared: {
...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
},
// sharedMappings: ['lib1'], // tried uncommenting this but it doesn't work
},
});
EDIT: I've also tried manually sharing each library as singletons and include the library amongst them in my shell
's webpack config file:
shared: share({
"@angular/core": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/common": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/common/http": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"@angular/router": {
singleton: true,
strictVersion: true,
requiredVersion: "auto",
},
"lib1": { singleton: true, import: "../lib1/src/public-api.ts" },
"rxjs": {
singleton: true,
requiredVersion: "auto"
}
})
What am I doing wrong? Please help :)
FOR ANYONE WHO STUMBLES UPON THIS THREAD:
I've found the solution. The import in your components that are consuming the service should match the name of your path mapping on tsconfig.json
.
For example, I've declared my shared lib like this on tsconfig.json
:
"paths": {
"lib1": [
"./projects/lib1/src/public-api.ts"
]
},
So, in my micro frontends, I should import the service like this:
import { Lib1Service } from 'lib1';
instead of
import { Lib1Service } from 'projects/lib1/src/public-api';
And that's it. Manfred Steyer was right. Once you declared the shared lib in your tsconfig.json
, you won't need to do anything else (if you're using the shareAll
approach in your webpack.config.js
, that is).