仿vue的前端自定义cmd命令拉取项目脚手架
原文地址:https://github.com/screetBloo...
含純node或者commander實(shí)現(xiàn)自己的前端腳手架
文章碼字分享不易,希望如果幫到您的話,幫忙github點(diǎn)個(gè)star
腳手架
這里主要講的是如何自定義node命令,拉取項(xiàng)目
snowcat init // 用戶安裝我們的命令,就可以一行代碼拉取對(duì)應(yīng)項(xiàng)目,可擴(kuò)展成根據(jù)不同命令拉取不同終端模板1.腳手架的實(shí)現(xiàn)
腳手架作用: 快速搭建一個(gè)我們預(yù)定義好的模板項(xiàng)目結(jié)構(gòu)
我們這里就做了兩件事(已經(jīng)滿足了我目前的需求,可以繼續(xù)拓展):
- 1.自定義nodejs命令
- 2.在nodejs中執(zhí)行shell命令(通俗說(shuō)的命令行命令),拉取模板項(xiàng)目到本地
1.1 導(dǎo)言
我們平時(shí)經(jīng)常會(huì)使用vue、angular、react等的腳手架,都可以達(dá)到如下效果
// 1. 全局安裝對(duì)應(yīng)的腳手架 "xxx-cli" (不全局安裝的話,只能在當(dāng)前安裝包下使用) npm install -g xxx-cli// 2. 接下來(lái)直接就如"vue init"就可以直接拉取一個(gè)模板項(xiàng)目到我們的當(dāng)前文件夾 vue init這個(gè)效果挺好用的,假如我積累了一套框架,我不想每次重開(kāi)項(xiàng)目都拷貝到其他文件夾來(lái)用;當(dāng)別人需要的時(shí)候,別人又要從我這拷貝一份;或者是我每次都給別人一串別人基本記不住的git的url鏈接,這個(gè)太麻煩了
我希望能有一套腳手架,能像這些成熟的框架的腳手架一樣直接把我想要的模板項(xiàng)目用最簡(jiǎn)短而有效的命令拉取到任何我想要獲取的電腦的文件夾中,再有需要了,我還能繼續(xù)拓展
本地效果演示:
其它機(jī)器上演示:
1.2 腳手架具體實(shí)現(xiàn)過(guò)程
先上組織結(jié)構(gòu)和代碼(結(jié)合思路和代碼如果你已經(jīng)懂了,省的還向下看),再?gòu)牧汩_(kāi)始講實(shí)現(xiàn)方式和原理
1.1.1 0.0.1版本腳手架組織結(jié)構(gòu)
1.1.2 實(shí)現(xiàn)0.0.1版本腳手架的完整代碼
snowcat.js ==> 腳手架定義的所有命令的入口,這里暫時(shí)只有init命令
#!/usr/bin/env node 'use strict' const program = require('commander') program.version(require('../package').version )program.command('init').description('pull a new project').alias('i').action(() => {require('../command/init')()})program.parse(process.argv)if(!program.args.length){program.help() }init.js ==> init 命令的定義文件
'use strict' const exec = require('child_process').exec const projectUrl = 'https://github.com/screetBloom/wecat.js.git'module.exports = () => {console.log('this is my first commander >>>>>> ')let cmdStr = `git clone `+projectUrlexec(cmdStr, (error, stdout, stderr) => {if (error) {console.log(error)process.exit()}console.log('pull我們的項(xiàng)目已經(jīng)成功了')process.exit()})}package.json ==> 在package.json文件中聲明整個(gè)文件包的可執(zhí)行文件的位置
"bin": {"snowcat": "bin/snowcat.js"}1.1.3 實(shí)現(xiàn)思路
上述的3個(gè)文件主要完成了2個(gè)最基本的事情
- 1.自定義nodejs命令。在nodejs原本肯定是沒(méi)有"snowcat"這種命令的,這個(gè)是我們自定義的
- 2.用nodejs執(zhí)行shell命令(通俗講的命令行命令),這里主要是執(zhí)行了git clone
那么我們現(xiàn)在先來(lái)嘗試一下,如何自定義nodejs命令
在這里我們需要引入一個(gè)"commander.js"的npm包
先說(shuō)明:不引入任何包都是可以完成我們上述的兩件事,引入的主要原因有2個(gè)
- 1.有了這個(gè)npm包,可以簡(jiǎn)化我們命令行的開(kāi)發(fā),把我們主要精力還是回歸到框架開(kāi)發(fā)上
- 2.commander有大量的api,我們目前只是0.0.1版本,不依賴任何包來(lái)實(shí)現(xiàn)都是沒(méi)有問(wèn)題的,以后高版本1.0.0的拓展還是要用它的,這里我直接和大家說(shuō)一下,也可以熟悉一下它的使用
我在這里補(bǔ)充一下不用任何依賴包的實(shí)現(xiàn)方式:
// PS.在nodejs中,可以直接用nodejs內(nèi)置的全局變量process獲取到你輸入的命令的參數(shù) // 現(xiàn)在我們直接就可以利用 process.argv來(lái)獲取,如定義snowcat.js文件如下: #!/usr/bin/env node let run= function (para) {if(para[0] === '-test'){console.log('version is 1.0.0');}if(para[1] === '-host'){console.log('127.0.0.1');} };console.log(process.argv) run(process.argv.slice(2));頂部的"#!/usr/bin/env node"的意思是 顯式的聲明這個(gè)文件用node來(lái)執(zhí)行
執(zhí)行snowcat.js文件
這里我想告訴大家的就是process.argv,這個(gè)東西很關(guān)鍵,可以拿到用戶輸入的命令,然后你就可以根據(jù)輸入執(zhí)行對(duì)應(yīng)的函數(shù)就行了
先把 console.log(process.argv)注釋了, 再來(lái)自定義指令試一試
node snowcat.js -test /* 輸出如下: version is 1.0.0 */ node snowcat.js -host/*輸出如下:127.0.0.1*/我寫這個(gè)demo主要表示現(xiàn)在我們就可以直接根據(jù)參數(shù)來(lái)匹配對(duì)應(yīng)執(zhí)行的函數(shù)了,以上面的init.js文件為例
我們是先利用process.argv.slice(2) 獲取到輸入的參數(shù),匹配一下執(zhí)行對(duì)應(yīng)的函數(shù)就行;純node.js實(shí)現(xiàn)
argv返回的是一個(gè)不定長(zhǎng)的數(shù)組,第一個(gè)是node.exe的路徑,第二個(gè)是當(dāng)前文件的路徑,接下來(lái)是你命令后面跟的參數(shù)
nodejs中的process的官方說(shuō)明文檔在這
這里我們就順著這個(gè)繼續(xù)了,commander等等再說(shuō),對(duì)目前的我們來(lái)說(shuō)也沒(méi)到重要要偏說(shuō)不可的地步
有沒(méi)有注意到上面我們都是在js文件所在目錄下直接"node snowcat.js -test"來(lái)執(zhí)行js文件,我們?cè)撊绾沃苯?#34;snowcat -test"就執(zhí)行js文件呢 ,也就是上面我們說(shuō)的自定義nodejs命令
這個(gè)時(shí)候package.json就需要登場(chǎng)了
在里面添加一行
"bin": {"snowcat": "snowcat.js"}這個(gè)是什么意思呢: 簡(jiǎn)單說(shuō)就是把命令名作為key,本地文件名作為value做一個(gè)映射。全局安裝的時(shí)候,npm會(huì)把你定義的這個(gè)命令名"snowcat"對(duì)應(yīng)的可執(zhí)行文件安裝到系統(tǒng)路徑下,達(dá)到全局使用該命令的目的;本地安裝的時(shí)候,會(huì)直接鏈接到'./node_modules/.bin/'
目前的配置信息應(yīng)該基本如下:
{"name": "snowcat","version": "0.0.1","description": "my cli 0.0.1","main": "init.js","bin": {"snowcat": "snowcat.js"},"scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "wim_chen","license": "ISC" }現(xiàn)在我們來(lái)嘗試本地的全局的運(yùn)行 "snowcat" 命令,這里需要用到 "npm link",這里注意:是我們自己全局使用,給別人全局用可以發(fā)布到npm倉(cāng)庫(kù)
// 在當(dāng)前的package.json中輸入該命令 npm link這個(gè)"npm link"主要是在我們本機(jī)的全局的"node_modules"目錄中,生成一個(gè)符號(hào)鏈接"a symbolic link"指向我們當(dāng)前文件夾
又因?yàn)槲覀冊(cè)?strong>package.json中定義了"bin",指出了全局安裝的時(shí)候命令"snowcat"對(duì)應(yīng)的js文件
現(xiàn)在我們?cè)诒緳C(jī)的任何一個(gè)地方輸入"snowcat -test -host"都會(huì)輸出下述結(jié)果:
想要進(jìn)一步的達(dá)到如
npm install -g snowcat // 執(zhí)行我們目前的腳手架 snowcat -test -host現(xiàn)在只需要做如下幾步:
- 1.注冊(cè)一個(gè)npm賬號(hào),點(diǎn)擊https://www.npmjs.com/ 直達(dá)npm官網(wǎng)
- 2.給你的package.json里面的name寫一個(gè)大家都沒(méi)用過(guò)名字(snowcat你是別想了,很明顯已經(jīng)名花有主了)
- 3.在你本地的package.json所在的路徑下輸入:"npm adduser",然后輸入你的用戶名、密碼、郵箱
- 4.輸入 "npm publish"就將你的npm包發(fā)送到了npm倉(cāng)庫(kù)
- 5.找個(gè)好朋友,讓他安裝一下你的包"npm install -g xxx",讓他輸入" snowcat -test -host"就可以打印出你寫好的內(nèi)容了,比如"我愛(ài)你"?
現(xiàn)在我們來(lái)按要求拉取我們的項(xiàng)目,用一開(kāi)始的文件結(jié)構(gòu)舉例
先創(chuàng)建一下對(duì)應(yīng)的文件
首先"npm init"我們的package.json文件,并設(shè)置"commander.js"依賴和合適的bin
{"name": "snowcat","version": "0.0.1","description": "my js cli 0.0.1","main": "index.js","bin": {"snowcat": "bin/snowcat.js"},"dependencies": {"commander": "^2.9.0"},"author": "wim_chen","license": "ISC" }這里先說(shuō)明一下 commander.js的語(yǔ)法
program.command('init') // 命令是 init.description('pull a new project') // 命令的描述.alias('i') // 命令別名,用init和i都行.action(() => {require('../command/init')() // 執(zhí)行init命令時(shí)要做什么,這里是執(zhí)行init文件里導(dǎo)出的函數(shù)})開(kāi)始是編寫我們的命令行入口文件,bin文件夾下的snowcat.js,也很簡(jiǎn)單
// 頭部添加顯示聲明:本文件用node來(lái)執(zhí)行 #!/usr/bin/env node // 嚴(yán)格模式 'use strict' // 引入 commander,用于處理自定義nodejs命令 const program = require('commander') // 引用package.json里面的版本號(hào)來(lái)定義當(dāng)前版本 program.version(require('../package').version )// 定義init命令,同時(shí)定義init命令的簡(jiǎn)化命令 i,包括命令的腳本文件所在路徑 program.command('init').description('pull a new project').alias('i').action(() => {require('../command/init')()})// 這一句必不可少,作用是解析命令行參數(shù)argv,這里的process.argv是nodejs全局對(duì)象的屬性 program.parse(process.argv)// 如果用戶只是輸入了 "snowcat"沒(méi)帶參數(shù),就給他展示他能輸入的所有命令 if(!program.args.length){program.help() }我們先來(lái)試一下,執(zhí)行snowcat命令
node ./bin/snowcat.js顯示如下,就是正確的,說(shuō)明我們commander.js使用的很順利
編寫我們的 init.js
'use strict' // 這個(gè)是node自帶調(diào)用自窗口執(zhí)行shell命令的方法,等會(huì)用 const exec = require('child_process').exec module.exports = () => {console.log('this is my first commander >>>>>> ') }現(xiàn)在我們輸入
node ./bin/snowcat.js init
接下來(lái)我們來(lái)利用git來(lái)拉取我們的項(xiàng)目
編寫init.js
現(xiàn)在我們?cè)佥斎?/p> node ./bin/snowcat.js init
此時(shí)項(xiàng)目已經(jīng)可以正確的拉取下來(lái)了,接下來(lái)我們來(lái)進(jìn)行本地全局安裝,在當(dāng)前的package.json路徑下輸入"npm link"(可以本地全局使用了)
在其它路徑下拉取項(xiàng)目
成功,那么現(xiàn)在我們把它放到npm倉(cāng)庫(kù)里,如果上一次你已經(jīng)放進(jìn)去0.0.1版本了,這次就需要修改版本號(hào)了,操作如下:
最后我們?cè)僭谄渌鼨C(jī)器上測(cè)試
// 全局安裝腳手架 npm install -g snowcat // 拉取預(yù)定義模板 snowcat init
0.0.1版本的腳手架分享到此結(jié)束
總結(jié)
以上是生活随笔為你收集整理的仿vue的前端自定义cmd命令拉取项目脚手架的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 分公司访问列表(ACL)
- 下一篇: stm32 can bus 总结