2

I have several modules of styled components in a file exported which I want to dynamically import into another file.

I learned to import a module we have to do this

const Heading = dynamic( () => import("./style").then((module) => module.Heading), { ssr: false, } ); 

How can I import all the modules at once instead of importing them separately for every module from the same file?

I want to achieve something like this, but it gives me an error to load all components in a single import

 const {Heading , CustomError }= dynamic( () => import("./style").then((module) => module), { ssr: false, } ); 
3
  • 1
    dynamic is only meant for single components. Nextjs will do some behind-the-scene magic to make it a loadable component (wrap it inside a custom component of theirs) so you can't load several components that way. If you're worried about bundling / loading, you should look into webpack rather than nextjs itself, but I probably wouldn't recommend it unless you actually notice some performance issues. Commented Sep 25, 2022 at 6:53
  • 1
    @T.J.Crowder dynamic doesn't necessarily need a default export. The first code snippet in this question will work, and it uses a named export. Commented Sep 25, 2022 at 7:05
  • Thanks @Sheraff! I shouldn't have inferred that from React.lazy's requirement. In fact, the docs I linked even show how to do a named export. :-) Commented Sep 25, 2022 at 7:38

1 Answer 1

1

Caveat: I don't use Next.js (yet?). But trying to help anyway:

I think the nature of dynamic is that it creates and returns a single component facade when you call it, so you'll have to make multiple calls to dynamic. But that doesn't mean you have to repeat everything. Unless dynamic is a pseudo-function that's replaced at build time, you can give yourself a helper to do the heavy lifting:

const dynamicStyle = (name) => dynamic( () => import("./style").then((module) => module[name]), { ssr: false } ); 

Then at least each component is simpler and not (that) repetitive:

const Heading = dynamicStyle("Heading"); const CustomError = dynamicStyle("CustomError"); 

About this:

how can I import all the modules at once instead of importing them separately for every module from the same file

I suspect you meant "...for every component from the same file..." In case you're worried about the module being imported multiple times, don't be. Regardless of how many times you call import("./style"), the module is only imported once. If the module is already imported or being imported the second/third/fourth time you call import(), the promises from those calls just get fulfilled with the same module namespace object that the first one did/will. That's effectively guaranteed by the specification where it says:

Any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments referencingScriptOrModule and specifier, must return a normal completion containing a module which has already been evaluated, i.e. whose Evaluate concrete method has already been called and returned a normal completion.

Sign up to request clarification or add additional context in comments.

2 Comments

This will work, but be careful because the () => import("./style") part should remain static (you can't replace "./style" with a variable) otherwise the bundler won't work.
@Sheraff - Indeed, I was careful to use a string literal there. As you say, bundlers don't like truly dynamic imports, just ones that are optional/delayed. :-D (And fair enough.)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.