用node開(kāi)發(fā)并發(fā)布一個(gè)cli工具的方法步驟
cli本質(zhì)是一種用戶操作界面,根據(jù)一些指令和參數(shù)來(lái)與程序完成交互并得到相應(yīng)的反饋,好的cli還提供幫助信息,我們經(jīng)常使用的vue-cli就是一個(gè)很好的例子。本文將使用nodejs從頭開(kāi)發(fā)并發(fā)布一款cli工具,用來(lái)查詢天氣。
項(xiàng)目效果圖如下:
配置項(xiàng)目
初始化一個(gè)項(xiàng)目: npm init -y
編寫入口文件index.js:
module.exports = function(){ console.log('welcome to Anderlaw weather') }
創(chuàng)建bin文件
bin目錄下創(chuàng)建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同級(jí))運(yùn)行 npm link
,該操作會(huì)將該項(xiàng)目的模塊信息和bin指令信息以軟鏈接的形式添加到npm全局環(huán)境中:
C:\Users\mlamp\AppData\Roaming\npm\node_modules
下多了一個(gè)模塊鏈接C:\Users\mlamp\AppData\Roaming\npm
下多了個(gè)名為weather
的cmd文件。
好處是可以更方便地進(jìn)行本地調(diào)試。 然后我們打開(kāi)終端輸入: weather
就會(huì)看到 welcome to Anderlaw weather
的log信息
解析命令與參數(shù)
此處我們使用 minimist
庫(kù)來(lái)解析如:npm --save ,npm install 的參數(shù)。
安裝依賴庫(kù) npm i -S minimist
使用 process.argv
獲取完整的輸入信息
使用 minimist
解析,例如:
weather today === args:{_:['today']} weather -h === args:{ h:true } weather --location 'china' === args:{location:'china'}
首先我們要實(shí)現(xiàn)查詢今天和明天的天氣,執(zhí)行 weather today[tomorrow]
const minimist = require('minimist'); module.exports = ()=>{ const args = minimist(process.argv.slice(2));//前兩個(gè)是編譯器相關(guān)路徑信息,可以忽略 let cmd = args._[0]; switch(cmd){ case 'today': console.log('今天天氣不錯(cuò)呢,暖心悅目!'); break; case 'tomorrow': console.log('明天下大雨,注意帶雨傘!'); break; } }
以上,如果我們輸入 weather
就會(huì)報(bào)錯(cuò),因?yàn)闆](méi)有取到參數(shù).而且還沒(méi)添加版本信息,因此我們還需要改善代碼
const minimist = require('minimist') const edition = require('./package.json').version module.exports = ()=>{ const args = minimist(process.argv.slice(2));//前兩個(gè)是編譯器相關(guān)路徑信息,可以忽略 let cmd = args._[0] || 'help'; if(args.v || args.version){ cmd = 'version';//查詢版本優(yōu)先! } switch(cmd){ case 'today': console.log('今天天氣不錯(cuò)呢,暖心悅目!'); 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
截止目前工作順利進(jìn)行,我們還只是手工輸入的一些mock信息,并沒(méi)有真正的實(shí)現(xiàn)天氣的查詢。 要想實(shí)現(xiàn)天氣查詢,必須借助第三方的API工具,我們使用心知天氣提供的免費(fèi)數(shù)據(jù)服務(wù)接口。
需要先行注冊(cè),獲取API key和id 發(fā)送請(qǐng)求我們使用axios庫(kù)(http客戶請(qǐng)求庫(kù))
安裝依賴: 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 }
該模塊接收一個(gè) 地理位置 信息返回今天、明天、后臺(tái)的天氣信息。
例如查詢上海今天的天氣: weather today --location shanghai
修改入口文件,添加 async標(biāo)志
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));//前兩個(gè)是編譯器相關(guān)路徑信息,可以忽略 let cmd = args._[0] || 'help'; if(args.v || args.version){ cmd = 'version';//查詢版本優(yōu)先! } 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('今天天氣不錯(cuò)呢,暖心悅目!'); console.log(`${posotion.timezone_offset}時(shí)區(qū),${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}時(shí)區(qū),${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
,發(fā)現(xiàn)有結(jié)果了:
修修補(bǔ)補(bǔ),添加loading提示和默認(rèn)指令
截止當(dāng)前,基本完成了功能開(kāi)發(fā),后續(xù)有一些小問(wèn)題需要彌補(bǔ)一下,首先是一個(gè)進(jìn)度提示,使用起來(lái)就更加可感知,我們使用 ora
庫(kù).
其次我們需要當(dāng)用戶輸入無(wú)匹配指令時(shí)給予一個(gè)引導(dǎo),提供一個(gè)默認(rèn)的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));//前兩個(gè)是編譯器相關(guān)路徑信息,可以忽略 let cmd = args._[0] || 'help'; if(args.v || args.version){ cmd = 'version';//查詢版本優(yōu)先! } 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('今天天氣不錯(cuò)呢,暖心悅目!'); console.log(`${posotion.timezone_offset}時(shí)區(qū),${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}時(shí)區(qū),${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(`你輸入的命令無(wú)效:${cmd}`) loading.stop(); } }
發(fā)布
發(fā)布至npm倉(cāng)庫(kù)之后 可以直接以npm i -g weather全局方式安裝我們發(fā)布的cli,并在任何地方輸入weather命令查詢天氣了喲!
如果不清楚如何發(fā)布可查看我的另一篇文章發(fā)布一款npm包幫助理解npm
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
VsCode與Node.js知識(shí)點(diǎn)詳解
在本篇文章中小編給大家分享了關(guān)于VsCode與Node.js的相關(guān)知識(shí)點(diǎn)以及安裝等內(nèi)容,需要的朋友們可以參考下。2019-09-09node通過(guò)express搭建自己的服務(wù)器
本篇文章主要介紹了node通過(guò)express搭建自己的服務(wù)器 ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09node.js中的fs.readdirSync方法使用說(shuō)明
這篇文章主要介紹了node.js中的fs.readdirSync方法使用說(shuō)明,本文介紹了fs.readdirSync方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12Node.js從字符串生成文件流的實(shí)現(xiàn)方法
這篇文章主要介紹了Node.js從字符串生成文件流的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Nodejs使用archiver-zip-encrypted庫(kù)加密壓縮文件時(shí)報(bào)錯(cuò)(解決方案)
這篇文章主要介紹了Nodejs使用archiver-zip-encrypted庫(kù)加密壓縮文件時(shí)報(bào)錯(cuò),朋友朋友在測(cè)試過(guò)程中都出現(xiàn)過(guò)異常,下面小編把問(wèn)題過(guò)程分析腳本之家平臺(tái),需要的朋友可以參考下2019-11-11在Node.js中使用Express框架和Mongoose庫(kù)實(shí)現(xiàn)視頻評(píng)論功能
本文我們將詳細(xì)介紹如何在Node.js應(yīng)用中使用Express框架和Mongoose庫(kù)來(lái)實(shí)現(xiàn)一個(gè)視頻評(píng)論功能,這個(gè)功能允許用戶對(duì)視頻內(nèi)容添加評(píng)論,并將評(píng)論數(shù)實(shí)時(shí)更新,以下是逐步的實(shí)現(xiàn)過(guò)程,包括代碼示例和說(shuō)明,需要的朋友可以參考下2024-04-04node.js實(shí)現(xiàn)多圖片上傳實(shí)例
這篇文章主要介紹了node.js實(shí)現(xiàn)多圖片上傳實(shí)例,包括路由、控制器和視圖的源碼,重點(diǎn)在圖片上傳處理程序,需要的朋友可以參考下2014-06-06解決node終端下運(yùn)行js文件不支持ES6語(yǔ)法
這篇文章主要介紹了解決node終端下運(yùn)行js文件不支持ES6語(yǔ)法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04