Skip to content

--entry-names=[name] errors out for some dynamic imports #1056

Closed
@iamakulov

Description

@iamakulov

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:

  1. 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 two build/index.js chunks and erroring out, ESBuild would generate:

    build/node_modules-date-fns-index.js 
    build/node_modules-axios-index.js
    
  2. Manage names of import() chunks with a different flag. As in, don’t use --entry-names for import() – 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions