Exec in place instead of spawning and waiting in the CLI's wrapper processes
Maintainer thường phản hồi trong vòng 1 ngày
@fengmk2 đang làm issue này rồi.
Từ ngày 18/10/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
Follow-up to #2936, which made the project-local vpx bin replace itself with the script's Node.js through process.execve() on Unix instead of spawning it and waiting. The global CLI's shims already exec in place (exec_tool in crates/vp_global_cli/src/shim/exec.rs). Several other paths still spawn a child only to wait for it and pass its exit status on.
Why
- One PID and real signals. The wrappers ignore SIGINT so that Ctrl+C reaches the child through the process group, and none of them forwards SIGTERM or SIGHUP. A tool that holds the PID of
vpand sends it a signal (kill <pid>, a process manager, a test harness) stops the wrapper, or nothing, while the real process keeps running.SIGUSR1opens a Node.js wrapper's inspector instead of the tool's, and kills the Rustvpwrapper while the tool keeps running. - Exact exit status. A child killed by a signal comes back as a plain exit code (
exit_code_from_status,exit_status_from,process.exit(n)inbin.ts), so callers cannot tellSIGINTfromexit 130. - Fewer idle processes.
vp devthrough the global CLI runs three processes:vp(Rust) waits fornode dist/bin.js, which waits for the Vite Node.js process. An idle Node.js wrapper holds about 50 MB for as long as the dev server runs.
Startup time does not change, since each wrapper still starts before it execs.
Candidates
Strongest first. "After the child" is what the parent still does once the child exits, which an exec must move earlier or keep on the spawn path.
| # | Command | Where | After the child |
|---|---|---|---|
| 1 | global vpr → node <vite-plus>/dist/bin.js run … |
js_executor.rs run_js_entry → vp_command::execute_with_terminal_guard |
nothing (shim mode skips the upgrade notice) |
| 2 | global vpx pkg@version / -p / -c → package manager dlx |
vpx.rs → vp_pm_cli resolution/runner.rs run_command → vp_command::run_command |
nothing |
| 3 | vp env exec --node <v> [--npm <v>] <command> |
commands/env/exec.rs:235-252 |
the upgrade notice; the shim branch of the same command already execs |
| 4 | vp sync-versions with the packaged sidecar |
commands/sync_versions.rs:32-35 |
nothing |
| 5 | vp exec <command> for one package, without --report-summary |
binding/src/exec/workspace.rs:254 |
nothing in that case |
| 6 | vp dev, preview, build, test, pack, doc, lint (not --init) |
binding/src/cli/execution.rs:36-57 |
nothing; the --init and fmt paths filter output and stay as they are |
| 7 | package-manager passthrough in the local CLI (vp install, add, dlx, …, and the local vpx pkg@version) |
binding/src/cli/mod.rs → vp_pm_cli runner |
the toolchain hint after vp why only |
| 8 | global CLI delegation to JS (vp dev, build, test, lint, fmt, check, pack, run, …) |
cli.rs → commands/delegate.rs → js_executor.rs |
the cached upgrade notice (main.rs:597-599) |
| 9 | global package-manager passthrough (vp install, add, why, …) |
cli.rs → vp_pm_cli runner |
the vp why hint and the upgrade notice |
Rows 2, 7, and 9 share vp_pm_cli's runner and vp_command::run_command, so an exec variant there covers them together. Rows 5–7 run inside the Node.js process of the local CLI. For row 8, the upgrade notice has to print before the exec, keep the spawn path when a notice is due, or be dropped as the shim branch already does.
Not candidates: npm install -g / uninstall -g (they link bins afterwards), vp fmt and vp check (they filter or capture output), vp run / vp cache (task graph, many children), multi-package and --parallel vp exec, the installer (it owns the temp directory with the binary), and every call that captures output.
Lessons from #2936
- Blocking stdio. Node.js sets
O_NONBLOCKon a pipe once it opens it as stdio, andprocess.execve()passes that on (nodejs/node#66824), so the new program's writes fail withEAGAIN.bin.tsalready restores blocking stdio; anything that execs from Node.js must do so first. - Signal dispositions. Node.js ignores SIGPIPE and SIGXFSZ, and an ignored signal stays ignored across exec. std's
CommandExt::execrestores SIGPIPE but not SIGXFSZ.vpx-bin.tsrestores both by adding and removing a listener. - A failed exec.
process.execve()aborts Node.js on failure before 26.12 instead of throwing.vpx-bin.tsexecs binaries through/bin/sh -c 'exec "$0" "$@"'for that reason. A Rust exec returns an error the caller can still report. - IPC. Exec closes an IPC channel, so a process started with one (
NODE_CHANNEL_FD,process.send) keeps spawning. - Windows has no exec, so every path keeps its spawn there.
- Rust side.
tokio::process::Command::as_std_mut().exec()keeps the configured env, cwd, andpre_exechooks (such asfix_stdio_streams), so the existing command builders can be reused.
Suggested order
- Add a Unix exec variant to
vp_commandnext torun_commandandexecute_with_terminal_guard, and use it for rows 1–4. - Use it for the local CLI's paths (rows 5–7), skipping exec when the process has an IPC channel and restoring SIGXFSZ.
- Decide the upgrade notice, then switch rows 8 and 9.
Separately, vp run does not forward SIGTERM to its tasks, which is out of scope here because it manages many children.
- Ngôn ngữ chính
- Rust
- Star
- 6.3k
- Fork
- 283
- Merge trung bình
- 1 ngày 16 giờ
- Pull request đã merge (30 ngày)
- 214
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của voidzero-dev/vite-plus
-
pending triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
voidzero-dev/vite-plus#2882 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
voidzero-dev/vite-plus#2097 · 10 bình luận · 2 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
defineConfig drops own properties of Promise plugins (breaks Vike discovery)Có thể đã có người làm @liangmiQwQ đã nhận hôm nay. Đang mởbug
voidzero-dev/vite-plus#3152 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
vpx: watch reports for `vpx --watch`, and `vpx watch` on oxc-node's watcherCó thể đã có người làm @fengmk2 đã nhận hôm nay. Đang mở
voidzero-dev/vite-plus#3141 · 1 reaction · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Document cross-platform `FOO=bar cmd` in task commands and scriptsCó thể đã có người làm @hyunbinseo đã nhận hôm nay. Đang mởdocumentation
voidzero-dev/vite-plus#3140 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của voidzero-dev/vite-plus
Issue tương tự
-
Alt select PhotocraftĐang mởpriority: medium
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
storytold/photocraft#8041 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
documentation good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
writerslogic/holographic-memory#96 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 63/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug good first issue help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
engine-rs P3 review-deferral wasm
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
maniator/verticopolis#1154 ·
Maintainer thường phản hồi trong vòng 1 ngày