监听模式(nub watch)运行你的入口点并在它实际依赖的任何内容发生变化时重启。底层引擎是 Node 自身的 --watch(以 --watch-preserve-output 运行),加上 Nub 侧的粘合层,将内存中转译的依赖图——加上仍然会使进程失效的非图内文件——报告回 Node 的监听器。结果是一个对 TypeScript 项目直接可用的监听器,无需维护 glob 列表。

本页是使用手册。关于 nub 首先如何运行文件,参见运行文件;关于脚本,参见运行脚本

监听并重启文件

监听器接受一个文件,而非脚本名。将 nub watch 指向一个入口文件——例如你的 dev 脚本运行的那个。它运行文件,然后在文件或其解析的导入图中的任何内容变化时重启进程。

nub watch src/server.ts

TypeScript、JSX、.env* 加载、tsconfig.json 路径——nub <file> 给你的一切在这里也激活,因为 nub watch 底下运行的是相同的增强 Node。

脚本名之后的 --watch 像其他参数一样转发给脚本——nub run test --watch 运行你测试工具自身的监听模式,不会调用 Nub 的监听器。参见 nub run → 转发参数

--watch

标志和子命令是别名:nub --watch <file> 调度到与 nub watch <file> 完全相同的代码路径——相同的默认值、相同的行为。标志形式的存在使 node --watch script.ts 的肌肉记忆无缝进入 Nub 改进的体验。

nub --watch src/server.ts

保留输出

Nub 在重启间保留终端输出而非清屏,所以上一次运行的错误消息保持可见。它以 --watch-preserve-output 运行 Node 的监听器,所以重启打印 Node 自身的状态行而非擦除终端:

$ nub watch src/server.ts
Completed running 'src/server.ts'. Waiting for file changes before restarting...
Restarting 'src/server.ts'

什么触发重启

监听集是加载器插装的,而非基于 glob 的:nub watch 只监听作为运行一部分实际加载的文件,加上一小组变化时会使进程失效的非图内文件。具体来说,以下变化会触发重启:

  • 入口的解析依赖图中的任何文件——包括通过 module.registerHooks() 在内存中转译、Node 从未在磁盘上看到的 .ts / .tsx 文件。
  • 你的 .env* 文件,按正常优先级(.env.env.local.env.[mode]、…)——这些在启动时读取一次,不在任何导入图中,所以 Nub 将它们显式报告给监听器。
  • tsconfig.json extends 链——编辑 tsconfig(例如更改 paths 映射)会重启进程,即使 tsconfig 不被任何东西导入。
  • package.json

这就是为什么原生 node --watch 在 tsconfig 编辑时悄悄过期,以及为什么 Nub 通过 Node 内部的 WATCH_REPORT_DEPENDENCIES 通道报告这些非图内文件。

什么不触发重启

因为监听集是导入图而非目录 glob,运行中实际不加载的文件根本不被监听。发出 dist/foo.js 的重新构建不会触发重启,除非运行中的某物导入了 dist/foo.js

nub watch src/server.ts
# 编辑 dist/** 或 coverage/** 不会重启——
# 它们不在已加载的依赖图中

无需维护忽略列表。基于 glob 的监听器需要的大部分 ignore / 重启循环防护维护在加载器插装模型中是不必要的。

原生 Node --watch

Nub 的监听模式刻意不是逐字节的 Node——它添加了上述的横幅、保留输出默认值和非图内报告。当你想要完全没有 Nub 侧粘合层的原生 Node --watch 时,在你的 shell 中直接输入 node --watch

node --watch script.js

Nub 的 PATH 垫片是每次调用独立的:它只影响活跃 nub ... 调用的后代,所以你 shell 中的 node 始终是你的真实 Node。对于严格 Node 监听行为,这就是路径。

相关

  • 运行文件nub <file> 如何执行 TypeScript 和 JSX。
  • 运行脚本nub run 及其工作区功能。
  • nubx — 从 node_modules/.bin 运行本地 CLI。
  • FAQ — 整个面的简短回答。