execa NodeJs新一代child_process的强力替代品

execa

execa 是 NodeJs 官方 child_process 模块的增强替代品。把 JS 里"执行命令"这件麻烦事,做成简单、可靠、对新手友好的 Promise API

对比原生写法,优势立现:

操作 child_process 原生 execa
执行并拿输出 要自己包 Promise 直接 await 返回 {stdout, stderr}
捕获错误 判断回调 error 对象 catch 即可,错误对象信息齐全
二进制输出 Buffer 处理繁琐 stdout 自动 UTF-8 解码成字符串

快速开始:

shell 复制代码
npm install execa
js 复制代码
import { execa } from 'execa'

const { stdout } = await execa('echo',['hello world'])
console.log(stdout); //hello world

try{
    await execa('unknown-command');
} catch(error){
  console.log(error.shortMessage);
  // 命令不存在时:'/bin/sh: unknown-command: command not found'
  console.log(error.exitCode); // 127
}

await 返回 {stdout, stderr},正确回调的返回结果和错误结果。

核心API

execa('command',[argument],[options])

最常用形式,数组传参,不需要拼字符串,天然规避 shell 注入:

js 复制代码
// 执行 git log --oneline -5
await execa('git', ['log', '--oneline', '-5']);

// 传环境变量
await execa('echo', ['$HOME'], { shell: true });
$模板字符串命令

虽然 execa 全程只认数组参数,但提供 $ 语法糖让你写模板字符串,同时自动做参数转义

js 复制代码
import { $ } from 'execa';

await $`echo hello`;                    // 简单命令
await $`git commit -m ${'feat: 新功能'}`; // 参数自动安全转义,防注入

// 同样返回 { stdout, stderr }
const { stdout } = await $`ls -al`;
execaSync('command',[arguments],[options])

同步版本,适合脚本初始化和简单场景:

js 复制代码
import { execaSync } from 'execa';

const { stdout } = execaSync('npm', ['--version']);
console.log(stdout);

结果对象

await 后返回的对象包含:

  • stdout --- 标准输出字符串
  • stderr --- 错误输出字符串
  • exitCode --- 退出码
  • failed --- 布尔值,是否失败
  • command --- 实际执行的完整命令(便于日志)
  • timedOut、killed、isCanceled 等状态标记

execa 的异常对象非常全(继承 Error):

  • error.stdout / error.stderr --- 失败时的输出/错误输出
  • error.exitCode
  • error.message --- 命令+args+退出码
  • error.shortMessage --- 精简错误信息
  • error.failed --- true
  • error.timedOut / error.isCanceled / error.killed --- 各种失败原因标记
  • error.command --- 实际的完整命令串

同步execa返回的是result对象

常用配置项(options)

选项 作用 示例
cwd 指定工作目录 { cwd: '/path/to/project' }
env 注入环境变量(默认继承父进程) { env: { FOO: 'bar' } }
shell 用 shell 执行(支持管道、重定向、通配符) { shell: true }
timeout 超时强杀(毫秒) { timeout: 5000 }
input 给子进程喂 stdin 数据 { input: 'hello stdin' }
stdio 控制输入输出流向 { stdio: 'inherit' } 可直接打印到终端
reject 失败是否抛错,false 时不抛、返回结果对象 { reject: false }
buffering 关闭输出缓冲、实时流式读取(v7+) { buffering: false } 配合 stream.pipe()/catch()
windowsHide Windows 下隐藏子进程窗口 默认 true

加载配置与默认值

js 复制代码
// cwd 是高频需求,配合 path 使用
const res = await execa('node', ['app.js'], {
  cwd: path.resolve('./server'),
  timeout: 10000,
  env: { NODE_ENV: ' 'production' },
});

进阶能力

1 管道(stream 链式)
js 复制代码
import { execa } from 'execa';

const psResult = await execa('ps', ['aux'], { stripFinalNewline: false });
await execa('grep', ['node'], { input: psResult.stdout });
2 流式实时输出(看到命令一行行打,而不是最后一次性)
js 复制代码
const subprocess = execa('npm', ['run', 'build'], { buffering: false });
subprocess.stdout.pipe(process.stdout);     // 实时打印
subprocess.stderr.pipe(process.stderr);

// 流式错误处理用 catch 而非 try/catch
subprocess.catch((error) => {
  console.error(error.stderr);
});
3 取消任务(kill / cancel)
js 复制代码
const subprocess = execa('node', ['long-task.js']);
setTimeout(() => subprocess.kill('SIGTERM'), 3000);

await subprocess; // 会被拒绝,错误对象带 killed: true

// v8+ 用 AbortController 更干净
import { execa } from 'execa';
const controller = new AbortController();
setTimeout(() => controller.abort(), 3000);
await execa('node', ['long-task.js'], { signal: controller.signal });
4 超时
js 复制代码
try {
  await execa('ping', ['-t', '127.0.0.1'], { timeout: 2000 });
} catch (error) {
  console.log(error.timedOut); // true
}
5 拒绝策略(reject: false)

不想让失败抛异常、只想拿退出码判断时:

js 复制代码
const result = await execa('my-tool', args, { reject: false });
console.log(result.exitCode, result.failed, result.stderr);
// 不会 throw,一切信息都在 result 里
6 执行 shell 整段脚本
js 复制代码
const { stdout } = await execa('bash', ['-c', 'echo a && echo b']);
相关推荐
水獭比特2 小时前
工作流都公开了,为什么还不能继承 Owner 权限?
javascript·人工智能·node.js
ly76894 小时前
Vue 3 从入门到工程实践:基础语法、组件化、路由、状态管理与项目部署
前端·javascript·vue.js
四千岁5 小时前
抓包LangChain-了解LangChain的原理
前端·javascript·后端
用户298698530145 小时前
使用 JavaScript 在 React 中实现 Word 转 PDF
前端·javascript·react.js
悟空瞎说5 小时前
UICollectionViewLayout 全套源码 + 逐行中文注释 + 使用场景说明
javascript
铁皮饭盒8 小时前
浏览器AI肯定离不开onnxruntime, 微软开源
前端·javascript·后端
码视野8 小时前
基于 Vue3 + Element Plus 的【智慧社区洗车养车与上门流动洗车预约调度系统】设计与实现(含PRD/三端源码/大屏)
前端·javascript·vue.js·人工智能·vue3
码视野8 小时前
基于 Vue3 + Element Plus 的【无人值守共享自习室与空间智能预约系统】设计与实现(含PRD/三端源码/大屏)
前端·javascript·vue.js·人工智能·vue3
CarIise8 小时前
JavaScript基础语法与DOM操作实战课堂笔记
开发语言·javascript·笔记