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

when dependency modules use React.lazy, vite convert more 'default' wrapped the component #4553

Closed
7 tasks done
SheldonWatson opened this issue Aug 9, 2021 · 18 comments · Fixed by #4596
Closed
7 tasks done

Comments

@SheldonWatson
Copy link

Describe the bug

When I use this code:
image
throw this error:
image
I guess vite may convert more 'default' wrapped the component, which cause the error.

Reproduction

https://github.com/SheldonWatson/vite-commonjs-isure

System Info

System:
    OS: macOS 11.2.3
    CPU: (8) arm64 Apple M1
    Memory: 139.81 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.1.0 - ~/n/bin/node
    Yarn: 1.22.10 - /opt/homebrew/bin/yarn
    npm: 7.17.0 - ~/n/bin/npm
  Browsers:
    Chrome: 92.0.4515.131
    Safari: 14.0.3
  npmPackages:
    vite: ^2.4.4 => 2.4.4

Used Package Manager

npm

Logs

No response

Validations

@ygj6
Copy link
Member

ygj6 commented Aug 10, 2021

Because @material-ui/icons/Search is a comonJS module, vite will convert it to esm during dependency pre-bundling, so .default is required for dynamic import, for example:

React.lazy(async () => (await import('@material-ui/icons/Search')).default)

@SheldonWatson
Copy link
Author

Because @material-ui/icons/Search is a comonJS module, vite will convert it to esm during dependency pre-bundling, so .default is required for dynamic import, for example:

React.lazy(async () => (await import('@material-ui/icons/Search')).default)

I'm still confused, when I use import Search from '@material-ui/icons/Search', it's right,
why dynamic import will cause error?

@SheldonWatson
Copy link
Author

SheldonWatson commented Aug 10, 2021

In other words,when I use a third part dependency, what's the applicable way to use React.lazy, ?
does your way is still work for esm dependency?

React.lazy(async () => (await import('@material-ui/icons/Search')).default)

@ygj6
Copy link
Member

ygj6 commented Aug 10, 2021

In other words,when I use a third part dependency, what's the applicable way to use React.lazy, ?
does your way is still work for esm dependency?

React.lazy(async () => (await import('@material-ui/icons/Search')).default)

Both ways are possible, only the time to load the module is different.

The import Search from '@material-ui/icons/Search method attaches default members to Searchdocument link.

And the dynamic import import('@material-ui/icons/Search') is returning a promise, so it is asynchronous, document link.

(await import('@material-ui/icons/Search')) returns the entire module object, so .default is needed to use the default members of the module.

@SheldonWatson
Copy link
Author

In other words,when I use a third part dependency, what's the applicable way to use React.lazy, ?
does your way is still work for esm dependency?

React.lazy(async () => (await import('@material-ui/icons/Search')).default)

Both ways are possible, only the time to load the module is different.

The import Search from '@material-ui/icons/Search method attaches default members to Searchdocument link.

And the dynamic import import('@material-ui/icons/Search') is returning a promise, so it is asynchronous, document link.

(await import('@material-ui/icons/Search')) returns the entire module object, so .default is needed to use the default members of the module.

Thx for your detailed document link,but I still want to know if (await import('@material-ui/icons/Search')) returns the entire module object,why when I use const Search = React.lazy(() => import('@material-ui/icons/Search')) in webpack bundled project, it works well?It is webpack do the things that attaches default members to Search?

@ygj6
Copy link
Member

ygj6 commented Aug 10, 2021

Because it is a commonJS module, vite will convert it to esm during dependency pre-bundling.
here is the converted code:
image

@SheldonWatson
Copy link
Author

SheldonWatson commented Aug 10, 2021

Because it is a commonJS module, vite will convert it to esm during dependency pre-bundling.
here is the converted code:
image

However, if I dynamic import local files:

const Child =  React.lazy(() => import('./child'))

Uploading image.png…

it can work well,
here is my demo: https://github.com/SheldonWatson/vite-commonjs-isure

@ygj6
Copy link
Member

ygj6 commented Aug 10, 2021

After import('@material-ui/icons/Search') conversion there is a defalut under the default,
here's my printout of the differences between them, which should help you understand:
image

@SheldonWatson
Copy link
Author

SheldonWatson commented Aug 11, 2021

Thx for your so detailed explain!
However, in case of some unexpected error in production environment,I still use webpack to bundle project,
I just use vite in development environment,so your code React.lazy(async () => (await import('@material-ui/icons/Search')).default) works well in Dev environment, but throw this error in Prod environment:
image

I'm really confused about vite's pre-bundling that convert cjs to esm, why cause another default? Or is it webpack does some compatible thing to it?

@hyf0
Copy link
Contributor

hyf0 commented Aug 13, 2021

@ygj6 It looks like an edge case for lazyImport, which is handled properly in static import. I'm working on it.

@ygj6
Copy link
Member

ygj6 commented Aug 14, 2021

Good, I mistakenly thought the problem was caused by esbuild conversion code and I stopped analyzing the problem, fortunately you found the correct cause.

@SheldonWatson
Copy link
Author

SheldonWatson commented Aug 14, 2021 via email

@hyf0
Copy link
Contributor

hyf0 commented Aug 14, 2021

@SheldonWatson It should be the nearest version after #4596 merged. After reading commit history, I think it should be v2.5.0.

@SheldonWatson
Copy link
Author

SheldonWatson commented Aug 14, 2021 via email

@hyf0
Copy link
Contributor

hyf0 commented Aug 14, 2021

@SheldonWatson I haven't met such cases. It will be good to open another issue to track the problem and provide a reproduction example.

@SheldonWatson
Copy link
Author

SheldonWatson commented Aug 16, 2021

@SheldonWatson I haven't met such cases. It will be good to open another issue to track the problem and provide a reproduction example.
@iheyunfei
@ygj6 He know the problem, and I solved it by his plugin @originjs/vite-plugin-commonjs

@SheldonWatson
Copy link
Author

v2.5.0.

Have you fixed it? I update vite to 2.5.0,but it still doesn't work!

@hyf0
Copy link
Contributor

hyf0 commented Aug 16, 2021

@SheldonWatson It's still pending and not merged #4596.

antfu pushed a commit that referenced this issue Aug 16, 2021
* fix(vite): unexptected overwriting for default export fix(#4553)

* feat: add test

* feat: delete unused package
@github-actions github-actions bot locked and limited conversation to collaborators Aug 31, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants