示例说明
原生 child_process 的回调与流式输出拼接繁琐,且容易把参数拼进 shell 字符串造成注入。execa 把子进程封装成 Promise,参数以数组传递不走 shell,stdout 与 stderr 分开返回,退出码与失败原因也成为结构化字段,适合在 CLI 工具或脚本管线里组合调用。
技术要点
- 参数数组形式天然避免 shell 注入风险
- reject:false 把失败转为普通返回值便于分支处理
- timeout 选项为子进程提供硬性时间上限
代码解读
runChecks 里执行 git diff –stat 并指定工作目录;reject 设为 false 后命令失败不会抛异常,而是返回带 failed 与 exitCode 字段的结果对象,代码据此打印 stderr 并返回布尔值。第二段演示 timeout 选项,超时会让进程被终止并抛出超时错误。
使用建议
需要 shell 特性(管道、通配符)时可显式开启 shell 选项,但输入来自外部时务必避免。长输出应改用 execa 的流式接口逐块消费,防止整段缓存占用过多内存。退出码语义要与服务约定对齐。
代码示例
import { execa } from 'execa';
async function runChecks() {
const result = await execa('git', ['diff', '--stat'], {
cwd: process.cwd(),
reject: false,
});
if (result.failed) {
console.error('command failed with code', result.exitCode);
console.error(result.stderr.trim());
return false;
}
console.log(result.stdout.trim());
return true;
}
const timeout = await execa('node', ['--version'], { timeout: 5000 });
console.log('node version:', timeout.stdout.trim());