evanw / evanw/esbuild

Glob-style require doesn't resolve extension correctly

Open
#3,328 1 comment 11 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
40.1k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

Thanks for building the glob require feature, it's much appreciated! I noticed a small bug i'd like to share.

For `require("./chunks/" + id)` where `id` is a module name without extension, esbuild produces a bundle that results in `Module not found in bundle: ./chunks/abcde`. Here's a code example: [ESBuild Playground](https://esbuild.github.io/try/#YgAwLjE5LjIALS1idW5kbGUAZQBlbnRyeS5qcwBjb25zdCBfX3dlYnBhY2tfcmVxdWlyZV9fID0gewogIHUoY2h1bmtJZCkgewogICAgcmV0dXJuIHsgNDI6ICJhYmNkZSIgfVtjaHVua0lkXQogIH0KfQoKZnVuY3Rpb24gcnVuRW50cnlQb2ludChjaHVua0lkKSB7CiAgcmVxdWlyZSgiLi9jaHVua3MvIiArIF9fd2VicGFja19yZXF1aXJlX18udShjaHVua0lkKSkKfQoKcnVuRW50cnlQb2ludCg0MikAAGNodW5rcy9hYmNkZS5qcwBjb25zb2xlLmxvZygiSGVsbG8gV29ybGQhIikKbW9kdWxlLmV4cG9ydHMgPSA0Mg
).

Without bundling, Node resolves this correctly, and it's a pattern Webpack likes to emit - so I'd consider it a bug within esbuild.

I believe the cause is that the `__glob` snippet generated by esbuild doesn't correctly mimic Node's resolution strategy. Here's a sketch of how it might be fixed:

```diff
var __glob = (map) => (path) => {
- var fn = map[path];
+ var fn = map[path] ?? map[path + '.js'] ?? map[path + '/index.js'];
if (fn)
return fn();
throw new Error("Module not found in bundle: " + path);
};
```

[Node's full resolution strategy](https://nodejs.org/api/modules.html#all-together) is a little more nuanced, but i'm sure there's a tradeoff to be made here between simplicity and spec-completeness :)

I'd be open to contribute a fix for the issue, please let me know if you're interested in that.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the linked esbuild Playground and inspect the generated __glob helper and glob-style require handling. Verify extensionless ./chunks/abcde resolution against the reported case; done means the bundled output loads chunks/abcde.js instead of throwing.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, javascript
Domain
build-system, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.