Skip to content

Improve typescript compiler API documentation with respect to overriding the host's watchFile and watchDirectory #46725

@insidewhy

Description

@insidewhy

Suggestion

It would be nice to document how to use the compiler API to build an incremental watching compiler using custom file and directory watching behavior. The documentation shows how to build an incremental watching compiler using tsc's standard file watching behavior which supports tsconfig.tsbuildinfo. It then provides a second example of how to build a compiler with custom watch behavior, but that does not support tsconfig.tsbuildinfo. It is hard to reconcile both of these examples to get a typescript compiler that works the same as tsc --watch in every way but uses custom file watching code.

🔍 Search Terms

  • compiler api
  • watch
  • documentation

✅ Viability Checklist

My suggestion meets these guidelines:

  • [-] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [-] This wouldn't change the runtime behavior of existing JavaScript code
  • [-] This could be implemented without emitting different JS based on the types of the expressions
  • [-] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • [-] This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

Currently the documentation at https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API for "Writing an incremental program watcher" shows how to create an incremental compiler that watches the filesystem using typescript's default file watching functionality.

It is currently possible to override the host methods watchFile and watchDirectory in order to provide custom file and directory watching behaviour.

My team used this to build a compiler that uses watchman, it supports file changes and deletions. We do this by overriding the watchFile host method and adding the callbacks passed to this method to a Map<string, FileWatcherCallback>. When we detect a file change we access theFileWatcherCallback from the map and call it with FileWatcherEventKind.Deleted or FileWatcherEventKind.Changed as necessary. This works great. When a new file is created we have no entry in the map since, of course, the typescript compiler would not request to watch a file it never knew existed in the first place. So we tried passing the path of the file to the respective directory watcher (which we add to a Map<string, ts.DirectoryWatcherCallback> when it is supplied by the watchDirectory callback) but this does nothing. We have a compiler that seems to do everything we want but cannot respond to newly added source files.

It would be great to document how to override these methods so that we can build our own watching compiler with watchman and so that others who want to use different watch methods are able to understand how to do this.

Our attempt can be found at https://github.com/insidewhy/tsc-watchman/blob/main/src/index.ts

📃 Motivating Example

This would allow us to avoid the built-in polling based watcher and use something more efficient such as watchman to watch our files and directories.

💻 Use Cases

This would be especially useful for projects already using watchman, since its client-server architecture would allow typescript to hook into the watches that have already been set up by other processes that are already watching the same directory structure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureDocsThe issue relates to how you learn TypeScriptSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions