本篇博客主要介绍了如何使用 commander, inquirer 以及 chalk 从零开始, 创建属于自己的命令行工具.
0. 一分钟体验
首先我们先花一分钟的时间, 体验一下创建自己的命令行 cli 工具是什么感觉.
0.1. 新建项目目录
假如我们的项目名称叫 hello-cli, 使用如下命令新建项目目录.
mkdir hello-cli && cd hello-cli
0.2. 初始化项目
接下里使用 NPM-init 命令来初始化一个简单的 package.JSON 文件.
NPM init -y
-y 命令表示接受 NPM 的一切默认参数设置. 然后替换 package.JSON 为如下代码.
- {
- "name": "hello-cli",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "bin": {
- "hello": "hello"
- },
- "scripts": {
- "test": "echo \"Error: no test specified\"&& exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "dependencies": {
- "chalk": "^2.4.2",
- "commander": "^2.20.0",
- "inquirer": "^6.3.1",
- "shelljs": "^0.8.3"
- }
- }
然后使用 NPM install 安装依赖.
0.3. 新建入口文件
在项目根目录下新建名为 hello 的文件, 不需要任何后缀, 值得注意的是此时的文件名就是你的 cli 工具第一个键入的命令, 例如 NPM install, 那么 hello 就等价于 NPM. 并将代码替换如下.
- #! /usr/bin/env node
- const program = require('commander');
- const inquirer = require('inquirer');
- const chalk = require('chalk');
- program
- .command('init')
- .alias('i')
- .description('初始化项目')
- .action(option => {
- // 该对象用于存储所有与用户交互的数据
- let config = {
- // 假设我们需要用户自定义项目名称
- projectName: null
- };
- // 使用 chalk 打印美化的版本信息
- console.log(chalk.default.bold('hello v1.0.0'));
- // 用于存储所有的交互步骤, 例如让用户输入项目名称就是其中一个步骤
- let promps = [];
- if (config.projectName === null) {
- promps.push({
- type: 'input',
- name: 'projectName',
- message: '请输入项目名称',
- validate: input => {
- if (!input) {
- return '项目名称不能为空';
- }
- // 更新对象中属性的数据
- config.projectName = input;
- return true;
- }
- });
- }
- // 至此, 与用户的所有交互均已完成, answers 是收集到的用户所填的所有数据
- // 同时, 这也是你开始操作的地方, 这个 cli 工具的核心代码应该从这个地方开始
- inquirer.prompt(promps).then(async (answers) => {
- // do something here
- console.log(answers);
- });
- });
- program.parse(process.argv);
- 0.4. NPM link
那么问题来了,
在你的项目根目录下使用 NPM link, 然后在你本地上就相当于安装了名为 hello-cli 这样的一个全局 NPM 包了. 其原理是将你本地的项目在全局的 node_modules 中做了一个软链接, 拿此项目举例, 全局的 hello 命令已经指向了你的本地目录. 如果你想取消测试项目在全局中的映射, 同样的进入项根目录, 输入命令 NPM unlink 即可.
然后搭配以下命令食用你的第一个 cli 工具吧. 如果报错提示没有权限, 在命令前加上 sudo 即可.
- hello init
- # 或者
- # hello i
- 1. commander
https://github.com/tj/commander.js 是一个 Node.JS 环境下的命令行接口解决方案. 在上面的一分钟体验例子中, 我们用到了 command,alias,description,action 这四个 API.
command command 代表了这个 cli 工具向用户暴露的命令行指令. 我们还是拿 NPM install 来举例子, command('init') 声明了一个叫 init 的命令, 在此处, init 等价于 install
alias alias 是对于当前命令行指令的更短的指令. 例如大家都知道, NPM install 可以简写为 NPM i.i 就是定义的 alias
description description 是对当前命令行指令的描述, commander 会自动的生成当前 cli 工具的帮助文档, 而该描述就会在 hello -h 中展示, 如果你的一分钟体验项目还在的话, 在命令行中输入 hello -h 就可以看到自动生成的帮助文档了
action action 是我们注册我们自己回调函数的地方
parse parse 命令则是解析命令行
下面是一分钟体验项目中没有使用的命令, option. 还是举一个例子. 如果有用过 https://hexo.io/zh-cn/index.html 的应该熟悉这个命令.
hexo new post $YOUR_POST_NAME
没用过也没关系, 这个命令是用于创建一个可以自定义名字的 Markdown 的文档的. 大家可能会发现, 上面的命令包含了 4 个单词, 而我们的例子中只有两个. 那是因为一分钟项目中没有使用 commander 的 optionAPI.
如果你想在 hello 项目中实现一样的命令, 那么只需要在 program 中调用该 API 即可..option('-p, --post', 'add post'), 然后就可以通过 option 参数获取到 - p 后面, 用户输入的参数的值.
2. inquirer
大家也发现了, 在命令行输入 init 命令后, 我们需要不停地与命令行进行交互拿到数据, 但是在代码里并没有怎么体现, 这是因为我们用了 inquirer https://github.com/SBoudrias/Inquirer.js/ 来帮我们做这些事情.
通过 inquirer, 我们可以实现输入框, 获取用户的输入数据, 还可以实现选择框. 举个例子, 用过 antd-design-pro 应该熟悉创建项目的流程. 在命令行中输入命令 yarn create umi, 在之后的流程中就会出现一个可选择的 list. 只需要将步骤中的代码替换成如下即可.
- promps.push({
- type: 'list',
- name: 'projectName',
- message: '请输入项目名称',
- choices: [
- {
- name: 'ant-design-pro',
- value: 'ant-design-pro'
- },
- {
- name: 'dva',
- value: 'dva'
- }
- ]
- });
在项目中, 还使用了 validate 来对用户的输入数据进行验证, 如果不需要验证的话, 直接把 validate 整个代码删除掉就好.
3. chalk
https://github.com/chalk/chalk 没有什么好介绍的, 官网上的文档已经写的很详细了. 给大家列一下项目中使用的例子就好.
- // 使用默认的字体颜色, 加粗字体
- console.log(chalk.default.bold('hello v1.0.0'));
- // 打印蓝色的提示信息
- console.log(chalk.blue('hello v1.0.0'));
- // 字符串模板用法, 在同一行中打印不同样式的信息
- console.log(chalk`{white.bold [1/3]} ` + chalk`{default.bold Clone project into local path...}`);
4. 最后
如果你厌倦了 Node.JS 写后端, 想用 Java 的 Spring Boot 来写, 但是又担心环境的搭建浪费太多时间. 那么你可以试试 https://github.com/detectiveHLH/venus-init , 只需要一行命令便可以快速搭建 Java 的开发环境.
Happy hacking.
来源: https://www.cnblogs.com/detectiveHLH/p/10881963.html