Skip to content

Conversation

@lbsal
Copy link

@lbsal lbsal commented Apr 14, 2025

edit (2025-05-26):

For what it's worth:

We've forked this at https://github.com/masslbs/deno-vite-plugin and published the fork so that it can be used by ci: https://www.npmjs.com/package/@masslbs/deno-vite-plugin

Info from the fork's README:

Care has been taken to avoid introducing changes in the final output arrived at by running this version of deno-vite-plugin compared to the upstream version. The result of this fork is that it uses a bounded amount of memory and its execution time is faster after a first run has populated the cache.

This fork:

  • uses a lock to limit external calls to deno info --json
  • improves how the in-memory cache is used by catching more cases
  • implements an on-disk cache, speeding up initial loading considerably

The on-disk cache is only written after a clean exit from vite, or when the server restarts as that is when Rollup's buildEnd phase runs.

Prevent the on-disk cache from being used by setting the environment variable NOCACHE e.g. NOCACHE="1" deno run dev. This can be helpful if debugging any build errors that may/may not have to do with caching.

Logging what the plugin is doing at any point in time can be enabled by providing DEBUG=deno-vite-plugin or DEBUG=*.


This fix builds on the insight in #55 but does so by performing the minimal change required to fix the underlying issue. The reason for this departure from #55 is due to our project's build failing when executed using the proof of concept's plugin, presumably due to some unknown change introduced on part of the proof of concept's extensive revision.

The fix reuses @notcome's lock component and threads said lock through the codebase to ultimately place it around the deno info --json ${id} calls.

When building our project using this patch of the plugin, my CPU utilization never goes about ~30% and the memory usage stays more or less constant. This is compare to before, where CPU utilization hit 100% and I ran out of memory and my system froze.

Fixes #50 and closes masslbs/Tennessine#330


For reviewers:

  • I license the changes I've introduced under the same license as deno-vite-plugin itself i.e. MIT; @notcome could you let me know whether you license my usage of your Lock class under MIT as well?
  • I'm open to introducing a semaphore to allow for a configurable degree of parallelism. In that case I would import https://www.npmjs.com/package/async-mutex and use its semaphore implementation.

This fix builds on the insight in denoland#55 but does so by performing the
minimal change required to fix the underlying issue. The reason for this
departure from denoland#55 is due to our project's build failing when executed
using the proof of concept's plugin, presumably due to some unknown
change introduced on part of the proof of concept's extensive revision.

The fix reuses @notcome's lock component and threads said lock through
the codebase to ultimately place it around the `deno info --json ${id}`
calls.
@lbsal
Copy link
Author

lbsal commented Apr 22, 2025

ping @marvinhagemeister: any thoughts on this fix for the plugin to enable its use by bounding the concurrency of deno info calls without eating all RAM on machines with ~16GB & less?

Happy to iterate and make changes!

Copy link
Collaborator

@marvinhagemeister marvinhagemeister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for adding this

@marvinhagemeister
Copy link
Collaborator

Looks like CI is stuck. Can you rebase against main?

@swcarter007
Copy link
Contributor

Any updates on this PR. It seems like its been sitting out here for a couple of months. Does something else need to be done with it?

@notcome
Copy link

notcome commented Sep 29, 2025

Hey, missed this for a while, but sure on MIT part. That lock code is basically generated by o3.

That being said, I am no longer sure if this would be the best practice now. Our team have worked internally on an entirely new approach. Basically, we don't need deno info at all:

  • For NPM packages, vite can handle them on its own, as long as nodeModulesDir is set to auto.
  • For JSR packages, it is much easier to just turn on vendor. The folder structure is very clean.
  • For generic import maps, and peer packages in workspace, it is not very hard to resolve them manually.

Consequently, we opt to enable vendor: true, and parse deno.json on our own. Zero external call to deno info is needed.

Right now this plugin is dedicated to workspace + vendor: true, and it is inlined in our monorepo. I would hope to test it as an independent JSR package and open source them soon. Stay tuned!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vite build causes OOMs due to spawning deno info with unbounded concurrency. Get a handle on vite+deno memory overhead

4 participants