当 esbuild 处于监视或服务模式时,为什么 Tcl 没有检测到任何“可读”事件?

问题描述 投票:0回答:0

我正在尝试在事件循环中驱动 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]

可能相关的其他一些参数:

  • Tcl 版本:8.6.7(通过 Windows 7 x64 上的 IronTcl)
  • esbuild 版本:0.17.18(下载链接

非常感谢您阅读本文。

tcl stdout event-loop esbuild
© www.soinside.com 2019 - 2024. All rights reserved.