FR: Walk directories in leaf -> root order
- Dominant language
- Go
- Stars
- 40.1k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
During the build process, esbuild walks the directory hierarchy, looking for `package.json` files along the way (in [resolver.go]). For reasons explained below, there are two problems with the current arrangement:
1. **The traversal happens in root -> leaf order.** If it's being run in `/Volumes/src/my-project/my-package`, then it'll read:
1. `/package.json` (if it exists)
2. `/Volumes/package.json` (if it exists)
3. `/Volumes/src/package.json` (if it exists)
4. `/Volumes/src/my-project/package.json` (if it exists)
5. `/Volumes/src/my-project/my-package/package.json` (if it exists)
2. **There's no way to stop the traversal.** Other projects provide a way to designate a known "root", to prevent higher traversal.
- ESLint, for example, provides a `root: true` [configuration option][root: true]
This setup creates a problem for us. Our project exists within a monorepo, and we're building with [BuildXL]. We're working to enable the `enforceSourceReadsUnderPackageRoots` [configuration option][source-reads] build flag, which prevents processes from reading outside of their declared dependency tree.
## Proposal
The proposal is to invert the logic: read from the leaf down. Along the way, the process could be aborted with a similar mechanism to indicate "this is the root, please stop traversing" to ESLint.
This pattern has other precedence in configuration of other projects in the JS ecosystem.
## Workarounds
Our current workaround is to add our top-level `package.json` to the allow-list of files which can be read outside of the declared dependencies. This is suboptimal, since it opens up the window for _other_ processes to read the file when they shouldn't.
[resolver.go]:
https://github.com/evanw/esbuild/blob/df815ac27b84f8b34374c9182a93c94718f8a630/internal/resolver/resolver.go#L1585-L1596
[root: true]:
https://archive.eslint.org/docs/7.0.0/user-guide/configuring#:~:text=ESLint%20will%20stop%20looking%20in%20parent%20folders%20once%20it%20finds%20a%20configuration%20with%20%22root%22%3A%20true.
[buildxl]:
https://github.com/microsoft/BuildXL
[source-reads]:
https://github.com/microsoft/BuildXL/blob/main/Documentation/Wiki/Frontends/js-misc-options.md#enforcesourcereadsunderpackageroots-boolean
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the directory traversal in internal/resolver/resolver.go at the linked lines, then review how package.json files are discovered during resolution. The change is complete when traversal proceeds from the leaf toward the root and provides a way to stop at a designated project root; add or update coverage for both behaviors if the resolver has corresponding tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, javascript
- Domain
- build-system, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100