alienbuild
alienbuild

Reputation: 294

Nextjs dynamic import of multiple exports

I'm using a third party package which im loading using next js dynamic:

const am5 = dynamic(() => import("@amcharts/amcharts5"), {ssr: false})

The amcharts5 that it's importing is a bunch of exports and imports

export { Root } from "./.internal/core/Root";
export { Theme } from "./.internal/core/Theme";
export { addLicense, registry, disposeAllRootElements } from "./.internal/core/Registry";
export { ready } from "./.internal/core/util/Utils";
...several other lines and some imports too

However when I run dev/build my application is falling over due to this line below.

let root = am5.Root.new('chart')

The error is

TypeError: Cannot read properties of undefined (reading 'new')

I assume I need to somehow import the Root dynamically too ? I've tried the following already but it didn't work.

const { Root }= dynamic(() =>
    import('@amcharts/amcharts5').then((mod) => mod),{ssr:false}
)

And also

const Root = dynamic(() =>
    import('@amcharts/amcharts5').then((mod) => mod.Root),{ssr:false}
)

For reference the package documents importing like this (though i need to dynamically import this)

import * as am5 from "@amcharts/amcharts5"

Any help appreciated! :)

Upvotes: 2

Views: 3248

Answers (1)

Sam Gomena
Sam Gomena

Reputation: 1479

tl;dr: Next dynamic(() => ...) imports can only be used to import React components not third-party modules. Instead, you should use a regular old dynamic import(...).

The longer version:

This is confusing (for me at least) as the docs don't outright state that you can't import modules with dynamic(...), only that it should be used to import components:

React components can also be imported using dynamic imports, but in this case, we use it in conjunction with next/dynamic to make sure it works just like any other React Component.

And indeed, looking at this comment from a Next maintainer you can't use dynamic(...) to import modules, only components.

So here's a somewhat general solution noting that you may need to modify based on how and where you're using the module in your app:

  useEffect(() => {
    (async () => {
      const am5 = await import("@amcharts/amcharts5");
      am5.Root.new("chart");
    })();
  }, []);

Perhaps also handy is the Next docs on dynamic imports

Upvotes: 2

Related Questions