deno.com
本页内容

构建命令行工具

视频描述 跳转到标题

学习如何使用 Deno 标准库构建命令行工具。你将探索如何使用实用函数解析参数、处理标志并提供有用的消息。跟随我们构建一个滑雪场信息应用,优雅地处理错误,并将脚本编译成可在多个平台(包括 Windows、MacOS 和 Linux)上运行的可执行文件。观看完本视频后,你将了解如何充分利用 Deno 的功能来开发和分发你自己的 CLI 工具。

文本和代码 跳转到标题

Deno 标准库介绍 跳转到标题

如果你想创建一个命令行工具,可以使用 Deno 的标准库。它包含数十个稳定的库,提供有用的实用函数,可以涵盖在 Web 中使用 JavaScript 时的许多基本操作。该标准库还可以在多种运行时和环境中工作,例如 Node.js 和浏览器。

设置命令行工具 跳转到标题

我们将创建一个命令行工具,然后将其编译成可在多个不同平台上用作可执行文件的形式。

创建一个名为 main.ts 的新文件并解析这些参数(请记住,我们总是可以从 Deno.args 中获取它们),然后我们将它们输出到控制台。

main.ts
const location = Deno.args[0];

console.log(`Welcome to ${location}`);

现在,如果我运行 deno main.ts,然后提供一个滑雪场名称,比如 Aspen,它就会将该名称插入到字符串中,例如:

deno main.ts Aspen
## Welcome to Aspen

安装和使用标准库 跳转到标题

现在让我们安装其中一个标准库。在终端中运行:

deno add jsr:@std/cli

这将把 Deno 标准库中的 cli安装到我们的项目中,以便我们可以利用它的一些实用函数。

我们将在这里使用的实用函数叫做 parseArgs。我们可以这样导入它:

import { parseArgs } from "jsr:@std/cli/parse-args";

然后我们可以更新代码以使用此函数,传递参数并移除零。我们的 main.ts 文件现在看起来像这样:

main.ts
import { parseArgs } from "jsr:@std/cli/parse-args";

const args = parseArgs(Deno.args);

console.log(args);

让我们来试一下,在你的终端中运行:

deno main.ts -h Hello

我们可以看到 Hello 已添加到我们的 args 对象中。好的,这按预期工作。

构建滑雪场信息应用 跳转到标题

现在我们的应用将是一个滑雪场信息应用,所以我们希望先用一些数据来填充它。我们将创建一个名为 resorts 的值。这是一个包含几个不同键的对象,所以我们将设置 elevation(海拔)、snow(雪况)和 expectedSnowfall(预期降雪)。然后我们直接复制粘贴这些,以便更快地进行操作。我们将 Aspen 的海拔设置为 7945,雪况设置为 packed powder(压实粉雪),预期降雪量为 15。然后我们再添加一个,将 Vail 的海拔设置为 8120,然后我们将预期降雪量设置为 25

main.ts
const resorts = {
  Whistler: {
    elevation: 2214,
    snow: "Powder",
    expectedSnowfall: "20",
  },

  Aspen: {
    elevation: 7945,
    snow: "packed powder",
    expectedSnowfall: 15,
  },
  Vail: {
    elevation: 8120,
    snow: "packed powder",
    expectedSnowfall: 25,
  },
};

我们这里有几个不同的滑雪场。最终,我们希望能够通过命令行参数运行我们的应用,提供滑雪场名称,然后让 CLI 工具返回该滑雪场的信息。

处理命令行参数 跳转到标题

那么,让我们继续向 parse args 传入另一个对象。在这里,我们将定义一个别名——所以我们会说“如果我传入 r 标志,我们希望它被认为是 resort”。然后我们再使用默认值,我们将 default resort 设置为 Whistler

main.ts
const args = parseArgs(Deno.args, {
  alias: {
    resort: "r",
  },
  default: {
    resort: "Whistler",
  },
});

从这里开始,我们可以设置一个名为 resortName 的常量并将其设置为 args.resort。然后获取滑雪场信息,使用 resorts[resortName](我们稍后会修复那个类型错误),并更新控制台输出:

main.ts
const resortName = args.resort;
const resort = resorts[resortName];

console.log(
  `Resort: ${resortName} Elevation: ${resort.elevation} feet Snow: ${resort.snow} Expected Snowfall: ${resort.expectedSnowfall}`,
);

为了测试它,我们可以使用:

deno main.ts -r Aspen

这将打印出 Aspen 的所有详细信息。

我们也可以不带任何参数运行,这应该会显示 Whistler 的详细信息,因为它被设置为默认值。

deno main.ts

我们的全名也是如此,所以我们可以这样说:

deno main.ts --resort Veil

这也应该提供那些详细信息。

改进错误处理 跳转到标题

现在,如果我尝试用一个不存在的滑雪场运行它,比如说 Bachelor;会出现一个错误,这有点难看。它在尝试解析时遇到了无法找到的时刻。所以我们可以通过以下方式让它变得更好:如果我们的数据集中没有匹配输入的 resort,我们就输出一个控制台错误信息,说“未找到滑雪场名称,请尝试 Whistler、Aspen 或 Vail”,然后我们使用 Deno.exit 退出该进程。

main.ts
if (!resort) {
  console.error(
    `Resort ${resortName} name not found. Try Whistler, Aspen, or Veil`,
  );
  Deno.exit(1);
}

修复类型错误 跳转到标题

好的,这里看起来不太好,我们可以在 TypeScript 中查看这里的问题——它告诉我们这隐式地具有 any 类型,你可以查找更多关于这个错误的信息,但我会告诉你如何修复它。将 resortName 的类型更新为 resorts 的一个键。

main.ts
const resortName = args.resort as keyof typeof resorts;

这样做是提取了 args.resort 的值,并断言数据中存在一个有效的键。

添加帮助和颜色输出 跳转到标题

让我们再进一步,我们将说如果 args.help 为真,我们将输出到控制台,然后给我们的用户一个简短的消息,告诉他们“嘿,这才是它的实际用法”,以防他们随时需要帮助,我们还会将这里的别名更新为 helpH,最后我们会确保调用 Deno.exit,以便我们一完成就退出进程。

main.ts
const args = parseArgs(Deno.args, {
  alias: {
    resort: "r",
    help: "h",
  },
  default: {
    resort: "Whistler",
  },
});

...

if (args.help) {
  console.log(`
    usage: ski-cli --resort <resort name>
    -h, --help    Show Help
    -r, --resort  Name of the ski resort (default: Whistler)
  `);
  Deno.exit();
}

你可以通过运行以下命令来测试你的帮助设置:

deno main.ts -h

接下来,让我们用颜色输出结果。Deno 支持使用 %C 语法来实现 CSS。

这将获取文本,并应用我们作为第二个参数传递给 console.log() 的样式。例如,这里我们可以将 color:blue 设置为第二个参数:

main.ts
console.log(`
    %c
    Resort: ${resortName} 
    Elevation: ${resort.elevation} feet 
    Snow: ${resort.snow} 
    Expected Snowfall: ${resort.expectedSnowfall}
    `, "color:blue"
);

Then run the program again:

```sh
deno main.ts -r Veil

你 E应该会看到所有内容都以蓝色显示。是不是很酷?!

为不同平台编译工具 跳转到标题

我也希望其他人能够享受这个应用。使用 Deno 将此工具编译成可执行文件非常容易。正如你可能想象的,运行此命令是 deno compile,然后是我们的脚本名称。这将把代码编译为项目中的一个可执行文件。

deno compile main.ts

你 E应该会在项目文件夹中看到名为 MyDenoProject 的可执行文件。现在你可以使用 ./ 将其作为可执行文件运行,例如:

./MyDenoProject --resort Aspen

所以这对我来说非常棒,但如果我想将它分享到其他平台怎么办?你所需要做的就是再次运行 deno compile,这次传入一个 --target 标志来指定你想要编译到的目标平台。

假设我们想为 Windows 编译,我们会使用:

deno compile --target x86_64-pc-windows-msvc --output ski-cli-windows main.ts

或为 Mac:

deno compile --target x86_64-apple-darwin --output ski-cli-macos main.ts

或为 Linux:

deno compile --target x86_64-unknown-linux-gnu --output ski-cli-linux main.ts

你可以在 Deno 文档中查看所有用于编译应用的选项。有许多不同的标志可以根据你自己的特定用例使用。

回顾一下,我们始终可以使用 Deno 标准库,它提供了许多有用的函数。如果我们要创建一个命令行工具,就像我们在这里所做的,我们总是可以通过 Deno 全局命名空间访问这些参数。我们可以使用标准库 CLI 包中的 parseArgs 函数来解析参数,并且可以为所有平台运行编译,这样我们的应用就可以在任何地方使用。

“示例”页面和我们的YouTube 频道上查找更多视频。

您找到所需内容了吗?

隐私政策