Skip to content

Empty module if dep is not optimized ahead of time #1949

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

Closed
2 of 3 tasks
calebeby opened this issue Feb 9, 2021 · 9 comments
Closed
2 of 3 tasks

Empty module if dep is not optimized ahead of time #1949

calebeby opened this issue Feb 9, 2021 · 9 comments

Comments

@calebeby
Copy link
Contributor

calebeby commented Feb 9, 2021

  • Read the docs.
  • Use Vite >=2.0. (1.x is no longer supported)
  • If the issue is related to 1.x -> 2.0 upgrade: no

Describe the bug

This is somewhere between a bug and a feature request/question:

I have a use case where I am using Vite via createServer, and the files that will be bundled are not known ahead of time (so the dependency pre-bundling won't/can't work).

Here's what I expect to happen:

  1. Start Vite server. It sees nothing to pre-bundle
  2. I ask Vite to transpile a file with any import to node_modules:
    import $ from 'jquery'
    console.log($)
  3. Vite sees that there is a non-pre-bundled import, and triggers a pre-bundle, in the meantime it should either respond with the transpiled file, or wait until the pre-bundle finishes before responding (I don't know if the ?v= param depends on the pre-bundle already existing
    Something like:
    import __vite__cjsImport0_jquery from "/node_modules/.vite/jquery.js?v=1d07b389"
    const $ = __vite__cjsImport0_jquery.__esModule ? __vite__cjsImport0_jquery.default : __vite__cjsImport0_jquery
    
    console.log('here is jquery:', $)
  4. Then I fetch the module /node_modules/.vite/jquery.js?v=1d07b389 and once Vite finishes bundling it Vite responds with it

Here's what currently happens:

On step 3 Vite responds with:

import $ from '/node_modules/jquery/dist/jquery.js'

console.log('here is jquery:', $)

And when I fetch /node_modules/jquery/dist/jquery.js Vite responds with an empty file and without a content-type so the module can't be executed.

Reproduction

You can see the bug here: https://github.com/calebeby/vite-bug

  1. npm i
  2. Clear node_modules/.vite if you ran it previously
  3. npm run dev
  4. Open a browser tab to http://localhost:3000/main.js (only to avoid CORS errors)
  5. In the browser console paste await import('http://localhost:3000/main.js')
  6. Problem: response for imported jquery is empty and doesn't have a content type

There is code in place that triggers a full-reload when a missing pre-bundled dep gets bundled, but what I am not understanding is why vite doesn't just wait to respond until the pre-bundled dep gets pre-bundled. I think WMR's npm middleware handles it closer to the way I expect

@yyx990803
Copy link
Member

yyx990803 commented Feb 9, 2021

This is expected, because a new found import may have cross-imports with other existing deps, which can lead to invalidations of other pending or already imported imports. i.e. a new import doesn't necessarily only affect that import itself. To ensure correctness it is necessary to perform a full reload.

@calebeby
Copy link
Contributor Author

calebeby commented Feb 9, 2021

@yyx990803 Is there any way for me to workaround for my use case, where a reload is not possible? I am using vite to transpile modules for a puppeteer-based test runner, and if the browser reloaded in the middle of the test all of the state would get lost and the test would fail.

@yyx990803
Copy link
Member

But this should only happen if you are editing the files? Are you editing source files during the tests?

@calebeby
Copy link
Contributor Author

calebeby commented Feb 9, 2021

The files that are run in the browser are virtual files that are given to vite via a rollup plugin

So vite's crawler can't find the deps to pre-bundle them ahead of time

@calebeby
Copy link
Contributor Author

calebeby commented Feb 9, 2021

Is there a way at runtime for me to tell Vite to walk a module graph and perform dep optimization? Sort of like adding entries to library mode at runtime?

Also, does the dep optimizer run rollup plugins for resolution/loading/transpiling when it figures out the module graph?

@yyx990803
Copy link
Member

Well, adding entries at runtime leads to a re-bundle and requires a reload. So I'm afraid you'll have to rethink your use case.

@calebeby
Copy link
Contributor Author

calebeby commented Feb 9, 2021

I have a few more questions, sorry 🙈

  • Is it possible to disable pre-bundling for ESM node_modules?
  • Is there a way from the API to detect when Vite found a missing dep and performed re-dep-optimizing?
  • If I restart vite does it keep previously optimized deps in the cache when it rebuilds the deps, even if the new entry no longer points to the previously optimized deps?

I think I am able to make my use case work if the first one is true, or if both the second and third are true

@yyx990803
Copy link
Member

Is it possible to disable pre-bundling for ESM node_modules?

If the dep provides pure ESM you can list it in https://vitejs.dev/config/#optimizedeps-exclude

Is there a way from the API to detect when Vite found a missing dep and performed re-dep-optimizing?

No.

If I restart vite does it keep previously optimized deps in the cache when it rebuilds the deps, even if the new entry no longer points to the previously optimized deps?

Yes it keeps previously found imports as long as the lockfile + vite config didn't change.

@calebeby
Copy link
Contributor Author

calebeby commented Feb 9, 2021

👍 I am planning to make it restart the test when Vite performs just-in-time-pre-bundling. Would you accept a PR to expose events to the API that trigger at the same time as these logs?

new dependencies found: ${...}, updating...
✨ dependencies updated, reloading page...

@github-actions github-actions bot locked and limited conversation to collaborators Jul 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants