cli本質是一種用戶操做界面,根據一些指令和參數來與程序完成交互並獲得相應的反饋,好的cli還提供幫助信息,咱們常常使用的vue-cli就是一個很好的例子。本文將使用nodejs從頭開發併發布一款cli工具,用來查詢天氣。javascript
項目效果圖以下: vue
初始化一個項目:npm init -y
編寫入口文件index.js:java
module.exports = function(){
console.log('welcome to Anderlaw weather')
}
複製代碼
bin目錄下建立index:node
#!/usr/bin/env node
require('../')()
複製代碼
package.json配置bin信息ios
{
"name": "weather",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": {
"weather": "bin/index"
}
}
複製代碼
而後在根目錄(package.json同級)運行npm link
,該操做會將該項目的模塊信息和bin指令信息以軟連接的形式添加到npm全局環境中:ajax
C:\Users\mlamp\AppData\Roaming\npm\node_modules
下多了一個模塊連接C:\Users\mlamp\AppData\Roaming\npm
下多了個名爲weather
的cmd文件。好處是能夠更方便地進行本地調試。 而後咱們打開終端輸入:weather
就會看到welcome to Anderlaw weather
的log信息vue-cli
此處咱們使用minimist
庫來解析如:npm --save ,npm install 的參數。npm
安裝依賴庫 npm i -S minimist
json
使用process.argv
獲取完整的輸入信息axios
使用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 `)
}
}
複製代碼
截止目前工做順利進行,咱們還只是手工輸入的一些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
,發現有結果了:
截止當前,基本完成了功能開發,後續有一些小問題須要彌補一下,首先是一個進度提示,使用起來就更加可感知,咱們使用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
本文完!