Esbuild: custom paths for entrypoints, chunks, and assets in outdir

Created on 5 Jul 2020  ยท  9Comments  ยท  Source: evanw/esbuild

I have been unable to build my project with esbuild because the structure of the output directory is not customizable. For example, esbuild fails for multiple entrypoints with the same basename, such as src/a/page.tsx and src/b/page.tsx, because esbuild wants to output both to <outdir>/page.js. Rollup's input, entryFileNames, chunkFileNames, and assetFileNames options give users a good deal of control over where output files are placed. Would you consider similar features for esbuild?

Perhaps something like this...

esbuild --outdir=dist --entryFileNames="pages/[name].js" "pageA=src/a/page.tsx" "pageB=src/b/page.tsx"

...which would output dist/pages/pageA.js and dist/pages/pageB.js.

Below are links to Rollup's documentation for the relevant options:

http://rollupjs.org/guide/en/#input
http://rollupjs.org/guide/en/#outputentryfilenames
http://rollupjs.org/guide/en/#outputchunkfilenames
http://rollupjs.org/guide/en/#outputassetfilenames

Most helpful comment

@evanw thought you may like to know that I finished migrating my build scripts over from Rollup to esbuild (I had to code my own functions for things like clearing dist folder, copying files, etc but this is trivial in node.js). Here is the build log now:

โœ” Cleared target folder (1083 ms)
โœ” Copied dist files (8 ms)
โœ” Built Phaser 4 v0.1.9 - 1151 modules (21 ms)
โœ” TypeScript defs complete (10615 ms)
โœ” Build complete in 11.733 secs

Just to be clear, it used to take Rollup _over 6 minutes_ to do the exact same thing. The esbuild portion of this log is just 21 ms for, currently, 1,151 entry points.

Lovely :)

All 9 comments

Just adding my support for having this feature.

I, too, cannot do a full build because the entry files are all lumped in the outdir together, so lots of them overwrite each other.

I don't mind, because I can still do a full release build with Rollup and use esbuild for all my testing, but it would be great to have this feature.

Spent a good while today playing with the esbuild JS API, hoping to maybe emulate this feature via Transform, but I just don't think it's possible.

I don't need to be able to configure the output chunks, I just need them to mirror the structure of the input entry files.

Fingers crossed this lands in a forth-coming release :)

_(Merging in from #244)_

Problem

Given the following file structure:

.
โ”œโ”€โ”€ a
โ”‚   โ””โ”€โ”€ index.js
โ””โ”€โ”€ b
    โ””โ”€โ”€ index.js

If you run:

esbuild --bundle --outdir=dist --format=esm a/index.js b/index.js

You get the following error:

error: Two output files share the same path: dist/index.js

Possible Solution

I think I'd expect the bundle output to look like this:

โ”œโ”€โ”€ a
โ”‚   โ””โ”€โ”€ index.js
โ””โ”€โ”€ b
    โ””โ”€โ”€ index.js

So it seems like there'd need to be a base directory (defaulting to working directory) so you could do:

const rel = path.relative(basedir, entry)
const outpath = path.join(outdir, rel)

I'd suggest steering this discussion to the minimal changes required to solve this problem. I agree that customizing the names of chunks, assets, and entrypoints is nice to have (I use these features in rollup too), but even without any of those options, rollup and tsc handle the issue of two entrypoints in different directories with the same name.

Just did a survey of different tools to see what they do.

It looks like Parcel and tsc avoid collisions by generating nested folders (so dist/a/index.js and dist/b/index.js). That approach will work for esbuild.

Rollup avoids collisions by adding a number after the file (so dist/index.js and dist/index2.js) but I don't want to use that solution for esbuild because it seems error-prone. The meaning of the path dist/index.js could unexpectedly change if one of the entry points is later removed such that there is no longer a collision.

This should be fixed as of version 0.6.0.

Superb, thank you! I will test this on my codebase on Monday and open an issue if I find any. It should be a good test, as there are over 1200 entry points for the API (which is why I'm desperate to move away from Rollup as it takes over 6mins for a full build)

Works beautifully. Thanks Evan!

Entrypoints

- views/users/edit.js      => dist/users/edit.js
- views/posts/index.js     => dist/posts/index.js
- views/posts/show.js      => dist/posts/show.js
- views/posts/new.js       => dist/posts/new.js
- views/posts/edit.js      => dist/posts/edit.js
- views/layouts/default.js => dist/layouts/default.js
- views/users/index.js     => dist/users/index.js
- views/users/show.js      => dist/users/show.js
- views/users/new.js       => dist/users/new.js

Additional Chunks

- dist/chunk.mivFoCKm.js
- dist/chunk.-3gnZy6S.js
- dist/chunk._Q398Reo.js
- dist/chunk.ryjutOKl.js
- dist/chunk.nkB2WGXm.js
- dist/chunk.a4CBmrWb.js

Superb, thank you! I will test this on my codebase on Monday and open an issue if I find any. It should be a good test, as there are over 1200 entry points for the API (which is why I'm desperate to move away from Rollup as it takes over 6mins for a full build)

How long does it take now? Just curious.

Works beautifully. Thanks Evan!

Thanks for reporting back. That's great to hear!

@evanw thought you may like to know that I finished migrating my build scripts over from Rollup to esbuild (I had to code my own functions for things like clearing dist folder, copying files, etc but this is trivial in node.js). Here is the build log now:

โœ” Cleared target folder (1083 ms)
โœ” Copied dist files (8 ms)
โœ” Built Phaser 4 v0.1.9 - 1151 modules (21 ms)
โœ” TypeScript defs complete (10615 ms)
โœ” Build complete in 11.733 secs

Just to be clear, it used to take Rollup _over 6 minutes_ to do the exact same thing. The esbuild portion of this log is just 21 ms for, currently, 1,151 entry points.

Lovely :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aelbore picture aelbore  ยท  3Comments

qnp picture qnp  ยท  4Comments

mohsen1 picture mohsen1  ยท  3Comments

Gotterbild picture Gotterbild  ยท  3Comments

ayox picture ayox  ยท  4Comments