从 TypeScript 3.8 版本开始,Typescript 编译器公开了配置,用于控制它如何监视文件和目录。在此版本之前,配置需要使用环境变量,这些变量仍然可用。
背景
编译器的 --watch
实现依赖于 Node 的 fs.watch
和 fs.watchFile
。这两种方法各有优缺点。
fs.watch
依赖于文件系统事件来广播被监视文件和目录的变化。该命令的实现依赖于操作系统,并且不可靠 - 在许多操作系统上,它无法按预期工作。此外,一些操作系统限制了可以同时存在的监视数量(例如,某些版本的 Linux)。在大型代码库中大量使用 fs.watch
有可能超过这些限制,并导致不良行为。然而,由于这种实现依赖于基于事件的模型,因此 CPU 使用率相对较低。编译器通常使用 fs.watch
来监视目录(例如,编译器配置文件包含的源目录和模块解析失败的目录等)。TypeScript 使用这些来增强单个文件监视器中潜在的故障。但是,这种策略有一个关键限制:递归监视目录在 Windows 和 macOS 上受支持,但在 Linux 上不受支持。这表明需要额外的文件和目录监视策略。
fs.watchFile
使用轮询,因此会消耗 CPU 周期。但是,fs.watchFile
是目前最可靠的机制,可用于订阅来自感兴趣文件和目录的事件。在这种策略下,TypeScript 编译器通常使用 fs.watchFile
来监视源文件、配置文件以及根据引用语句似乎丢失的文件。这意味着使用 fs.watchFile
时 CPU 使用率提高的程度直接取决于代码库中监视的文件数量。
使用 tsconfig.json
配置文件监视
建议的配置监视行为的方法是通过 tsconfig.json
中新的 watchOptions
部分。我们在下面提供了一个示例配置。有关可用设置的详细说明,请参阅下一节。
{// 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 的发行说明。
使用环境变量 TSC_WATCHFILE
配置文件监视
选项 | 描述 |
---|---|
PriorityPollingInterval |
使用 fs.watchFile ,但对源文件、配置文件和丢失文件使用不同的轮询间隔 |
DynamicPriorityPolling |
使用动态队列,其中频繁修改的文件以较短的间隔轮询,而未更改的文件以较低的频率轮询 |
UseFsEvents |
使用 fs.watch 。在限制活动监视器数量的操作系统上,如果监视器无法创建,则回退到 fs.watchFile 。 |
UseFsEventsWithFallbackDynamicPolling |
使用 fs.watch 。在限制活动监视器数量的操作系统上,回退到动态轮询队列(如 DynamicPriorityPolling 中所述) |
UseFsEventsOnParentDirectory |
在包含文件的父目录上使用 fs.watch (产生一种折衷方案,导致比纯 fs.watchFile 更低的 CPU 使用率,但可能导致更低的准确性)。 |
默认(未指定值) | 如果环境变量 TSC_NONPOLLING_WATCHER 设置为 true,则使用 UseFsEventsOnParentDirectory 。否则,使用 fs.watchFile 监视文件,其中 250ms 作为任何文件的超时。 |
使用环境变量 TSC_WATCHDIRECTORY
配置目录监视
对于不支持原生递归目录监视的平台(例如非 macOS 和 Windows 操作系统),可以通过使用 TSC_WATCHDIRECTORY
选择的不同选项,为每个子目录递归创建目录监视器来实现支持。
注意:在支持原生递归目录监视的平台上,TSC_WATCHDIRECTORY
的值将被忽略。
选项 | 描述 |
---|---|
RecursiveDirectoryUsingFsWatchFile |
使用 fs.watchFile 监视包含的目录和子目录。 |
RecursiveDirectoryUsingDynamicPriorityPolling |
使用动态轮询队列轮询包含的目录和子目录的更改。 |
默认(未指定值) | 使用 fs.watch 监视包含的目录和子目录。 |