evanw / evanw/esbuild

Expose details of module resolution

Open
#555 2 comments 1 reaction 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.