Code前端首页关于Code前端联系我们

如何使用 Google 的 zx 库在 Node 中编写 Shell 脚本

terry 1个月前 (02-24) 阅读数 129 #Javascript
文章标签 Google

image.png

在本文中,我们将了解 Google 的 zx 库提供了哪些功能,以及如何使用它来编写 Node.js 的 shell 脚本。然后,我们将学习如何通过构建一个命令行工具来使用 zx 的功能,该工具可帮助我们引导新 Node.js 项目的配置。

关键要点

  • Google 的 zx 库简化了 Node.js 中的 shell 脚本,通过利用 JavaScript 和内置实用程序使其更容易、更高效。

  • Zx 包装子进程创建并使用诸如用于执行 shell 命令的 `$` 函数之类的实用程序简化 stdout 和 stderr 处理。

  • Zx 通过附加工具(如“cd()”、“question()”)以及对流行库(如“chalk”、“minimist”、“fetch”和“fs-extra”)的访问增强了脚本功能。

  • 为了有效地使用 zx,应该将脚本设置为 ECMAScript 模块,并且应该将 zx 安装为本地依赖项以管理项目内的版本控制。

  • Zx 与 TypeScript 兼容,需要进行一些配置调整,并可能将异步代码包装在立即调用的函数表达式(IIFE)中。

  • 本教程演示了如何使用 zx 构建项目引导工具,该工具可自动执行设置新的 Node.js 项目、初始化 Git 和管理 npm 依赖项等任务。

编写 Shell 脚本:问题

创建 shell 脚本(由 Bash 或 zsh 等 shell 执行的脚本)是自动执行重复任务的好方法。Node.js 似乎是编写 shell 脚本的理想选择,因为它为我们提供了许多核心模块,并允许我们导入我们选择的任何库。它还使我们能够访问 JavaScript 提供的语言功能和内置函数。

但是,如果您尝试编写在 Node.js 下运行的 shell 脚本,您可能会发现它并不像您希望的那样顺利。您需要为子进程编写特殊处理,处理命令行参数的转义,然后最终弄乱stdout(标准输出)和stderr(标准错误)。它不是特别直观,并且会使 shell 脚本编写非常尴尬。

Bash shell 脚本语言是编写 shell 脚本的流行选择。无需编写代码来处理子进程,并且它具有用于处理stdout和的内置语言功能stderr。但使用 Bash 编写 shell 脚本也并非易事。语法可能相当混乱,难以实现逻辑或处理诸如提示用户输入之类的事情。

Google 的 zx有助于使使用 Node.js 的 shell 脚本编写变得高效且愉快。

跟随的要求

遵循本文有一些要求:

  • 理想情况下,您应该熟悉 JavaScript 和 Node.js 的基础知识。

  • 您需要能够熟练地在终端中运行命令。

  • 您需要安装Node.js >= v14.13.1。

Google 的 zx 如何工作?

Google 的 zx 提供了一些函数,用于包装子进程的创建以及这些进程的处理stdoutstderr我们将使用的主要函数是该$函数。下面是它的实际示例:

import { $ } from "zx";
await $`ls`;

以下是执行该代码的输出:

$ ls
bootstrap-tool
hello-world
node_modules
package.json
README.md
typescript


上面示例中的 JavaScript 语法可能看起来有点奇怪。它使用了一种称为标记模板文字的语言功能。其功能与编写相同await $("ls")

Google 的 zx 提供了其他几个实用函数来简化 shell 脚本编写,例如:

  • cd().这使我们能够改变当前的工作目录。

  • question()。这是 Node.js readline模块的包装器。它可以直接提示用户输入。

除了 zx 提供的实用功能外,它还为我们提供了几个流行的库,例如:

  • Chalk。该库允许我们为脚本的输出添加颜色。

  • minimist。解析命令行参数的库。然后它们在argv对象下公开。

  • fetch 。Fetch API的一个流行 Node.js 实现。我们可以使用它来发出 HTTP 请求。

  • fs-extra . 一个公开 Node.js 核心fs 模块的库,以及许多附加方法,使使用文件系统变得更加容易。

现在我们知道了 zx 给我们提供了什么,让我们用它创建我们的第一个 shell 脚本。

使用 Google 的 zx 来创建 Hello World

首先,让我们创建一个新项目:

mkdir zx-shell-scripts
cd zx-shell-scripts

npm init --yes

然后我们可以安装该zx库:

npm install --save-dev zx

注意:zx文档建议使用 npm 全局安装库。通过将其作为我们项目的本地依赖项安装,我们可以确保 zx 始终安装,并控制我们的 shell 脚本使用的版本。

顶层await

为了await在 Node.js 中使用 top-level (await在函数之外),我们需要在支持 top-level 的ECMAScript (ES) 模块async中编写代码。我们可以通过添加来指示项目中的所有模块都是 ES 模块,或者我们可以将各个脚本的文件扩展名设置为。我们将使用文件扩展名作为本文中的示例。await"type": "module"package.json.mjs.mjs

运行命令并捕获其输出

让我们创建一个名为 的新脚本hello-world.mjs。我们将添加一个shebang 行,它告诉操作系统 (OS)内核使用node程序运行该脚本:

#! /usr/bin/env node

现在我们将添加一些使用 zx 运行命令的代码。

在下面的代码中,我们运行一个命令来执行ls程序。该ls程序将列出当前工作目录(脚本所在的目录)中的文件。我们将从命令的进程中捕获标准输出,将其存储在变量中,然后将其记录到终端:

// hello-world.mjs

import { $ } from "zx";

const output = (await $`ls`).stdout;

console.log(output);

注意:zx文档建议将/usr/bin/env zxshebang 行放入脚本中,但我们使用的/usr/bin/env node是。这是因为我们已经将其安装zx为项目的本地依赖项。然后,我们明确地从包中导入我们想要使用的函数和对象zx。这有助于明确说明脚本中使用的依赖项来自何处。

然后我们使用chmod使脚本可执行:

chmod u+x hello-world.mjs

让我们运行脚本:

./hello-world.mjs

我们现在应该看到以下输出:

$ ls
hello-world.mjs
node_modules
package.json
package-lock.json
README.md
hello-world.mjs
node_modules
package.json
package-lock.json
README.md

您会注意到我们的 shell 脚本输出中的几件事:

  • 我们运行的命令(ls)包含在输出中。

  • 该命令的输出显示两次。

  • 输出末尾有一个额外的新行。

zx默认情况下,它以模式运行verbose。它将输出您传递给函数的命令$,并输出该命令的标准输出。我们可以在运行命令之前添加以下代码行来更改此行为ls

$.verbose = false;

大多数命令行程序(例如ls)都会在输出末尾输出一个换行符,以使终端中的输出更具可读性。这有利于提高可读性,但由于我们将输出存储在变量中,因此我们不需要这个额外的换行符。我们可以使用 JavaScript String#trim()函数将其删除:

const output = (await $`ls`).stdout;
const output = (await $`ls`).stdout.trim();

如果我们再次运行脚本,我们会看到情况好多了:


hello-world.mjs
node_modules
package.json
package-lock.json

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门