2

I'm using Next.js to develop a website.

I want to use dynamic import import() to dynamically load a module. It might not exist.

And if it does not exist, I'm OK with supressing it:

const Blog = async () => {

    let Layout = <div>Fallback layout</div>
    try {
        const { ModuleLayout } = await import('path-to-module').catch(reason => {})
        if (ModuleLayout) {
            Layout = ModuleLayout
        }
    }
    catch (error) {
        // intentionally swallawed
    }

    return <Layout />
}

I would expect the try-catch statement to suppress the error for me.

But I get this error:

Module not found: Can't resolve 'path-to-module'

Why the catch block does not work? How can I catch the error of dynamic import?

Big boy
  • 1,113
  • 2
  • 8
  • 23

1 Answers1

4

The try-catch works with normal JavaScript in both the browser and Node:

  try {
    const { ModuleLayout } = await import('path-to-module').catch(reason => { })
    if (ModuleLayout) {
      console.log(ModuleLayout);
    }
  }
  catch (error) {
    console.log('error');
  }

BTW the .catch there is redundant.

I think the problem here is that Next does extra analysis on imports through WebPack:

https://github.com/webpack/webpack/issues/6680#issuecomment-370800037

The suggestion here is to constrain the path to a known directory, but that might not be applicable in your case. Maybe your usecase would make for a good issue on the Next repository so that Vercel is motivated to add a flag to disable the static analysis for certain imports.

Documentation about dynamic import in Next: https://nextjs.org/docs/advanced-features/dynamic-import#example

Note: In import('path/to/component'), the path must be explicitly written. It can't be a template string nor a variable. Furthermore the import() has to be inside the dynamic() call for Next.js to be able to match webpack bundles / module ids to the specific dynamic() call and preload them before rendering. dynamic() can't be used inside of React rendering as it needs to be marked in the top level of the module for preloading to work, similar to React.lazy.

No hint on how to work around this and get a truly dynamic export at runtime.

Someone here claims warapping the import in dynamic did the trick for them.

Tomáš Hübelbauer
  • 9,179
  • 14
  • 63
  • 125