angular-architects / module-federation-plugin

MIT License
715 stars 192 forks source link

Really need help sharing a service between mfes #188

Open EliteSuperGames opened 2 years ago

EliteSuperGames commented 2 years ago

I have been trying to get this to work for hours and hours. I've googled the hell out of it and probably read every single stackOverflow post and random half assed article and nothing provides a solution, just a bunch of people throwing out suggestions that don't work.

https://github.com/jcardoz/SampleAngularWorkspace/tree/feature/part-2

I've followed this tutorial, I have the shell and a remote MFE both served up, and created a service to try to share data between them, but the service gets instantiated twice. The service is simple, here is basically all thats in it.

testValue: BehaviorSubject('test');

getValue(): Observable { return this.testValue.asObservable(); }

setValue(val: string): void { this.testValue.next(val); }

Each MFE's app.component.ts is subscribing to this, and I've created an input in each app.component to update the value, but they are isolated from each other and changes don't reflect across apps.

Can anyone point me to something that actually shows how to accomplish this task? The docs have a tiny paragraph that mentions it, but of course the thing mentioned doesn't work.

EliteSuperGames commented 2 years ago

I tried the tutorial on this github https://github.com/angular-architects/module-federation-plugin/blob/main/libs/mf/tutorial/tutorial.md

This project actually accomplishes exactly what I'm trying to do with the login userName. It was extremely easy to implement, but its using Angular 14 so the webpacks have basically nothing in them because of the "shareAll" function. The project at my job is using Angular 13, and upgrading to v14 isn't an option. Would anyone be able to translate the webpack files from v14 -> v13? I'd be so appreciative, because I'm about to go insane.

ytakahashi-d commented 2 years ago

Did you add rxjs at shared in webpack.config.js? I had to add peer dependencies of a sharing service.

david-griffin-fis commented 2 years ago

I'll add rxjs in webpack and see if that does anything. Not sure what you mean by your second sentence though, could you elaborate?

david-griffin-fis commented 2 years ago

Adding rxjs did nothing. I was able to get the service to only instantiate one time application wide, but now that I have deployed the application it is back to the previous behavior of each MFE instantiating its own service.

I created a library in the project, and this library has the service that I need to be the singleton.

Each MFE's webpack.config.js has this library included in the sharedMappings like so:

sharedMappings.register( path.join(__dirname, '../../tsconfig.json'), ['@shared-library']);

I'm also including the library in the shared array of the webpacks:

shared: share({ ...stuff, "@shared-library": { singleton: true, strictVersion: true, requiredVersion: 'auto' }, ...

tsConfig.json has a path for the library like so "paths": { ...other paths, "@shared-library": [ "projects/shared-library/src/public-api.ts" ]

Like I said, with this setup, it works correctly locally and each MFE shares the same instance of the service, but when deployed, each one instantiates its own version. I tried changing the providedIn: 'root' to 'platform' in the service, but the service has its own dependencies which makes it give me a null injector error because those dependencies don't have a provider at the platform level.

There really needs to be more complete examples of how to use this plugin, I've seen so many questions online that are basically the same as mine (regarding needing a singleton service), and there isn't a solution that works for a single person. I'm going to ask my team lead this week to just scrap this whole architecture altogether because there's no support and all examples are extremely basic and useless.

kiruthin commented 2 years ago

Is it possible to share your repo? I am concerned as well if this is problematic as we are in the middle of evaluating as well. Thanks!

david-griffin-fis commented 2 years ago

It isn't something I can share due to it all being done on company time, sorry. Its possible I'm just missing something obvious, but I've followed everything the docs/guides say regarding this particular issue and nothing works. Due to the amount of people that use this thing I'm sure others have it figured out.

ytakahashi-d commented 2 years ago

@david-griffin-fis regarding peer dependencies, In my case, I have AuthService that uses "@openid/appauth" and Rxjs. And I export AuthService from a library.

I shared the library via webpack and I could use AuthService in Shell and Client, but I wasn't a singleton service until I share "@openid/appauth" and Rxjs via webpack.

EliteSuperGames commented 2 years ago

@ytakahashi-d any chance you could share some of that code? Mostly the webpack.config.js files, tsconfig, the AuthService file and the public-api.ts file of the library? Or if you could share the important snippets it would be very helpful.

My service is importing a few things from RXJS like BehaviorSubject, ReplaySubject etc, HttpClient, a company-made auth module, and a couple other imports. I believe everything imported in my service is already being shared in the webpacks, but I'll check again and see if anything is missing, or maybe I'm just sharing those libraries wrong altogether.

One other thing, is your project being deployed anywhere and working correctly there as well?

jeff-hull-ultimate commented 2 years ago

I have this same issue.... @dgriffin123 were you able to arrive at a stable solution?

david-griffin-fis commented 2 years ago

@jeff-hull-ultimate unfortunately no, not when deployed. Do you have it working locally and not while deployed, or just not at all?

We scrapped the MFE project because it was causing more issues than it was solving.

grimaldistudio commented 2 years ago

Hi, I thought I was the only one with this problem! I also have shared libraries with some Services inside. Locally everything works correctly, when I build and deploy the services are not shared as they should.

angular-architects / module-federation: 13.0.1 angular core: 14

`sharedMappings.register( tsConfigPath, [

/* mapped paths to share */
'@ng-usermgmnt-mfe-app/shared/data-access/api',
'@ng-usermgmnt-mfe-app/shared/ui'

], workspaceRootPath );`

david-griffin-fis commented 2 years ago

@grimaldistudio glad its not just me! Hope you're able to figure it out. Would be cool to get some official word on this.

grimaldistudio commented 2 years ago

@david-griffin-fis I have been looking for a solution since this morning, hopefully in an official indication. In any case, as soon as I know something I write it here.

ytakahashi-d commented 2 years ago

@dgriffin123 I tried the sample and it didn't work as singleton. I'm using a private library that independents from my projects. It's still working as singleton today.

grimaldistudio commented 2 years ago

An update, as I suspected to generate this type of problem is the build with the production parameter. I did the build of the MFEs in dev mode, for example in my case:

nx run shell: build: development

I loaded the dist in the dev environment and everything is working correctly with all shared libraries and service singletons.

Of course it is not the definitive solution but it can encourage someone to give useful ideas. Thank you

grimaldistudio commented 1 year ago

I picked up the problem after some time. Damn it was my oversight !! Only now I realized that the MFE shell webpack.prod.config.js does not include all shared libraries. I insisted on looking exclusively at webpack.config.js ... Now everything works correctly, unforgivable sorry.