告别 Bash!zx 让 Node.js 轻松接管自动化脚本

18 阅读2分钟

zx 是一款强大的工具,它弥合了 shell 脚本与 JavaScript 之间的鸿沟,让你兼得两者的优势。它为 child_process 提供了便捷的封装,具备合理的默认值和跨平台兼容性,非常适合编写自动化脚本、部署工具和命令行实用程序。

为什么选择 zx?

传统的 shell 脚本在处理复杂逻辑时会变得繁琐,而 Node.js 在执行简单命令时又需要大量样板代码。zx 通过以下特性解决了这个问题:

  • JavaScript 语法及其所有现代特性
  • 内置实用程序用于常见 shell 操作
  • 跨平台兼容性(Linux、macOS、Windows)
  • 开箱即用的 TypeScript 支持
  • 零样板代码执行命令

安装

选择你喜欢的安装方式:

方法命令描述
npmnpm install zx标准 npm 安装
globalnpm install -g zx全局安装以供系统使用
npxnpx zx script.js无需安装即可运行脚本
yarnyarn add zxYarn 包管理器
pnpmpnpm add zxpnpm 包管理器
bunbun install zxBun 运行时支持
denodeno install -A npm:zxDeno 运行时支持

对于轻量级脚本,可以考虑使用 zx@lite - 这是一个依赖更少、启动速度更快的精简版本。

你的第一个 zx 脚本

创建一个名为 script.mjs 的文件,并添加以下 shebang:

#!/usr/bin/env zx 
// 你的第一个 zx 脚本
await $`echo "Hello, zx!"` 
const name = "World"await $`echo "Hello, ${name}!"` // 并行运行多个命令
await Promise.all([  $`echo "Task 1"`,  $`echo "Task 2"`,  $`echo "Task 3"`])

使其可执行并运行:

chmod +x script.mjs./script.mjs

或者使用 zx CLI:

zx script.mjs

核心概念

使用 $ 执行命令

$ 模板字面量是你运行 shell 命令的主要工具:

// 基本命令执行const output = await $`ls -la` // 变量会自动转义和引用
const filename = "my file.txt"await $`touch ${filename}` // 同步执行
const currentDir = $.sync`pwd` // 数组参数
const flags = ["--oneline", "--decorate", "--color"]
await $`git log ${flags}`

进程输出处理

命令返回 ProcessOutput 对象,其中包含捕获的 stdout/stderr:

try {  
    const result = await $`git status`  
    console.log("Git status:", result.stdout)
} catch (error) {  
    console.log("Command failed:", error.exitCode)  
    console.log("Error output:", error.stderr)
}

内置实用程序

zx 包含了常用的实用程序,无需额外导入:

// 切换目录
cd('./my-project') 
// 读写文件
const content = await fs.readFile('config.json', 'utf8')
await fs.writeFile('output.txt', 'Hello World') 
// 获取数据
const response = await fetch('https://api.github.com/users/google')
const user = await response.json() 
// 解析参数
const args = minimist(process.argv.slice(2))
console.log("Arguments:", args)

文件扩展名和模块类型

扩展名模块类型顶层 await推荐用于
.mjsESM现代 JavaScript 脚本
.jsESM/CJS❌ (需要包装器)传统兼容性
.tsTypeScript类型安全开发

对于 .js 文件,需要包装你的代码:

void async function () {  await $`echo "Hello"`}()

为了获得更好的 IDE 自动补全功能,请显式导入全局变量:import 'zx/globals'