angular-architects / module-federation-plugin

MIT License
724 stars 196 forks source link

Issue with Loading MFE Routes in Native Federation - GET /routes.js 404 #672

Open Oadelek opened 3 days ago

Oadelek commented 3 days ago

For which library do you need help?

native-federation

Question

Description: Hi, I recently migrated my frontend apps from Module Federation to Native Federation, using Webpack and Angular v17. I’m conducting a proof of concept (POC) with Native Federation and decided to try out the latest version offered by angular-architects. In my package.json, for both the shell and micro-frontends (MFEs), I am using version 18.2.2, which I believe is the latest version. As part of this migration, I upgraded Angular to v18.

The issue I am facing is specific to my enterprise app, which includes numerous in-house libraries, making it difficult to reproduce outside our environment. However, I was able to set up a small demo project with a shell and two MFEs that worked fine using Native Federation. But when I attempted to apply the same method to my main app (previously established with Module Federation), I encountered the following issue.

Issue:

GET http://localhost:4201/routes.js 404 Not Found
TypeError: 404 Not Found http://localhost:4201/routes.js at doFetch (es-module-shims.js:816:21)
at async fetchModule at async es-module-shims.js:895:40

Current Setup:

Attempts and Observations:

Question:

I’m wondering why the app is attempting to load routes.js and failing. In my working demo, the routes.js file loads successfully, but in the larger app, it doesn't. I suspect the issue might be due to a misconfiguration in the federation settings or routing but can’t pinpoint the exact cause.

If you have any insights or suggestions on what could be causing this, I’d appreciate your help. Please feel free to ask for any clarification you might need, as I understand I’ve provided a lot of information.

Thanks in advance for your assistance!

Oadelek commented 3 days ago

Additional Comment:

Also, in the small demo I mentioned earlier for native federation (which worked fine), I noticed that when I updated the federation.manifest.json in the shell of this small demo to point to my enterprise remote MFE at localhost:4201, I encountered the same error: it couldn't find 4201/routes.js, even though it successfully loads routes.js in the small demo MFE.

This makes me think the issue might not stem from the shell in my main enterprise app but rather from the firstMfe (the entreprise remote MFE) itself.

For additional context, all the apps are standalone projects. In the bootstrapping process for the firstMfe, we call app.config, where in the providers array, I include provideRouter(APP_ROUTES). In the app-routes.ts file, I only have one route defined with an empty path:

{
  path: '', 
  loadComponent: () => import('./module/main/components/mfe-docs/first-mfe.component')
    .then(m => m.FirstMfeComponent), 
  pathMatch: 'full'
}

(Note: "FirstMfeComponent" is just a placeholder name for the actual component in the enterprise MFE.). This path is defined similarlyto how I did for the mfes in the small demo project and it worked fine.

I hope this additional context helps to clarify the issue. Let me know if you need further details.

Oadelek commented 3 days ago

Also, in my large enterprise shell app, when I update the federation.manifest.json file to point to the remoteEntry for the small demo MFE, it successfully loads it. This further confirms that the issue doesn't seem to originate from the shell or the way routing is set up in the shell.

Given this, what could be causing the issue? Any insights would be appreciated!

Oadelek commented 3 days ago

One additional comment, in the firstmfe remote enterprise mfe that is giving me issues, intermittently I see it blank and it simply shows on the browser console: Error: Unable to resolve specifier '@angular/platform-browser' imported from http://loalhost:4201/chunk-34553.js at throwUnresolved (es-module-shims.js). This only goes away when I refresh it. Sometimes once, sometimes more. Now this doesn't happen all the time. Sometimes it displays properly only to show that error after a while with a blank page. My federation.config file is standard. Only difference is that I skip some additional in-house design libraries but never any angular core library is skipped.

rainerhahnekamp commented 2 days ago

However, I was able to set up a small demo project

@Oadelek, what it possible to use our stackblitz template so that we can see your demo project as well?

Oadelek commented 2 days ago

Additional Comment:

Hi, as I mentioned earlier, there's no way to reproduce my main app since it contains in-house JavaScript libraries. I apologize as annoying as this can be. That said, I did manage to partially fix the issue in an unusual way.

Previously, in the routing file for the first MFE, the routes were exported as:

export const APP_ROUTES: Routes = [/* routing definitions */];

This was correctly imported into the app.config file and used with provideRouter(). However, I found that Native Federation didn’t expect this. Instead, it required:

export const routes: Routes = [];

After making this change, it started working, and the routes.js file was successfully retrieved. However, an hour later, without any changes, it stopped working again. To fix it, I renamed the routing file from app-routes.ts to follow the standard naming convention app.routes.ts. This seemed to resolve the issue. Even though it's recommended to follow naming conventions, it’s strange that this worked fine with Module Federation but not with Native Federation. It seems Native Federation expects app.routes.ts to compile into routes.js for the shell to consume.

That said, I intermittently encounter this error on the MFE:

Error: Unable to resolve specifier '@angular/platform-browser' imported from http://localhost:4201/chunk-34553.js at throwUnresolved (es-module-shims.js)

I don’t understand the root cause of this. After refreshing once or twice, the error disappears. I suspect it could be related to how the bootstrapping process and initFederation work, as I've seen a similar issue posted here: Issue #671.

However, unlike the linked issue, I only see this error for platform-browser. I previously encountered it for core Angular libraries as well, but I added some third-party libraries (e.g., loglevel, path-to-regexp) to the skip section in federation.config.js, as well as some in-house core design libraries. I'm wondering why, compared to webpack.config.js where you can specify shared libraries, Native Federation doesn't seem to offer a similar mechanism. Are there any plans for this?

Currently, I have a limited understanding of Native Federation with Angular, but I'm hoping to learn more and provide better insights on the issue.

rainerhahnekamp commented 1 day ago

@Oadelek, thanks for your detailed description. It doesn't annoy as at all, it is just very hard to help you.

If you've nailed down the problem to the router configuration, could you maybe re-create this router configuration in the provided StackBlitz example? You don't have to add the rest, like your in-house made libraries. It can be very minimalistic.

Oadelek commented 7 hours ago

Hi, so should I also modify the angular.json and package.json file? or is that not necessary

rainerhahnekamp commented 6 hours ago

If you have to modify these files to provide a reproducible example, then please feel free to do so.

Oadelek commented 2 hours ago

So initially, my routes file for the first MFE looked like this: StackBlitz example. I then modified it as described earlier. However, I'm now intermittently seeing an issue where Angular core libraries, mainly @angular/platform-browser, cannot be resolved.

I don’t think you'll be able to directly help me solve this, but I’d appreciate any tips on what might generally cause this issue. For some reason, in the generated chunks, it’s unable to locate @angular/platform-browser. What’s odd is that this only happens intermittently, and it mainly occurs when I’m checking the console directly on the MFE’s domain port, not through the host.

Do you have any idea why this could be happening?