You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测tsc --watch模式下多项目首次构建完成时机?

解决方案

不用关--watch模式就能拿到首次构建完成的时机,直接用下面的方法就行:

方案1:抓tsc watch的输出日志当触发信号

tsc --watch每次编译走完(包括第一次编译)都会往标准输出打固定内容的日志,首次编译成功的日志格式如下:

[HH:MM:SS] Found 0 errors. Watching for file changes.

后台启动Tokens和ModulesCollection的构建进程时,监听它们的输出,匹配到对应日志就给对应项目打完成标记,等两个项目的标记都齐了,再启动Lexer的watch构建即可。
下面是不需要额外装依赖的bash脚本,可直接使用:

#!/bin/bash
set -e

BASE_DIR="UAA_Generators/JapaneseSyntax/ByNodeJS"
TOKENS_DIR="$BASE_DIR/DataStructures/Tokens"
MODULES_DIR="$BASE_DIR/DataStructures/ModulesCollection"
LEXER_DIR="$BASE_DIR/Actuators/Lexer"

tokens_done=0
modules_done=0

# 后台启动Tokens构建,监听首次完成信号
(
  cd "$TOKENS_DIR" || exit 1
  npm run "Incremental building" 2>&1 | while read -r line; do
    echo "[Tokens] $line"
    if [[ $line == *"Watching for file changes."* && $tokens_done -eq 0 ]]; then
      tokens_done=1
      touch /tmp/tokens_build_done
    fi
  done
) &

# 后台启动ModulesCollection构建,监听首次完成信号
(
  cd "$MODULES_DIR" || exit 1
  npm run "Incremental building" 2>&1 | while read -r line; do
    echo "[Modules] $line"
    if [[ $line == *"Watching for file changes."* && $modules_done -eq 0 ]]; then
      modules_done=1
      touch /tmp/modules_build_done
    fi
  done
) &

echo "等待Tokens、ModulesCollection首次构建完成..."
# 轮询等待两个完成标记生成
while [ ! -f /tmp/tokens_build_done ] || [ ! -f /tmp/modules_build_done ]; do
  sleep 0.5
done

rm -f /tmp/tokens_build_done /tmp/modules_build_done
echo "前置依赖首次构建完成,启动Lexer构建..."

cd "$LEXER_DIR" || exit 1
npm run "Incremental building"

这里默认匹配规则为只要出现Watching for file changes.就算首次编译流程走完,不校验是否存在类型错误;如果需要等零错误再启动Lexer,把匹配字符串改回Found 0 errors. Watching for file changes.即可。脚本给每个子项目的输出加了前缀,不会出现三个项目日志混杂难以排查的问题。

方案2:使用带生命周期钩子的tsc封装工具

如果觉得自行写日志匹配逻辑麻烦,可以把原生tsc替换成带构建钩子的封装包,比如tsc-watch,它自带--onFirstSuccess参数,可直接指定首次构建成功后执行的命令,不需要手动解析日志,也不会因为后续tsc版本升级调整日志输出格式导致匹配失效。
用法很简单,安装依赖后,把Tokens和ModulesCollection的"Incremental building"脚本调整为:

rimraf Distributable && tsc-watch --onFirstSuccess "touch /tmp/%PROJECT_NAME%_build_done"

把%PROJECT_NAME%替换为对应项目标识(tokens或者modules)即可,后续等待标记、启动Lexer的逻辑和方案1完全一致,Lexer本身不需要修改,继续沿用原有watch脚本即可,完全不影响后续文件变更自动重编译的能力。

方案3:直接轮询构建产物

如果不想修改现有构建命令,可直接轮询两个项目Distributable输出目录下的核心文件,比如各自的入口js文件、类型声明文件,两个目标文件都生成即判定首次构建完成。
核心逻辑就是简单的循环判断:

while [ ! -f "$TOKENS_DIR/Distributable/index.js" ] || [ ! -f "$MODULES_DIR/Distributable/index.js" ]; do
  sleep 0.5
done

这个方法实现成本最低,但要注意选对判断用的特征文件,必须是构建流程最后生成的产物,不要选构建中途就会生成的临时文件,避免提前触发Lexer启动导致依赖缺失报错。

补充说明
  • 以上三个方案都不会破坏watch模式的自动重编译能力,完全匹配需求
  • 如果在Windows环境运行,使用Git Bash或者WSL执行bash脚本即可,临时标记文件路径替换为Windows系统临时目录路径就可以正常运行

内容的提问来源于stack exchange,提问作者Takeshi Tokugawa YD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:27:34