-
-
Notifications
You must be signed in to change notification settings - Fork 229
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
Seeing the dreaded ⨯ TypeError: Cannot read properties of undefined (reading 'call')
error again with NextJS
#2879
Comments
I have major PR which changes how the runtime is embedded. This may fix it. Do you have any custom chunk split? |
Awesome, I can try to upgrade again when that's ready. No, we don't have any custom chunk splitting. Our Next config just includes the MF webpack plugin, webpack resolve fallbacks, and For full context, we're running into an issue (and have been throughout this project over the past year) where anytime we deploy a producer without the consumer updating, we get an error from the MF runtime, and then the app stops working properly. Because it's NextJS, it manifests as hanging requests that eventually 504. I think this is due to our infrastructure: we use AWS Fargate on ECS to deploy 2 tasks for each MFE. What i believe is happening is that when a producer redeploys, both the 2 old tasks and the 2 new tasks are available concurrently for a short period of time. During this window, the consumers detect the change and refetch and recache the entry point. However, because we don't have sticky sessions, the consumer could first hit a new task to get the entry, then hit an old task when pulling a chunk/container. We see this in the logs as a 404 on the chunk because the filename is different on the old task versus what is in the new entry file. I've been trying to force clear the cache when this happens so that the consumer can refetch after the old tasks are removed, but there isn't a good way to do this. I saw in a recent release that the hashmap used by the hot-reload script was made available globally, so i tried to clear that from an API route. Technically, i think that worked, but i was running into the I have rolled back to the versions that were working, and I've found a workaround where I "force" the revalidate function to invalidate, but for some reason, i need to call it multiple times for it to work (I always thought it was not working at all, but hitting it in rapid succession seems to work). Ideally, I'd like to be able to do this from the If you're working on a runtime update, maybe you could expose a really simple and safe way to force clear all caches (not sure why I very much appreciate your work on this, thanks! |
@benmarch try In this release i have done a few things:
|
Thanks @ScriptedAlchemy! Sorry for the delayed response, i caught the plague last week. Let me try that and i'll get back as soon as i can. |
yeah no worries, feel better! I will be releaseing another "half" of the update in the near future. the current release opts into the experiment under the hood and the next release should implement the other half the the experiment so i no longer rely on entrypoint patching to inject federation runtime |
Can you create a repo I can debug? |
Let me see what i can do. I wasnt able to reproduce with the example repo earlier, but i'll try to set one up this weekend. |
Or can you do a zoom call? Dm me on twitter and we can do one whenever, just need to see a handful of thing for a few moments to understand usage |
Thanks @ScriptedAlchemy, I pinged you on twitter. I have all afternoon tomorrow and pretty much all day friday free if that works. Next week works for me as well. |
@ScriptedAlchemy I was able to partially reproduce this locally with the prerelease from this release (the one from last Friday): https://github.com/module-federation/core/actions/runs/11076163958/job/30778657753 I was able to get the ID of the module that wasn't loading (
This is part of what appears to be a map of exposed modules ("./pages/SearchResults" being one of the exposed modules). There is no other reference to To reproduce, i built the standalone apps and booted them up. Most pages are working as expected, but as soon as I go to the SearchResultsPage it throws this error with a 500. Looking at the code for the SearchResultsPage ssr chunk, it seems to be missing a lot of code that I would expect to be in there, so I'm wondering if it just didn't build correctly. I'm still digging into it; i want to try to comment some code out in that page component to see if it's contributing... Ok, the main difference on the SearchResultsPage compared to others is that we're using Next day... I was able to fully reproduce exactly the error we're seeing in QA (stack trace redacted): The syntax error is caused by a producer sending the 404 page to the consumer and Webpack tries to load it as a JS file. Once this happens, I haven't been able to find a way to recover, even by revalidating. Immediately after this happens, then next page load starts showing the "property of undefined" error, and it appears always to point to the page module. After i triggered this again i got this module ID: It's still possible that this is related to some code i have in my runtime plugin to remove things from the FederationHost module cache. Let me remove that and try again... Ok, I'm still getting the syntax error, but I'm no longer getting the "property of undefined" error 🎉 . This was the code i had in if (origin?.moduleCache?.has?.(remoteID)) {
log(remoteID, `Removing remote ${remoteID} from the module cache.`)
origin.moduleCache.delete(remoteID)
} So this immediate issue might be resolved, but i have more information about the effects of the syntax error: Even without the "property of undefined" error, the app does not recover from the syntax error (when the remote chunk 404s). Interestingly, this only happens on the page that the error occurred; the other pages continue to work correctly. Even after "fixing" the producers and revalidating the consumer, the app does not recover, it just keeps replaying the syntax error. I wonder if Webpack is still caching this due to the error? I think I'll stop here and get your feedback. I'll try updating to the latest prerelease as well to see if the latest changes make a difference. Thanks! Quick update: this is where the syntax error is being thrown, and I think it's part of the MF code, so maybe it just comes down to cache-busting these errors: |
You cant use next/dynamic with federated imports - it converts them into require calls, not async imports. The ssr flag doesnt do anything as it still requires the code in both builds. Use react lazy instead. If there is syntax error then yes it might be getting a http response like 404 page from the url and cannot evaluate it. If the url was a query string, would that get around the cache? or is it that the whole url it gets just doesnt exist anymore. |
@ScriptedAlchemy I've spent a few days trying to replace all my next/dynamics with react lazy, but I can't seem to avoid hydration errors when i use it. Even in the simplest cases I'll either get "initial UI does not match what was rendered on the server" or "Suspense boundary received an update before it finished hydrating". I see in the docs it says using next/dynamic will cause hydration errors, but I'm seeing the opposite. Is this a complete no-go if I'm using dynamic, or is it ok as long as it's not causing immediate errors?
The whole URL doesn't exist because it's named based on a hash. So an example would be "/_next/static/ssr/__federation_expose_AssetCard-8e384a5185d76b62.js". When it changes, the hash would be different and return a 404, which does contain the HTML for the generic 404 page and fails to evaluate. |
Next dynamic can only be used on federated imports. If you have other imports for non-module federation code, Next will want dynamic for inter-component dynamic import or local imports. Regarding the 404, yes, that looks right. Or at least like there's an old remote entry in the server but the JavaScript files and unloaded chunks have changed? Does the 404 evaluation "hard crash" execution or does it just throw to a runtime plugin hook? |
@ScriptedAlchemy when the 404 fails to evaluate it does throw to the runtime plugin, but it never recovers like it does when a remote is offline initially and then comes online later. Meaning, even when the remotes are invalidated and the caches are cleared, I'll keep getting the same error replayed until the consumer is rebooted. I unfortunately need to work on some other things, but I'll come back to this the week after next. Thank you for your help on this! |
No worries. Thanks ill try looking around with this info |
Describe the bug
Note: I'm not able to reproduce this in the example repos, and I can't expose my project publicly. I've spent a while trying to track down the problem, but I can't seem to find where these specific modules are removed from the module cache. I'm just hoping for some advice on how to track this down.
It appears only to happen with modules in the share scope (at least the ones that trigger the error are specifically shared modules, but I'm not sure if other modules would also have the same issue if the app didn't crash).
This was an issue in a much older version of the MF plugins, but I hadn't seen it in quite some time. I'm upgrading from
[email protected]
and[email protected]
to[email protected]
and[email protected]
.Any advice would be appreciated. Thanks!
More info:
This appears to happen only after a remote updates and the host detects the update. I see this message in the console:
Then shortly afterward I see this:
which points to
webpack-api-runtime.js
in the__webpack_require__
function:I've tried commenting out some of the new code in
hot-reload.ts
but it still occurs.Reproduction
(sorry, i can't reproduce outside my project)
Used Package Manager
npm
System Info
Validations
The text was updated successfully, but these errors were encountered: