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

[Bug?]: TypeError: Failed to fetch dynamically imported module #9352

Open
1 task
pvenable opened this issue Oct 27, 2023 · 9 comments
Open
1 task

[Bug?]: TypeError: Failed to fetch dynamically imported module #9352

pvenable opened this issue Oct 27, 2023 · 9 comments
Assignees
Labels
bug/confirmed We have confirmed this is a bug topic/web

Comments

@pvenable
Copy link
Contributor

What's not working?

We're seeing some errors in production like TypeError: Failed to fetch dynamically imported module: <url>, where <url> will be something like https://example.com/assets/ExamplePage-e948e32f.js.

I suspect this mainly occurs on client navigation to a code-split page after a deployment where the chunk names have changed -- this looks like an issue with code splitting and "expected" chunks not being present in the newer deployment.

I'm not sure whether this would be considered a bug per se that redwood should handle out of the box, or whether this is up to each application to decide how to handle as a natural symptom of code splitting, so I was hoping to get some clarity on that if nothing else.

If it needs to be handled at the app level, I'm thinking catching the specific error on navigation and either "hard"-reloading or navigating to the destination path might be the way to go (depending on when exactly it occurs). I'm not sure yet if there are e.g. any navigation/router error hooks to tap into to that would simplify this.

I was also surprised to find no mention of this in any existing issues, so I'm not sure if this just isn't happening to others.

(FWIW I've also noticed what I think are similar errors in development since switching to vite in redwood 6, though the app seems to auto-reload when similar errors occur in development.)

How do we reproduce the bug?

I don't have an exact repro yet; I'll update this section later if possible. But I think it's basically: deploy new version of app and attempt client side navigation to request a now-missing chunk.

What's your environment? (If it applies)

Redwood 6.3.2

Are you interested in working on this?

  • I'm interested in working on this
@pvenable pvenable added the bug/needs-info More information is needed for reproduction label Oct 27, 2023
@jtoar
Copy link
Contributor

jtoar commented Oct 27, 2023

Hey @pvenable

I suspect this mainly occurs on client navigation to a code-split page after a deployment where the chunk names have changed -- this looks like an issue with code splitting and "expected" chunks not being present in the newer deployment.

As far as I understand the issue, this is pretty much exactly it. It's a real bug and we've had two reports of it internally. Here's the associated Vite issue: vitejs/vite#11804. The workaround we've seen a user use is the one mentioned in the comment here: vitejs/vite#11804 (comment).

I'm not sure whether this would be considered a bug per se that redwood should handle out of the box, or whether this is up to each application to decide how to handle as a natural symptom of code splitting, so I was hoping to get some clarity on that if nothing else.

I'll bring this up to the team next week. If you ask me, I feel like the framework should handle it. The alternative is expecting pretty much every user to hack their FatalErrorPage to check localStorage.

@thedavidprice thedavidprice added bug/confirmed We have confirmed this is a bug and removed bug/needs-info More information is needed for reproduction labels Nov 2, 2023
@thedavidprice
Copy link
Contributor

thedavidprice commented Nov 2, 2023

Internally we are escalating this issue as a top priority. Because the core problem is upstream (Vite), we're in a bit of a catch-22 — most likely this will be a two-step process:

  1. short-term: workaround to resolve negative production behavior
  2. long-term: add functionality to Redwood that fully resolves the problem and gives devs control over desired behavior

If you have ideas/suggestions/expectations about how you'd like to handle the case where a) client chunks are b) out of sync with newly deployed chunks, please comment below!

Workaround

You can manually resolve the production error by forcing the window to reload. Add the code below to web/src/pages/FatalErrorPage/FatalErrorPage.tsx|jsx. In the current default file that ships with Redwood v6, you'll insert at Line 14 starting with the (({ error }) => { block below and ending with return ( (just before the html main tag:

// web/src/pages/FatalErrorPage/FatalErrorPage.tsx|jsx

...
import { DevFatalErrorPage } from '@redwoodjs/web/dist/components/DevFatalErrorPage'

export default DevFatalErrorPage ||
  (({ error }) => {
    if (
      error?.message?.includes(
        'Failed to fetch dynamically imported module'
      ) &&
      !window.location.href.includes('reload=1')
    ) {
      if (window.location.href.includes('?')) {
        window.location.href = window.location.href + '&reload=1'
      } else {
        window.location.href = window.location.href + '?reload=1'
      }
      return
    }

    return (
    <main>
      <style
           ...
      />
      <section>
        <h1>
          <span>Something went wrong</span>
        </h1>
      </section>
    </main>
    )
  })

You may need to modify the error check behavior per your application's unique implementation. Here's an alternate approach that's also working in production:

...
export default DevFatalErrorPage ||
  ((({ error }) => {
    const filename = error?.message.match(
      /Failed to fetch dynamically imported module:.+\/assets\/(.*)/
    )

    const prevDynamicImportModuleFailure = localStorage.getItem(
      'dynamicImportModuleFailureFile'
    )

    if (filename && filename[1] !== prevDynamicImportModuleFailure) {
      localStorage.setItem('dynamicImportModuleFailureFile', filename[1])

      window.location.reload()

      return null
    } else {
...

If you find a solution that works better for your app, please share it in the comments.

@Tobbe
Copy link
Member

Tobbe commented Dec 2, 2023

Update: This is a priority for the Core Team. We have a meeting scheduled for Wednesday where we will discuss what the next step should be

@ManavDia
Copy link

ManavDia commented Dec 6, 2023

Hi I'm also seeing this in local development on Vite dynamic dependency optimisation upon visiting a page/cell for the first time after

yarn rw dev

image

The error page shows for a second before being reloaded

This is causing some of our Playwright E2E tests to intermittently fail. I've tried to resolve this with vite.config.js changes, by preloading all dependency optimization in dev, but I was not successful. Any help is appreciated!

image

@Tobbe Tobbe self-assigned this Dec 6, 2023
@Tobbe
Copy link
Member

Tobbe commented Dec 8, 2023

@ManavDia I'm not sure that's the exact same error as this issue is about. Could you please try to provide us with a github repo we can clone and clear instructions on how to reproduce?

Thanks 🙏

@Tobbe
Copy link
Member

Tobbe commented Dec 8, 2023

I've reproduced the "TypeError: Failed to fetch dynamically imported module" error locally
image

I just generated our test project, and then did yarn rw build && yarn rw serve and finally I went to the home page. Then, and this is important, without visiting BlogPostPage I edited BlogPostPage.tsx and rebuilt the page yarn rw build. Now when clicking on one of the blog posts on the home page the "failed to fetch" error is triggered.

We will try to handle this by adding error handling to our dynamic page loading code as a first step. We're also hoping we can follow up with some improvements to let developers hook into the error handling to customize the behavior.

We also decided we didn't want to try to provide a generic solution to all missing chunk errors that can happen. If the developer has other lazy-loaded components (i.e. not just the pages that RW lazy loads on its own) then it's up to the individual developer to handle any errors with loading those components in a way that best fits their unique application.

@rohin-stafflink
Copy link

Hello @Tobbe, were fixes for this issue released in newer versions of Redwood? we are still currently on v6 and getting this issue.

@elifkinli
Copy link

Is there any update on this issue? We are experiencing it on v7. Thanks!

@rohin-stafflink
Copy link

Hello @elifkinli yes I found a plugin thats working great so far - https://www.npmjs.com/package/vite-plugin-preload

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/confirmed We have confirmed this is a bug topic/web
Projects
None yet
Development

No branches or pull requests

8 participants