使用 JavaScript 和 Oclif 构建出色的 CLI

2025-06-05

使用 JavaScript 和 Oclif 构建出色的 CLI

最初发表于Streaver 的博客

首先定义一个 CLI

当然,通过 Google 快速搜索可以找到一篇包含 CLI 定义的维基百科文章:

命令行界面或命令语言解释器 (CLI),也称为命令行用户界面、控制台用户界面和字符用户界面 (CUI),是一种与计算机程序交互的方式,用户(或客户端)以连续的文本行(命令行)的形式向程序发出命令。处理该界面的程序称为命令语言解释器或 Shell(计算)。

因此,简而言之,CLI 是一种可以理解用户以文本形式提出的请求,然后采取行动并执行代码的程序。

这类程序对于许多不同的用例都非常有用,从简单的 CLI(如cal显示当前月份的 Bash 工具)到极其复杂的 CLI(如kubectl管理 Kubernetes 集群)。

即使您不是每天直接使用 CLI(这种情况不太可能发生),您也可能受到它们的间接影响,例如gitCLI、gccGNU 编译器、create-react-app用于生成 React 应用程序的脚手架 CLI 等等。

如何构建自己的 CLI

就像科技界的许多事情一样,答案是“视情况而定”。构建 CLI 的方法有很多,而且每种方法可能在不同的环境下都适用。在本例中,我将探索如何使用 JavaScript 和Oclif 来构建一个 CLI:一个 Node.JS 开放 CLI 框架(由 Heroku 开发),它包含一个用于构建 CLI 的 CLI 🤔。

危险

从现在开始,我假设你对 JavaScript 和 NPM 生态系统已经很熟悉了,如果不是,你可能会有一个大概的了解,但我建议你在开始之前阅读一些相关内容😃。

Oclif 入门

在我看来,构建某些东西通常是一种很好的学习方式,所以在这种情况下,我与@flarraa进行了一些头脑风暴,并决定构建一个“Copa Libertadores”CLI(参见维基百科)。

这个想法是提供一组命令,可以检索和显示有关“南美解放者杯”锦标赛已经进行的比赛和即将进行的比赛的信息。

让我们开始吧!

Oclif CLI 有两种生成 CLI 项目的方法,一种是npx oclif single mynewcli,第二种是npx oclif multi mynewcli,在这种情况下,我们将生成一个多命令 CLI。

我们希望我们的命令看起来像libertadores games:all,,这与 Ocliflibertadores games:pastlibertadores games:upcoming多命令 CLI 生成一致。

初始化项目

首先,我们通过执行以下操作来初始化项目:

npx oclif multi libertadores-cli

这会询问一些问题,然后它会安装您开始编码所需的一切!

$ npx oclif multi libertadores
npx: installed 442 in 32.454s

     _-----_     ╭──────────────────────────╮
    |       |    │      Time to build a     │
    |--(o)--|    │  multi-command CLI with  │
   `---------´   │  oclif! Version: 1.13.1  │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

? npm package name libertadores-cli
? command bin name the CLI will export libertadores
? description A simple CLI to get information about "Copa Libertadores" right in your terminal
? author Federico Kauffman
? version 0.0.0
? license MIT
? Who is the GitHub owner of repository (https://github.com/OWNER/repo) streaver
? What is the GitHub name of repository (https://github.com/owner/REPO) libertadores-cli
? Select a package manager yarn
? TypeScript No
? Use eslint (linter for JavaScript) Yes
? Use mocha (testing framework) Yes
? Add CI service config circleci (continuous integration/delivery service)

我选择了一些我喜欢的默认设置,现在您有一堆文件和文件夹,它们将成为我们项目的主要结构。接下来使用 进入目录cd libertadores-cli

我将简要解释一下 Oclif 为我们生成了什么:

.
├── README.md
├── bin
│   ├── run
│   └── run.cmd
├── package.json
├── src
│   ├── commands
│   │   └── hello.js
│   └── index.js
├── test
│   ├── commands
│   │   └── hello.test.js
│   └── mocha.opts
└── yarn.lock

5 directories, 9 files

查看文件树,您可以看到bin包含在每个平台(Unix/Windows)上运行命令的二进制文件的目录。

您会看到src文件夹中有一个index.js文件,该文件只是导出了一个内部 Oclif 包,它将加载可用的命令,这些命令定义在src/commands文件夹中的文件中。默认情况下,Oclif 会生成一个hello命令,让我们运行它看看结果如何:

$ ./bin/run

A simple CLI to get information about "Copa Libertadores" right in your terminal

VERSION
  libertadores-cli/0.0.0 darwin-x64 node-v11.13.0

USAGE
  $ libertadores [COMMAND]

COMMANDS
  hello  Describe the command here
  help   display help for libertadores

如果您运行hello子命令,您将获得:

$ ./bin/run hello

hello world from ./src/commands/hello.js

最后但并非最不重要的一点是,您有tests一个放置所有测试的文件夹,事实上,Oclif 已经创建了一些测试,我们可以使用npm run test或运行它们yarn test

创建第一个命令

首先,我们可以删除该hello命令,因为我们不打算使用它,只需删除src/command/hello.jstests/commands/hello.test.js

现在我们可以使用 Oclif CLI 生成器命令,让我们games:all使用以下命令创建命令:

npx oclif command games:all

这将创建命令所需的所有文件(包括测试),并且还将README.md自动更新文件以包含新命令。

我们将从http://www.conmebol.com/es/copa-libertadores-2019/fixture获取“Copa Libertadores”的详细信息,我们将使用puppeteer进入该网站并获取数据。

$ yarn add puppeteer --save
const puppeteer = require("puppeteer");
...
class AllCommand extends Command {
  async run() {
    ...
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(
      "http://www.conmebol.com/es/copa-libertadores-2019/fixture",
      { waitUntil: "load", timeout: 0 }
    );

    // Insert some really crazy code to parse the HTML
    // you can find this at https://github.com/streaver/libertadores-cli

    this.log(results);
  }
}

现在我们可以执行libertadores games:all,我们将在终端上得到结果:

asciicast

你可能已经注意到,我还添加了一个“加载”功能,以便为用户提供一些视觉反馈。要添加此功能,你只需安装该软件包cli-ux,然后将代码中“缓慢”的部分包装在一些启动/停止调用中:

像这样安装:

yarn add cli-ux --save

添加微调器,例如:

const { cli } = require('cli-ux');
...

cli.action.start('Fetching data');
//Do something that takes time
cli.action.stop();
...

现在,我们已经有了 CLI,可以编写测试了!Oclif 内置了一些不错的默认设置,可以用来测试这类 CLI。在本例中,你只需要测试终端的输出是否符合你的预期。幸运的是,该命令的自动生成测试正是如此,你只需要调整代码即可!

我会把这个任务留给你(读者,就像数学书一样)🙄...或者你可以在“Copa Libertadores”CLI 的官方存储库中查看它们。

安装 CLI,保持最新状态,不再错过游戏❤️⚽!

文章来源:https://dev.to/fedekau/building-awesome-clis-with-javascript-and-oclif-291o
PREV
各位开发者,我们的姓氏该怎么写?我们目前的迭代 未来的可能性 Roygreen(更简单但仍然令人困惑) 关键要点 你的挑战
NEXT
使用 Instant.page Guess.js (alpha) 在 1 分钟内加速您的网站