Skip to main content

自定义脚手架CLI

自定义终端命令

首先执行 npm init -y 初始化一个项目。

然后在项目根目录,来配置一个脚本。

#!/usr/bin/env node

console.log("init-demo 脚本执行了");

注意第一行注释,表示从计算机根目录找到 node 可执行文件。

然后在 package.json 中添加上 bin 字段。

{
"name": "auro-cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": {
"init-demo": "init-demo.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

接着在该项目的根目录执行 npm link,这样就相当于创建了一个软链接,并且软链接生成在了全局的 node_modules 下,这样一来我们就可以在全局命令行中,直接运行 init-demo 命令,就会执行该脚本。

$ init-demo
init-demo 执行了

使用 npm link 的作用是方便我们调试需要发布的全局 npm 包,如果每次更新代码后都先 npm publish 然后再 npm install 安装对应的包,这是十分麻烦的。

commander 的使用

--version 参数配置

对于一个命令行工具来说,我们输入对应的命令,然后在后面加上某些参数,终端就可以返回一些信息。

最常见的就是 --version 参数,用来查看该命令行工具的版本号。这需要借助一个 commander 第三方包来实现,很多的命令行工具,比如 vue-cli 都是使用的这个包。

$ npm i commander -S

然后在我们的 init-demo 脚本中添加如下代码。

#!/usr/bin/env node

const { Command } = require("commander");

const program = new Command();
program.version(require("./package.json").version); // 获取 package.json 文件中的 version 字段值
program.parse(process.argv); // 解析命令行传来的参数

console.log("init-demo 执行了")

这样当我们执行如下命令。

$ init-demo --version # 或者 -V
1.0.0

终端就可以显示该模块的版本号了。

你也可以给参数配置别名,--version 的默认别名是 -V,我们把它改成 -v

program.version(require("./package.json").version, "-v --version");

另外还需要注意,当我们执行 init-demo --version 后,该脚本只会执行 program.parse() 及其之前的 "普通代码" 和 program.version(),"普通代码" 表示非 commander 调用的 API。

因此执行 init-demo --version 后,终端不会输出 init-demo 执行了

自定义参数

commander 的功能很强大,它内置了许多命令参数,比如当我们传入 --help 参数,终端会当前所支持的所有参数。

$ init-demo --help
Usage: init-demo [options]

Options:
-v --version output the version number
-h, --help display help for command

我们可以新增自定义参数,使用 program.option()

#!/usr/bin/env node

const { Command } = require("commander");

const program = new Command();

program
.option(
"-N --new <cpn-name> [other...]",
"a component name, e.g. init-demo --new Button"
)
.description("create a component")
.action((arg) => {
console.log(arg)
});

program.parse(process.argv);

这样就新增了一个 --new 参数命令,我们需要传入一个 <cpn-name> 必选参数,和其他可选参数 [others...]

$ init-demo --new Button test1 test2 test3
{ new: [ 'Button', 'test1', 'test2', 'test3' ] }

action 回调中可以接收到该参数值。

program.on() 监听

使用该方法可以监听执行命令行时,是否使用了该参数。

#!/usr/bin/env node

const { Command } = require("commander");

const program = new Command();

program.on("--help", () => {
console.log("Others:")
console.log(" other options~")
})

program.parse(process.argv);

这样当我们执行 init-demo --help 时,由于使用了 --help 参数,所以在调用完内置的 --help 参数的回调后,就会执行 on 中的回调。

如果你想自定义 --help 内置的回调,可以使用 program.addHelpText

command 子命令

如果想在 init-demo 命令后面支持一些子命令,比如:

$ init-demo by --template ./src/template/demo.js

你可以使用 program.command() 方法。

#!/usr/bin/env node

const { Command } = require("commander");

const program = new Command();

program
.command("by <template> [others...]")
.description("create a component by your template")
.action((template, others) => {
console.log(template, others);
});

program.parse(process.argv);

Node 脚本下载 git 远程仓库

使用 download-git-repo 这个模块