用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 相关文章推荐
jquery选择器(常用选择器说明)
Sep 28 Javascript
javascript string字符串优化问题
Jul 31 Javascript
深入理解JavaScript作用域和作用域链
Oct 21 Javascript
jquery插件bxslider用法实例分析
Apr 16 Javascript
js控制TR的显示隐藏
Mar 04 Javascript
jQuery 3 中的新增功能汇总介绍
Jun 12 Javascript
深入浅析JavaScript中的scrollTop
Jul 11 Javascript
干货!教大家如何选择Vue和React
Mar 13 Javascript
Javascript实现购物车功能的详细代码
May 08 Javascript
vue-quill-editor+plupload富文本编辑器实例详解
Oct 19 Javascript
JS中的算法与数据结构之二叉查找树(Binary Sort Tree)实例详解
Aug 16 Javascript
JS如何把字符串转换成json
Feb 21 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生成4位数字验证码的实现代码
2015/11/23 PHP
在Mac OS下搭建LNMP开发环境的步骤详解
2017/03/10 PHP
php数据序列化测试实例详解
2017/08/12 PHP
FF IE兼容性的修改小结
2009/09/02 Javascript
Mootools 1.2教程 选项卡效果(Tabs)
2009/09/15 Javascript
改进UCHOME的记录发布,增强可访问性用户体验
2011/01/17 Javascript
jquery ajax 调用失败的原因示例介绍
2013/09/27 Javascript
window.open打开页面居中显示的示例代码
2013/12/27 Javascript
button没写type=button会导致点击时提交
2014/03/06 Javascript
js监听鼠标事件控制textarea输入字符串的个数
2014/09/29 Javascript
JavaScript动态改变表格单元格内容的方法
2015/03/30 Javascript
JavaScript中iframe实现局部刷新的几种方法汇总
2016/01/06 Javascript
JQuery 传送中文乱码问题的简单解决办法
2016/05/24 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
JS阻止事件冒泡行为和闭包的方法
2016/06/16 Javascript
webpack打包单页面如何引用的js
2017/06/07 Javascript
浅谈angular4 ng-content 中隐藏的内容
2017/08/18 Javascript
JavaScript分步实现一个出生日期的正则表达式
2018/03/22 Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
2018/05/02 Javascript
VUE安装使用教程详解
2019/06/03 Javascript
微信小程序引入VANT组件的方法步骤
2019/09/19 Javascript
Vue学习之常用指令实例详解
2020/01/06 Javascript
举例讲解Python中的算数运算符的用法
2015/05/13 Python
python使用clear方法清除字典内全部数据实例
2015/07/11 Python
详解Python中的相对导入和绝对导入
2017/01/06 Python
Python绘制二维曲线的日常应用详解
2019/12/04 Python
Python列表倒序输出及其效率详解
2020/03/04 Python
HTML5中语义化 b 和 i 标签
2008/10/17 HTML / CSS
video.js支持m3u8格式直播的实现示例
2020/05/20 HTML / CSS
科尔士百货公司官网:Kohl’s
2016/07/11 全球购物
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
关于颐和园的导游词
2015/01/30 职场文书
2016秋季小学开学寄语
2015/12/03 职场文书
redis限流的实际应用
2021/04/24 Redis
Vue中Object.assign清空数据报错的解决方案
2022/03/03 Vue.js
JavaWeb Servlet开发注册页面实例
2022/04/11 Java/Android