simonw / download-esm

Download ESM modules from npm and jsdelivr
Apache License 2.0
96 stars 4 forks source link

Why not esbuild? #6

Open bakkot opened 1 year ago

bakkot commented 1 year ago

This is a neat tool! But I think you can get everything you want with more standard tools, if I understand this right.

I initially thought the idea was that you wanted to preserve the original source code of your dependencies so you could edit it later if need be. But I see that in fact you're using jsdeliver's +esm mode, which is already running a minifier as well as a tool to convert cjs to esm, which is somewhat fragile but is the only reason this works at all. So you've already given up on keeping the original source code.

If you don't have that constraint, the way a JS developer would solve this problem is by bundling. For example, here's a complete workflow using esbuild:

  1. Install node (which will include npm)
  2. echo '{}' > package.json'
  3. npm install @observablehq/plot
  4. echo 'export * from "@observablehq/plot"' | npx esbuild --bundle --format=esm > observable-plot.js - note that this will download and run esbuild; you can also get the esbuild binary yourself and plop it somewhere on your PATH and drop the npx part
  5. in your script, import * as Plot from "./observable-plot.js"

That will produce a single ES module named observable-plot.js which includes all of your dependencies, and which exports the things that @observablehq/plot does. It will also be a lot more readable than the things you get off of jsdeliver because it's not minified, though if you actually want minification you can pass --minify to esbuild.

This has a few advantages: 1) doesn't rely on jsdelivr and whatever opaque transformations it is doing; 2) produces a single file, which is better for the network and also can be smaller because it can do better dead-code elimination; 3) does not require python.

I know you said you didn't want a build step, but this is a run-once step, exactly the same way that running download-esm would be; you don't need to re-run when making changes. The output is a JS file you can drop on your server, load from your HTML, and code against for as long as you'd like.