用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 相关文章推荐
functional继承模式 摘自javascript:the good parts
Jun 20 Javascript
javascript中数组的多种定义方法和常用函数简介
May 09 Javascript
js格式化时间小结
Nov 03 Javascript
JavaScript 闭包机制详解及实例代码
Oct 10 Javascript
微信小程序 向左滑动删除功能的实现
Mar 10 Javascript
js中如何完美的解析数据
Mar 18 Javascript
Phaser.js实现简单的跑酷游戏附源码下载
Oct 26 Javascript
JS中的函数与对象的创建方式
May 12 Javascript
elementUI 动态生成几行几列的方法示例
Jul 11 Javascript
Node.js 实现简单的无侵入式缓存框架的方法
Jul 21 Javascript
layui的表单验证支持ajax判断用户名是否重复的实例
Sep 06 Javascript
使用js实现一个简单的滚动条过程解析
Sep 10 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自动识别文件编码并转换为UTF-8的方法
2014/06/12 PHP
PHP高手需要要掌握的知识点
2014/08/21 PHP
PHP实现八皇后算法
2019/05/06 PHP
线路分流自动跳转代码;希望对大家有用!
2006/12/02 Javascript
javascript 日历提醒系统( 兼容所有浏览器 )
2009/04/07 Javascript
前端开发必须知道的JS之原型和继承
2010/07/06 Javascript
js判断输入是否为正整数、浮点数等数字的函数代码
2010/11/17 Javascript
动态加载JS文件的三种方法
2013/11/08 Javascript
javascript 获取网页标题代码实例
2014/01/22 Javascript
详解Javascript 装载和执行
2014/11/17 Javascript
JavaScript中return false的用法
2015/03/12 Javascript
JS基于Mootools实现的个性菜单效果代码
2015/10/21 Javascript
利用jQuery实现WordPress中@的ID悬浮显示评论内容
2015/12/11 Javascript
适用于javascript开发者的Processing.js入门教程
2016/02/24 Javascript
json定义及jquery操作json的方法
2016/09/29 Javascript
JavaScript中Promise的使用详解
2017/02/26 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
2017/05/02 Javascript
jQuery扇形定时器插件pietimer使用方法详解
2017/07/18 jQuery
详谈JS中数组的迭代方法和归并方法
2017/08/11 Javascript
[06:01]刀塔次级联赛top10第一期
2014/11/07 DOTA
[03:42]2016国际邀请赛中国区预选赛首日现场玩家采访
2016/06/26 DOTA
Python3搜索及替换文件中文本的方法
2015/05/22 Python
聊聊Python中的pypy
2018/01/12 Python
python爬虫爬取淘宝商品信息(selenum+phontomjs)
2018/02/24 Python
python线程池threadpool使用篇
2018/04/27 Python
Pytorch卷积层手动初始化权值的实例
2019/08/17 Python
python错误调试及单元文档测试过程解析
2019/12/19 Python
利用Python的folium包绘制城市道路图的实现示例
2020/08/24 Python
外贸业务员的岗位职责
2013/11/23 职场文书
党员自我批评与反省材料
2014/02/10 职场文书
2014年小学教师工作自我评价
2014/09/22 职场文书
2014年信息宣传工作总结
2014/12/18 职场文书
试用期自我评价范文
2015/03/10 职场文书
报案材料怎么写
2015/05/25 职场文书
关于公司年会的开幕词
2016/03/04 职场文书
Opencv中cv2.floodFill算法的使用
2021/06/18 Python