Skip to content

Introduce dynamic(() => import()) #5249

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

Merged
merged 14 commits into from
Sep 25, 2018

Conversation

timneutkens
Copy link
Member

@timneutkens timneutkens commented Sep 21, 2018

Fixes #5221
Fixes #5208
Fixes #5213

Bringing back some old non-standard behavior:

import dynamic from 'next/dynamic'

const HelloWorld = dynamic(import('../components/hello-world'))

export default () => <HelloWorld />

Will compile to:

import dynamic from 'next/dynamic'

const HelloWorld = dynamic(() => import('../components/hello-world'))

export default () => <HelloWorld />
  • next/dynamic accepts a loader function as first argument
  • next/dynamic usage with just dynamic(import()) is transpiled to a loader function,

The reason for these changes is that calling import() will immediately load the module when the code is executed, which is what most users don't want. This is to mirror Next 6 and below behavior around this syntax. Do note that it's non-standard and has to be deprecated. We can easily write a codemod to change this usage to the new loader function syntax.

  • We now send the webpack moduleIds to the client side so that the preloadReady react-loadable function can filter out only the modules needed for hydration, instead of loading everything and waiting for that. This will introduce a performance boost when you are using next/dynamic but also make sure that modules aren't loaded when you don't render them.

TODO v7.1

  • Make the transpiled function log a warning with an err.sh link that explains how to run the codemod
  • Write codemod

@tusbar
Copy link
Contributor

tusbar commented Sep 24, 2018

Partly fixes #5213 as well.

@timneutkens
Copy link
Member Author

@tusbar I've spent this morning testing against your reproduction and it seems like my patch mzgoddard/hard-source-webpack-plugin#446 fixes the wrong assignment of bundles too, I'm going to temporarily release the package under a prefix so that we can get rid of these issues 👍

@Fumler
Copy link

Fumler commented Sep 24, 2018

Been testing this branch a bit since we are also doing something similar to #5208 (we get the page composition from an API and dynamically load components based on if the page needs them) and we want the benefits of webpack 4 (great job, btw).

In ProfChaos' example repo https://github.com/ProfChaos/nexttest

The original page

import Icon from '../components/Icon'

export default () => {
	return (
		<div>
			<h1>Only load "one"</h1>
			<Icon name="one" />
		</div>
	)
}

This now works, the extra chunks are not loaded.

But if I do this

import Icon from '../components/Icon'

export default () => {
	return (
		<div>
			<h1>Only load "one"</h1>
			<Icon name="one" />
			<Icon name="one" />
		</div>
	)
}

Now the "one" chunk loads twice, and if you add e.g. 15 <Icon name="one" /> it still only loads twice.

edit:

export default () => {
	return (
		<div>
			<h1>Only load "one"</h1>
			<Icon name="one" />
			<Icon name="one" />
			<Icon name="one" />
			<Icon name="one" />
			<Icon name="one" />
			<Icon name="one" />
			<Icon name="one" />
			<Icon name="one" />
			<Icon name="one" />
			<Icon name="one" />
		</div>
	)
}

screen shot 2018-09-24 at 15 26 46

@timneutkens
Copy link
Member Author

Re: #5249 (comment)

Looks like it still doesn't work, spent most of the day debugging.

@timneutkens
Copy link
Member Author

@Fumler great catch, I've fixed it and added a test for it. 👍

@timneutkens timneutkens merged commit 42736c0 into vercel:canary Sep 25, 2018
@timneutkens timneutkens deleted the fix/only-load-rendered-module branch September 25, 2018 13:27
@arthens
Copy link

arthens commented Sep 27, 2018

@timneutkens I think this might be causing a different bug with dynamic imports, see #5305

@lock lock bot locked as resolved and limited conversation to collaborators Sep 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants