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

Template literals on dynamic imports #2514

Closed
nathanqueija opened this issue Jul 9, 2017 · 12 comments
Closed

Template literals on dynamic imports #2514

nathanqueija opened this issue Jul 9, 2017 · 12 comments

Comments

@nathanqueija
Copy link

nathanqueija commented Jul 9, 2017

Hi,
Is it possible to use a template literal for dynamic imports?
I'd like to import a component based on a condition.
For example:
const DynamicComponent = dynamic(import(../components/${operation}))

@sergiodxa
Copy link
Contributor

Due to how webpack handle code splitting it's not possible, that's because the bundles are statically generated, not dynamically at runtime, but you can create a map of dynamic imports with every possible case and use it based on a condition.

const Components = {
  Red: dynamic(import('../components/red.js')),
  Blue: dynamic(import('../components/blue.js')),
}

export default ({ color }) => {
  const Component = Components[color]
  return <Component />
}

@arunoda
Copy link
Contributor

arunoda commented Jul 9, 2017

Thanks @sergiodxa This is the perfect answer.

@Roger
Copy link

Roger commented Jul 11, 2017

Dynamic expressions are supported for code splitting https://webpack.js.org/guides/migrating/#dynamic-expressions

@luisherranz
Copy link

luisherranz commented Jul 19, 2017

That's right, Webpack does support this.

Is there any reason Nextjs shouldn't support it?

@OutThisLife
Copy link
Contributor

@sergiodxa Do all of the components get bundled to the client regardless if they're used or not?

If so, then what's the point?

@luisherranz
Copy link

luisherranz commented Aug 2, 2017

@OutThisLife they are not.

It works this way: imagine you have three files (works for folders too):
/components/hello1.js
/components/hello2.js
/components/hello3.js
and you use this code to dynamically import any of those:
const DynamicComponent = dynamic(import(./components/${name}))

Webpack will go to the /components folder and will analyze the files (or folders) there, creating three separate bundles, for example:
--components-hello1.js
--components-hello2.js
--components-hello3.js
then, on runtime, it will import the proper bundle if name matches either hello1, hello2 and hello3.

@arunoda
Copy link
Contributor

arunoda commented Aug 2, 2017

@luisherranz I'm not exactly sure that's a good way to do this.
I'm in favor of #2514 (comment) way to do this.

It's explicit and cleaner.

@luisherranz
Copy link

@arunoda yeah, I was just explaining how Webpack works internally.

I'd love to have that feature but it's probably not a must.

@Roger
Copy link

Roger commented Aug 2, 2017

I have an use case with plugins with 3 entry points (backend/frontend/data), without dynamic expressions support, i'll end with 45 if statements and the implementation would be more error prone

@IanMitchell
Copy link
Contributor

IanMitchell commented Aug 17, 2017

Jumping in to say I also have a use that involves >40 files and is growing, and having the ability to use template literals to get the right one instead of listing each by hand would be really nice. Would making a static list as part of next.config.js work, and then choosing from among that list using template literals on the page?

@chrisui
Copy link

chrisui commented Nov 23, 2017

This is a big problem for those of us who are building more dynamic apps. Take for example if you were reimagining react-storybook with next.js (which I am) and had a list of all your components. From these you want to bundle in the relative __stories__/${component}.stories.js file. How would you do this?

We can't keep a file with all the string literal imports because there are hundreds of components constantly being added and removed.

The only viable solution right now for us is to have another step in the dev/build pipeline which generates a file.

This is a shame because this was simple with webpack's context feature alone and with babel register could also work on the server since the import would not be evaluated until later. I'm assuming it's not working here because babel is trying to eagerly read and load imports and parse them?

@JulesAU
Copy link

JulesAU commented Dec 18, 2017

Struggling with this as well; the every-case map suggestion results in the same error, and in any case wouldn't that result in all of the dynamic imports being imported as soon as the const is declared?

@lock lock bot locked as resolved and limited conversation to collaborators Dec 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants