esbuild icon indicating copy to clipboard operation
esbuild copied to clipboard

Getting Bundled node_modules Separately from Source

Open mildaniel opened this issue 3 years ago • 2 comments

Hi @evanw,

Our use case is a little different from the typical front-end use cases in that we want to use esbuild to build and package JS and TS to be used in something like AWS Lambda. We want the source code to be in a single bundle and all external dependencies still bundled and minified but in a separate file. Is there any way to currently do this using esbuild?

mildaniel avatar Jun 15 '22 22:06 mildaniel

You're correct that this is not something esbuild does. You could probably figure out something with the plugin API: https://esbuild.github.io/plugins/. I'm imagining something like this:

  1. Bundle your code once with a plugin that records dependencies, and throw the bundle away
  2. Bundle once with a generated entry point that just imports and re-exports all dependencies from step 1
  3. Bundle your code once with a plugin that substitutes each dependency with a stub that imports the dependency from the file in step 2

For correctness you may need the dependencies in the bundle in step 2 to be lazily-initialized (if they have side effects and/or are supposed to only be conditionally imported). You could do that by e.g. re-exporting them as a function that calls require() instead of re-exporting the result of the require() call directly.

evanw avatar Jun 16 '22 00:06 evanw

Here's a dead-simple example of doing manual chunks (#207) by yourself: esbuild-split-vendors-example

It doesn't include some more complex logic like

  1. Scan deps. Most of the time pkg.dependencies is what we want. It can be fixed by doing bundle once like evan said, which is easy.

  2. Lazily-initialized modules. It can be fixed with:

    Object.defineProperty(__vendors__, "mod", {
      get: () => require("mod"),
      enumerable: true
    })
    // instead of
    // __vendors__.mod = require("mod")
    

hyrious avatar Jun 16 '22 01:06 hyrious

Closing because this was answered.

evanw avatar Sep 12 '22 01:09 evanw