使用 JavaScript 和 Oclif 构建出色的 CLI
最初发表于Streaver 的博客。
首先定义一个 CLI
当然,通过 Google 快速搜索可以找到一篇包含 CLI 定义的维基百科文章:
命令行界面或命令语言解释器 (CLI),也称为命令行用户界面、控制台用户界面和字符用户界面 (CUI),是一种与计算机程序交互的方式,用户(或客户端)以连续的文本行(命令行)的形式向程序发出命令。处理该界面的程序称为命令语言解释器或 Shell(计算)。
因此,简而言之,CLI 是一种可以理解用户以文本形式提出的请求,然后采取行动并执行代码的程序。
这类程序对于许多不同的用例都非常有用,从简单的 CLI(如cal
显示当前月份的 Bash 工具)到极其复杂的 CLI(如kubectl
管理 Kubernetes 集群)。
即使您不是每天直接使用 CLI(这种情况不太可能发生),您也可能受到它们的间接影响,例如git
CLI、gcc
GNU 编译器、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:past
的libertadores 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.js
和tests/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
,我们将在终端上得到结果:
你可能已经注意到,我还添加了一个“加载”功能,以便为用户提供一些视觉反馈。要添加此功能,你只需安装该软件包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