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