我正在尝试在事件循环中驱动 esbuild(用于 Web 开发的 CLI)作为我项目的跨平台构建脚本的一部分。当然,我可以直接在终端中运行 CLI,如下所示:
esbuild init.js --bundle --outdir=build --watch --servedir=build
,但是拥有一个适用于所有开发任务的一体化脚本很好,我想了解更多关于 Tcl 脚本的知识。
现在处于阻塞模式(使用
exec
),获取输出没有问题,除了 esbuild 返回退出代码 1 的(常见?)奇怪,即使没有错误。但是,对于像“watch”或“serve”这样的长时间运行的任务,我需要设置一个事件循环,对吗?但令我惊讶的是,在运行时,esbuild 从未发出 Tcl 认为“可读”的任何内容,但当直接从终端调用时,CLI 显示其输出(如脚本重建或页面重新加载等消息)非常好。这是演示情况的脚本:
proc read_output {cid} {
global loopdone
puts {[read_output] I got sth!}
if {[catch {read $cid} content] || [chan eof $cid]} {
chan configure $cid -blocking 1
catch {close $cid} msg
puts {subproc is done}
puts $msg
set loopdone 1
return
} else {
puts $content
}
}
set dev build/dev
set cid [open "|esbuild init.js --bundle --outdir=$dev --watch --servedir=$dev" r]
# set cid [open "|esbuild init.js --bundle --outdir=$dev" r]
chan configure $cid \
-translation lf \
-buffering line \
-blocking 0
chan event $cid readable "read_output $cid"
puts "entering event loop..."
vwait loopdone
puts "loop ended"
运行时,脚本输出将永远停留在“进入事件循环...”,这意味着
readable
的事件处理程序永远不会被调用!
但是,如果 esbuild 未处于 watch 或 serve 模式(如注释掉的第二个
open
命令),事件处理程序将被正确触发:
entering event loop...
[read_output] I got sth!
subproc is done
build\dev\init.js 9.4kb
Done in 7ms
loop ended
我也尝试了一些东西,比如为
open
命令使用不同的访问模式,以及为chan configure
使用不同的选项,比如-buffering
。但到目前为止,似乎都没有效果。
在此之前,我成功地使用了 Tcl 的事件循环来驱动另一个 CLI 应用程序 yt-dlp,以非阻塞模式将其输出“流”到 Tk 应用程序。因此,当然可能是 esbuild 的不同行为导致了这种棘手的情况,但我的学识还不足以说这是一个错误。毕竟,正如我所说,esbuild 在长时间运行模式下独立运行得非常好。例如,这是一个会话输出的转储:
> Network: http://10.0.0.100:8000/
> Local: http://127.0.0.1:8000/
[watch] build finished, watching for changes...
127.0.0.1:9487 - "GET /esbuild" 200 [0ms]
127.0.0.1:9492 - "GET /" 200 [1ms]
127.0.0.1:9493 - "GET /init.js" 200 [0ms]127.0.0.1:9492 - "GET /main.js" 200
[52ms]
127.0.0.1:9492 - "GET /esbuild" 200 [0ms]
[watch] build started (change: "init.js")
[watch] build finished
127.0.0.1:9493 - "GET /" 200 [1ms]
127.0.0.1:9493 - "GET /main.js" 200 [11ms]
127.0.0.1:9485 - "GET /init.js" 200 [0ms]
127.0.0.1:9493 - "GET /esbuild" 200 [0ms]
可能相关的其他一些参数:
非常感谢您阅读本文。