从 TypeScript 3.8 版本开始,TypeScript 编译器提供了可以控制如何监视文件和目录的配置。在此版本之前,配置需要使用环境变量,这些变量仍然可用。
🌐 As of TypeScript 3.8 and onward, the Typescript compiler exposes configuration which controls how it watches files and directories. Prior to this version, configuration required the use of environment variables which are still available.
背景
🌐 Background
编译器的 --watch 实现依赖于 Node 的 fs.watch 和 fs.watchFile。每种方法都有其优缺点。
🌐 The --watch implementation of the compiler relies on Node’s fs.watch and fs.watchFile. Each of these methods has pros and cons.
fs.watch relies on file system events to broadcast changes in the watched files and directories. The implementation of this command is OS dependent and unreliable - 在许多操作系统上,它的表现并不如预期。此外,一些操作系统限制了可以同时存在的监视器数量(例如某些版本的Linux)。在大型代码库中大量使用 fs.watch 可能会超过这些限制,并导致不良行为。然而,由于该实现依赖于基于事件的模型,CPU 使用相对较低。编译器通常使用 fs.watch 来监视目录(例如编译器配置文件中包含的源目录以及模块解析失败的目录等)。TypeScript 使用这些监视来增强对单个文件监视器可能失败的情况的处理。然而,这种策略有一个关键限制:在 Windows 和 macOS 上支持递归监视目录,但在 Linux 上不支持。这表明需要为文件和目录监视制定额外的策略。
fs.watchFile 使用轮询,因此会消耗 CPU 周期。然而,fs.watchFile 无疑是订阅感兴趣的文件和目录事件最可靠的机制。在这种策略下,TypeScript 编译器通常使用 fs.watchFile 来监视源文件、配置文件以及根据引用语句可能丢失的文件。这意味着使用 fs.watchFile 时 CPU 使用率的增加程度直接取决于代码库中被监视的文件数量。
使用 tsconfig.json 配置文件监控
🌐 Configuring file watching using a tsconfig.json
建议通过 tsconfig.json 的新 watchOptions 部分来配置 watch 行为。我们在下面提供了一个示例配置。有关可用设置的详细说明,请参见以下部分。
🌐 The suggested method of configuring watch behavior is through the new watchOptions section of tsconfig.json. We provide an example configuration below. See the following section for detailed descriptions of the settings available.
{// Some typical compiler options"": {"": "es2020","": "node"// ...},// NEW: Options for file/directory watching"watchOptions": {// Use native file system events for files and directories"": "useFsEvents","": "useFsEvents",// Poll files for updates more frequently// when they're updated a lot."": "dynamicPriority",// Don't coalesce watch notification"": true,// Finally, two additional settings for reducing the amount of possible// files to track work from these directories"": ["**/node_modules", "_build"],"": ["build/fileWhichChangesOften.ts"]}}
欲了解更多详情,请参阅 Typescript 3.8 的发行说明。
🌐 For further details, see the release notes for Typescript 3.8.
使用环境变量 TSC_WATCHFILE 配置文件监控
🌐 Configuring file watching using environment variable TSC_WATCHFILE
| Option | Description |
|---|---|
PriorityPollingInterval |
Use fs.watchFile, but use different polling intervals for source files, config files and missing files |
DynamicPriorityPolling |
Use a dynamic queue where frequently modified files are polled at shorter intervals, and unchanged files are polled less frequently |
UseFsEvents |
Use fs.watch. On operating systems that limit the number of active watches, fall back to fs.watchFile when a watcher fails to be created. |
UseFsEventsWithFallbackDynamicPolling |
Use fs.watch. On operating systems that limit the number of active watches, fall back to dynamic polling queues (as explained in DynamicPriorityPolling) |
UseFsEventsOnParentDirectory |
Use fs.watch on the parent directories of included files (yielding a compromise that results in lower CPU usage than pure fs.watchFile but potentially lower accuracy). |
| default (no value specified) | If environment variable TSC_NONPOLLING_WATCHER is set to true, use UseFsEventsOnParentDirectory. Otherwise, watch files using fs.watchFile with 250ms as the timeout for any file. |
使用环境变量 TSC_WATCHDIRECTORY 配置目录监控
🌐 Configuring directory watching using environment variable TSC_WATCHDIRECTORY
对于不原生支持递归目录监视的平台(即非 macOS 和 Windows 操作系统),可以通过使用 TSC_WATCHDIRECTORY 选择的不同选项,为每个子目录递归创建目录监视器来实现支持。
🌐 For directory watches on platforms which don’t natively allow recursive directory watching (i.e. non macOS and Windows operating systems) is supported through recursively creating directory watchers for each child directory using different options selected by TSC_WATCHDIRECTORY.
注意: 在支持本地递归目录监控的平台上,TSC_WATCHDIRECTORY 的值将被忽略。
| 选项 | 描述 |
|---|---|
RecursiveDirectoryUsingFsWatchFile |
使用 fs.watchFile 来监视包含的目录及其子目录。 |
RecursiveDirectoryUsingDynamicPriorityPolling |
使用动态轮询队列来轮询包含的目录及其子目录的更改。 |
| default (未指定值) | 使用 fs.watch 来监视包含的目录及其子目录。 |