Skip to content
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

Failed to fetch dynamically imported module "/_nuxt/OpeningHours.CTqYYKGj.js" #26565

Closed
mikeCrafted opened this issue Mar 29, 2024 · 19 comments
Closed

Comments

@mikeCrafted
Copy link

Environment


  • Operating System: Windows_NT
  • Node Version: v21.6.1
  • Nuxt Version: 3.11.1
  • CLI Version: 3.11.1
  • Nitro Version: 2.9.5
  • Package Manager: npm@9.6.4
  • Builder: -
  • User Config: runtimeConfig, sourcemap, app, css, modules, i18n, alias, auth, build, site, schemaOrg, ogImage, sitemap, devtools
  • Runtime Modules: @sidebase/nuxt-auth@0.6.7, @nuxtjs/i18n@8.2.0, @pinia/nuxt@0.5.1, nuxt3-leaflet@1.0.12, @nuxtjs/seo@2.0.0-rc.10
  • Build Modules: -

Reproduction

This is an indeterministic bug in production, I cannot find commonalities when it occurs. Apple users (Safari browser) tend to have it more often. I get a lot of sentry errors and see it in the server logs, but mixed with a lot of correct requests, it works on all my devices and on ones of my colleagues, but according to sentry there are users who experience crashes.

Describe the bug

According to our sentry report, there are regular crashes of the app on many different pages (sometimes on the homepage, sometimes during search etc.), when nuxt fails to resolve a file path and the app crashes.

The majority of logs are fine, but still we see a regular issues popping up in sentry. The components that fail to resolve are also different. They work on all my devices, so I cannot reproduce the error in production. Nor does it occur in development.

We host the app on Azure App Service.

I recently upgraded to the latest nuxt version, where the naming of the chunks was changed, still I saw some logs today that a component with the old naming style could not be imported. I am not opting in for the old one, I switched to the default new one.

Can setting the builder: 'webpack' help?

I feel like this issue might be related @danielroe ? #21780

nuxt-error

Additional context

No response

Logs

No response

@danielroe
Copy link
Member

I suspect this is due to new deployments and failing to load a dynamic chunk after a new deployment occurs, which might have invalidating existing public assets. We currently handle chunk loading errors when navigating across routes but we could probably think about whether there is anything we could do when that is a dynamic component import.

@mikeCrafted
Copy link
Author

@danielroe is there anything I can do to avoid this crashing in production? did I understand correctly that this is due to the fact that I use Lazy components - i.e. dynamically loaded ones? Or is this an internal issue?

@michalzaq12
Copy link
Contributor

I can confirm that this issue (and others like it) occurs after a new deployment. This isn't just related to "Lazy Components" as it gives me the "Failed to load dynamically..." message for pages, layouts and middleware modules (chunks) as well. My observations when the error occurs:

  1. Lazy components
  2. The new deployment has not yet been detected by the check-outdated-build plugin
  3. The new deployment is detected by check-outdated-build and handled by Nuxt, but an unhandled exception still occurs (this error should be ignored)
  4. After a new deployment, somehow after a new visit, the old version of the page is loaded (how? Browser cache?) and immediately crashes with a "Failed to load dynamically..." for chunks that have changed (new file hash?)

@mikeCrafted
Copy link
Author

@michalzaq12 thank you for your observations! So I am using GitHub actions with Azure app service to deploy the app. Will a manual build an deploy via file upload for example help?

@michalzaq12
Copy link
Contributor

@mikeCrafted it won't help. For now, there is no way to avoid these errors.

@meirroth
Copy link

meirroth commented Apr 1, 2024

We've also encountered these errors after deployments, which we fixed by triggering page reload on chunk error by adding the following file plugins/error-handler.ts:

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('app:chunkError', () => {
    window.location.reload()
  })
})

I believe Nuxt should handle this internally, as I am sure it is a common problem.
Related Issues can be found on this thread: #14594

@mikeCrafted
Copy link
Author

@meirroth I think this handler is already added by default in Nuxt, see #19086
am I right, @danielroe ? Or can this custom plugin indeed make a difference?

@meirroth
Copy link

meirroth commented Apr 1, 2024

@mikeCrafted From what I understood, and I could be wrong, the built in handler takes care of errors only during route navigation. The plugin I shared above helps with any other chunk loading errors, such as lazy components.

@mikeCrafted
Copy link
Author

@meirroth oh, that is interesting! why are you not using reloadNuxtApp() instead of window.location.reload()?

@michalzaq12
Copy link
Contributor

We've also encountered these errors after deployments, which we fixed by triggering page reload on chunk error by adding the following file plugins/error-handler.ts:

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('app:chunkError', () => {
    window.location.reload()
  })
})

I believe Nuxt should handle this internally, as I am sure it is a common problem. Related Issues can be found on this thread: #14594

I see the possibility of an endless reload loop. That's probably why Nuxt doesn't support it internally.

@mikeCrafted
Copy link
Author

@michalzaq12 adding a query parameter to the URL would help, right? so that we can tell if a reload was already attempted.

@meirroth
Copy link

meirroth commented Apr 2, 2024

@meirroth oh, that is interesting! why are you not using reloadNuxtApp() instead of window.location.reload()?

@mikeCrafted Haven't tried that. I'll give it it a shot now.

I see the possibility of an endless reload loop. That's probably why Nuxt doesn't support it internally.

@michalzaq12 How so? I haven't encountered any issue in my testing, and got this running in production.

@meirroth
Copy link

meirroth commented Apr 2, 2024

@mikeCrafted reloadNuxtApp() is a wrapper for window.location.reload() with additional features like ttl and persistent useState. So considering we use Pinia and not useState, and I didn't need ttl window.location.reload() was good on it's own. But they both work, I just tested.

@mikeCrafted
Copy link
Author

@meirroth oh cool, thank you! what production site are you running?

@meirroth
Copy link

meirroth commented Apr 2, 2024

@mikeCrafted torahlive.com 😃

@michalzaq12
Copy link
Contributor

To avoid most errors:

  1. Do not delete old files during deployment, allow the user to smoothly update to the new version after a new visit (or when check-outdated-build detects new version)
  2. Make sure that all .html files are not cached (check Cache-Control header)
  3. Finally, you can add a plugin for users who still have a problem:
export default defineNuxtPlugin(nuxtApp => {
  const MAX_RETRIES = 2;
  const QUERY_PARAM_NAME = 'nuxt_reload_attempt'

  // Handle "Failed to fetch dynamically imported module ..." or similar issues
  nuxtApp.hook('app:chunkError', () => {
    const searchParams = new URLSearchParams(window.location.search);
    const currentRetry = Number(searchParams.get(QUERY_PARAM_NAME)) || 0
    if (currentRetry < MAX_RETRIES) {
      console.log('[nuxt]: Reloading due to chunk error')
      searchParams.set(QUERY_PARAM_NAME, (currentRetry + 1).toString())
      // Changing the search also causes a refresh
      window.location.search = searchParams.toString()
    }
  })
})

@meirroth
Copy link

meirroth commented Apr 8, 2024

I see the possibility of an endless reload loop. That's probably why Nuxt doesn't support it internally.

@michalzaq12 How so? I haven't encountered any issue in my testing, and got this running in production.

@nandi95
Copy link
Contributor

nandi95 commented Apr 23, 2024

Duplicate of #23612

@danielroe danielroe closed this as not planned Won't fix, can't repro, duplicate, stale Apr 23, 2024
@wgcorrea
Copy link

wgcorrea commented May 1, 2024

To avoid most errors:

  1. Do not delete old files during deployment, allow the user to smoothly update to the new version after a new visit (or when check-outdated-build detects new version)
  2. Make sure that all .html files are not cached (check Cache-Control header)
  3. Finally, you can add a plugin for users who still have a problem:
export default defineNuxtPlugin(nuxtApp => {
  const MAX_RETRIES = 2;
  const QUERY_PARAM_NAME = 'nuxt_reload_attempt'

  // Handle "Failed to fetch dynamically imported module ..." or similar issues
  nuxtApp.hook('app:chunkError', () => {
    const searchParams = new URLSearchParams(window.location.search);
    const currentRetry = Number(searchParams.get(QUERY_PARAM_NAME)) || 0
    if (currentRetry < MAX_RETRIES) {
      console.log('[nuxt]: Reloading due to chunk error')
      searchParams.set(QUERY_PARAM_NAME, (currentRetry + 1).toString())
      // Changing the search also causes a refresh
      window.location.search = searchParams.toString()
    }
  })
})

Doc says that hard reload at the route level is done by default: https://nuxt.com/docs/guide/going-further/experimental-features#emitroutechunkerror.

If the idea is to watch for that hook and refresh the window, I believe adjusting the emitRouteChunkError to manual might be required to avoid weird behaviour or making hard to debug what really is fixing the issue.

I'm having the same issue. Currently, deploying at Cloudflare Pages; and all cache settings were reviewed. We tried using a similar approach as the proposed plugin; even adding a t=Date.now() to the URL upon refresh to double down in the cache refresh force was not enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants