Description
Hey Evan! Thanks for your hard work on ESBuild.
Issue
Framer stumbled upon a case when --entry-names=[name]
generates a file conflict with dynamic imports. Specifically, a code like:
// entry.js
import("date-fns");
import("axios");
with a command like:
yarn esbuild entry.js --outdir=build --bundle --splitting --format=esm --entry-names=[name]
generates the following error:
> error: Two output files share the same path but have different contents: build/index.js
Here’s the repo with the reproduction: https://github.com/iamakulov/esbuild-entrynames-repro
Cause
The error happens because both date-fns
’ and axios
’ main file is called index.js
. ESBuild takes that file name as the entry point name. This causes it to generate two different chunks with an identical name of index
.
The challenge here is that this is a third-party code, and we can’t control how the main file of a specific library is called.
Potential solutions
Here are a couple potential solutions I can think of:
-
Explicitly rename entrypoints with identical names. As in, if there’re two
index
entrypoints, rename them to something else so that names don’t clash.One deterministic way to do this is to include
[dir]
into[name]
when (and only when) there are multiple identical[name]
s. In this case, with the example above, instead of generating twobuild/index.js
chunks and erroring out, ESBuild would generate:build/node_modules-date-fns-index.js build/node_modules-axios-index.js
-
Manage names of
import()
chunks with a different flag. As in, don’t use--entry-names
forimport()
– use--chunk-names
or eg a new--dynamic-import-names
flag instead.It’s not obvious to me why dynamic imports are managed by
--entry-names
(and are considered to be entry points).To me, an entry point is a script that’s inserted straight into the HTML page and starts the app execution. Names of entry points matter because an external system may be inserting an entry point into an HTML response.
Unlike a real entry point, a dynamic import is loaded from ESBuild-generated JS code, not from HTML. Its name doesn’t really matter – ESBuild takes full care of loading that import, and no external system normally deals with that chunk. Pretty much like a regular code-split chunk.