用node开发并发布一个cli工具的方法步骤


Posted in Javascript onJanuary 03, 2019

cli本质是一种用户操作界面,根据一些指令和参数来与程序完成交互并得到相应的反馈,好的cli还提供帮助信息,我们经常使用的vue-cli就是一个很好的例子。本文将使用nodejs从头开发并发布一款cli工具,用来查询天气。

项目效果图如下:

用node开发并发布一个cli工具的方法步骤 

配置项目

初始化一个项目: npm init -y 编写入口文件index.js:

module.exports = function(){ 
	console.log('welcome to Anderlaw weather') 
}

创建bin文件

bin目录下创建index:

#!/usr/bin/env node
require('../')()

package.json配置bin信息

{
 "name": "weather",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "bin": {
 "weather": "bin/index"
 }
}

然后在根目录(package.json同级)运行 npm link ,该操作会将该项目的模块信息和bin指令信息以软链接的形式添加到npm全局环境中:

  • C:\Users\mlamp\AppData\Roaming\npm\node_modules 下多了一个模块链接
  • C:\Users\mlamp\AppData\Roaming\npm 下多了个名为 weather 的cmd文件。

好处是可以更方便地进行本地调试。 然后我们打开终端输入: weather 就会看到 welcome to Anderlaw weather 的log信息

解析命令与参数

此处我们使用 minimist 库来解析如:npm --save ,npm install 的参数。

安装依赖库 npm i -S minimist

使用 process.argv 获取完整的输入信息

使用 minimist 解析,例如:

weather today === args:{_:['today']}
weather -h === args:{ h:true }
weather --location 'china' === args:{location:'china'}

首先我们要实现查询今天和明天的天气,执行 weather today[tomorrow]

const minimist = require('minimist');
module.exports = ()=>{
 const args = minimist(process.argv.slice(2));//前两个是编译器相关路径信息,可以忽略
 let cmd = args._[0];
 switch(cmd){
 	case 'today':
 	console.log('今天天气不错呢,暖心悦目!');
 	break;
 	case 'tomorrow':
 	console.log('明天下大雨,注意带雨伞!');
 	break;
 }
}

以上,如果我们输入 weather 就会报错,因为没有取到参数.而且还没添加版本信息,因此我们还需要改善代码

const minimist = require('minimist')
const edition = require('./package.json').version
module.exports = ()=>{
 const args = minimist(process.argv.slice(2));//前两个是编译器相关路径信息,可以忽略
 let cmd = args._[0] || 'help';
 if(args.v || args.version){
		cmd = 'version';//查询版本优先!
	}
 switch(cmd){
 	case 'today':
 	console.log('今天天气不错呢,暖心悦目!');
 	break;
 	case 'tomorrow':
 	console.log('明天下大雨,注意带雨伞!');
 	break;
 	case 'version':
 	console.log(edition)
 	break;
 	case 'help':
 	console.log(`
  	weather [command] <options>
 
		  today .............. show weather for today
		  tomorrow ............show weather for tomorrow
		  version ............ show package version
		  help ............... show help menu for a command
		`)
 }
}

接入天气API

截止目前工作顺利进行,我们还只是手工输入的一些mock信息,并没有真正的实现天气的查询。 要想实现天气查询,必须借助第三方的API工具,我们使用心知天气提供的免费数据服务接口。

需要先行注册,获取API key和id 发送请求我们使用axios库(http客户请求库)

安装依赖: npm i -S axios 封装http模块

///ajax.js
const axios = require('axios')
module.exports = async (location) => {
 const results = await axios({
 method: 'get',
 url: 'https://api.seniverse.com/v3/weather/daily.json',
 params:{
  key:'wq4aze9osbaiuneq',
  language:'zh-Hans',
  unit:'c',
  location
 }
 })
 return results.data
}

该模块接收一个 地理位置 信息返回今天、明天、后台的天气信息。

例如查询上海今天的天气: weather today --location shanghai

修改入口文件,添加 async标志

const minimist = require('minimist')
const ajax = require('./ajax.js')
const edition = require('./package.json').version
module.exports = async ()=>{
 const args = minimist(process.argv.slice(2));//前两个是编译器相关路径信息,可以忽略
 let cmd = args._[0] || 'help';
 if(args.v || args.version){
		cmd = 'version';//查询版本优先!
	}
 let location = args.location || '北京';
 let data = await ajax(location);
 data = data.results[0];
	let posotion= data.location;
 let daily = data.daily;
 switch(cmd){
 	case 'today':
 	//console.log('今天天气不错呢,暖心悦目!');
 	console.log(`${posotion.timezone_offset}时区,${posotion.name}天气,${posotion.country}`)
  console.log(`今天${daily[0].date}:白天${daily[0].text_day}夜晚${daily[0].text_night}`)
 	break;
 	case 'tomorrow':
 	//console.log('明天下大雨,注意带雨伞!');
 	console.log(`${posotion.timezone_offset}时区,${posotion.name}天气,${posotion.country}`)
  console.log(`今天${daily[1].date}:白天${daily[1].text_day}夜晚${daily[1].text_night}`)
 	break;
 	case 'version':
 	console.log(edition)
 	break;
 	case 'help':
 	console.log(`
  	weather [command] <options>
 
		  today .............. show weather for today
		  tomorrow ............show weather for tomorrow
		  version ............ show package version
		  help ............... show help menu for a command
		`)
 }
}

我们输入 weather today --location shanghai ,发现有结果了:

用node开发并发布一个cli工具的方法步骤 

修修补补,添加loading提示和默认指令

截止当前,基本完成了功能开发,后续有一些小问题需要弥补一下,首先是一个进度提示,使用起来就更加可感知,我们使用 ora 库.

其次我们需要当用户输入无匹配指令时给予一个引导,提供一个默认的log提示。

安装依赖 npm i -S ora

编写loading模块:

const ora = require('ora')
module.exports = ora()
// method start and stop will be use

修改入口文件

const minimist = require('minimist')
const ajax = require('./ajax.js')
const loading = require('./loading')
const edition = require('./package.json').version
module.exports = async ()=>{
 const args = minimist(process.argv.slice(2));//前两个是编译器相关路径信息,可以忽略
 let cmd = args._[0] || 'help';
 if(args.v || args.version){
		cmd = 'version';//查询版本优先!
	}
 let location = args.location || '北京';
 loading.start();
 let data = await ajax(location);
 data = data.results[0];
	let posotion= data.location;
 let daily = data.daily;
 switch(cmd){
  case 'today':
 	//console.log('今天天气不错呢,暖心悦目!');
 	console.log(`${posotion.timezone_offset}时区,${posotion.name}天气,${posotion.country}`)
  console.log(`今天${daily[0].date}:白天${daily[0].text_day}夜晚${daily[0].text_night}`)
  loading.stop();
  break;
  case 'tomorrow':
  
 	//console.log('明天下大雨,注意带雨伞!');
 	console.log(`${posotion.timezone_offset}时区,${posotion.name}天气,${posotion.country}`)
  console.log(`今天${daily[1].date}:白天${daily[1].text_day}夜晚${daily[1].text_night}`)
  loading.stop();
 	break;
  case 'version':
  
  console.log(edition)
  loading.stop();
 	break;
 	case 'help':
 	console.log(`
  	weather [command] <options>
 
		  today .............. show weather for today
		  tomorrow ............show weather for tomorrow
		  version ............ show package version
		  help ............... show help menu for a command
  `)
  loading.stop();
  default:
  console.log(`你输入的命令无效:${cmd}`)
  loading.stop();
 }
}

发布

发布至npm仓库之后 可以直接以npm i -g weather全局方式安装我们发布的cli,并在任何地方输入weather命令查询天气了哟!

如果不清楚如何发布可查看我的另一篇文章发布一款npm包帮助理解npm

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JSON 学习之完全手册 图文
May 29 Javascript
javascript使用数组的push方法完成快速排序
Sep 15 Javascript
js实现点击链接后延迟3秒再跳转的方法
Jun 05 Javascript
Js获取当前日期时间及格式化代码
Sep 17 Javascript
AngularJS全局scope与Isolate scope通信用法示例
Nov 22 Javascript
使用jquery给新生的th绑定hover事件的实例
Feb 10 Javascript
JavaScript 中调用 Kotlin 方法实例详解
Jun 09 Javascript
Vue应用部署到服务器的正确方式
Jul 15 Javascript
详解Vue文档中几个易忽视部分的剖析
Mar 24 Javascript
详解如何在Angular优雅编写HTTP请求
Dec 05 Javascript
vue.js 2.0实现简单分页效果
Jul 29 Javascript
微信小程序关键字变色实现代码实例
Dec 13 Javascript
详解Vue基于vue-quill-editor富文本编辑器使用心得
Jan 03 #Javascript
Vue2 添加数据可视化支持的方法步骤
Jan 02 #Javascript
如何在Vue.js中实现标签页组件详解
Jan 02 #Javascript
如何使用less实现随机下雪动画详解
Jan 02 #Javascript
详解Vue2 添加对scss的支持
Jan 02 #Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
Jan 02 #Javascript
JS中数据结构之栈
Jan 01 #Javascript
You might like
PHP 5.3新特性命名空间规则解析及高级功能
2010/03/11 PHP
PHP文件大小格式化函数合集
2014/03/10 PHP
Django中的cookie与session操作实例代码
2017/08/17 PHP
php use和include区别总结
2019/10/13 PHP
在次封装easyui-Dialog插件实现代码
2010/11/14 Javascript
判断用户是否在线的代码
2011/03/05 Javascript
推荐9款炫酷的基于jquery的页面特效
2014/12/07 Javascript
JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件
2015/12/20 Javascript
js实现商城星星评分的效果
2015/12/29 Javascript
微信小程序 教程之引用
2016/10/18 Javascript
使用Angular缓存父页面数据的方法
2017/01/03 Javascript
JS设置CSS样式的方式汇总
2017/01/21 Javascript
Bootstrap表格使用方法详解
2017/02/17 Javascript
微信小程序列表渲染功能之列表下拉刷新及上拉加载的实现方法分析
2017/11/27 Javascript
详解node.js 下载图片的 2 种方式
2018/03/02 Javascript
vue2.0实现音乐/视频播放进度条组件
2018/06/06 Javascript
微信小程序实现之手势锁功能实例代码
2018/07/19 Javascript
详解react native页面间传递数据的几种方式
2018/11/07 Javascript
详解小程序设置缓存并且不覆盖原有数据
2019/04/15 Javascript
[02:06]DOTA2肉山黑名单魔法终结者 敌法师中文配音鉴赏
2013/06/17 DOTA
[37:29]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.19
2020/11/19 DOTA
Python中的__SLOTS__属性使用示例
2015/02/18 Python
Python实现比较两个列表(list)范围
2015/06/12 Python
Django中Forms的使用代码解析
2018/02/10 Python
Python 实现一行输入多个值的方法
2018/04/21 Python
在cmder下安装ipython以及环境的搭建
2018/10/19 Python
Python 硬币兑换问题
2019/07/29 Python
Python调用C语言程序方法解析
2020/07/07 Python
python开发入门——列表生成式
2020/09/03 Python
利用Python pandas对Excel进行合并的方法示例
2020/11/04 Python
美国最大的存储市场:SpareFoot
2018/07/23 全球购物
伊莱克斯(Electrolux)俄罗斯网上商店:瑞典家用电器品牌
2021/01/23 全球购物
教师节商场活动方案
2014/02/13 职场文书
合伙经营协议书范本(通用版)
2014/12/03 职场文书
优秀党员主要事迹材料
2015/11/04 职场文书
redis lua限流算法实现示例
2022/07/15 Redis