Expose details of module resolution
- Dominant language
- Go
- Stars
- 40.1k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
Now that `incremental` mode landed, I'm interested in implementing a sort of hybrid of `nodemon` and `esbuild`. I've hacked together [an MVP](https://gist.github.com/ggoodman/879eba4bac7b9c88bb67f0b8095bef4f) that works very well for my use case.
However, it occurs to me that to generalize the solution, it would be important to be able to introspect which files are relevant to a given build. While we already have all the info about source files, two groups of files would be helpful to also see:
1. `package.json` files consulted in performing resolutions. Changes to these may invalidate parts of the build so an intelligent watcher would observe these for changes. Of course, a 100% bullet-proof solution would also need to observe certain directories where the absence of files with certain patterns like `node_modules/` or `package.json` might also invalidate resolutions that traversed up the filesystem.
2. `tsconfig.json` files consulted in performing resolutions and in configuring build settings. Similarly to the former, a watching process would want to watch the correct set of these to re-trigger incremental builds.
### General solution idea
I've built a (much less ambitious or complete) bundler called [Velcro](https://github.com/ggoodman/velcro) that was designed to run as a service and to run in various js environments. Part of the design of Velcro involved defining a minimal set of operations that can define a [module resolution interface](https://github.com/ggoodman/velcro/blob/e53dd3e42b91cc016d81d3abb97474fd54223251/packages/%40velcro/resolver/src/strategy.ts#L7-L111) across different conceptual stores (memory, fs, cdn like unpkg or even a collection of monaco-editor `Model`s). Since reads to these could be potentially expensive, the idea was to think about caching and invalidation from the beginning.
To address this, the [Velcro Resolver](https://github.com/ggoodman/velcro/blob/e53dd3e42b91cc016d81d3abb97474fd54223251/packages/%40velcro/resolver/src/resolver.ts#L5-L144) tracks a collection of path / access types that would invalidate the outcome of any of the cached operations. For example, if the resolver checks for the existence of `file.ts` before finding `file.js` via the default extensions setting, the creation of `file.ts` would invalidate that resolution.
Consumers of the Resolver, such as the Bundler receive the invalidation records for each operation and can remember these. When an event occurs that may invalidate something, all of the invalidations are pre-calculated. We just need to loop through what we have already tracked and delete records as well as tell the Resolver to delete its own: [like this](https://github.com/ggoodman/velcro/blob/e53dd3e42b91cc016d81d3abb97474fd54223251/packages/%40velcro/bundler/src/graph/graphBuilder.ts#L339-L362).
Anyway, all this to say that it would be interesting to think of how consumers of `esbuild` might be able to obtain some visibility into these resolution details so that they can be intelligent about when they trigger rebuilds. In general a naive watch pattern will work well enough but as soon as we get into weird directory structures and inter-linking `tsconfig.json` files, having this metadata would be almost essential.
Contributor guide
No contributing guide indexed for this repository
Research direction
No esbuild files or tests are named. Start by reviewing the existing incremental-build and module-resolution entry points, then compare the requested package.json and tsconfig.json visibility with the linked Velcro resolver design. Done would require a decided API and tests covering the resolution metadata and invalidation behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, javascript, typescript
- Domain
- build-system, compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100