欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

仿vue-cli搭建屬于自己的腳手架的方法步驟

 更新時(shí)間:2019年04月17日 11:50:05   作者:尤水就下也  
這篇文章主要介紹了仿vue-cli搭建屬于自己的腳手架的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

腳手架是啥

從前我總覺得腳手架是個(gè)很高大上的東西,好像得牛叉:ox:一點(diǎn)的人才寫的出來,可望而不可即。其實(shí)并不是因?yàn)槔щy使我們放棄,而是因?yàn)榉艞壊棚@得困難(這是個(gè)好詞好句:see_no_evil:)。只要你肯花個(gè)一天半天的時(shí)間:fist:,也能寫出屬于你自己的腳手架。

早前腳手架這個(gè)詞是從 vue-cli 這里認(rèn)識的,我們通過 npm install -g vue-cli 命令全局安裝腳手架后, 再執(zhí)行 vue init webpack project-name 就能初始化好一個(gè)自己的項(xiàng)目,真是尼瑪?shù)纳衿?hushed:。但你有沒有想過為什么我們執(zhí)行 vue init 這個(gè)命令就能有個(gè)自己的項(xiàng)目呢。今天,就讓我們一起來揭開廬山真面目吧!

等等:hand:,扯了一堆,你好像還沒說下啥是腳手架?emmm... 它就是個(gè)工具,方便我們新建項(xiàng)目用的,有了這個(gè)項(xiàng)目我們就能直接開發(fā)了。其實(shí)我們本可以用 git clone url 來新建(復(fù)制)項(xiàng)目,再 cuo 一點(diǎn)的方法就是復(fù)制粘貼整個(gè)文件夾,一樣也能達(dá)到初始化的目的。腳手架的本質(zhì)也是從遠(yuǎn)程下載一個(gè)模板來進(jìn)行一個(gè)新項(xiàng)目。額。所以。。。有什么不同呢?就高大上啊:anguished:。當(dāng)然不止于此啦,腳手架可是高級版的克隆,它主要是提供了交互式的命令讓我們可以動態(tài)的更改模板,然后用一句命令就可以一勞永逸了(當(dāng)然還是要維護(hù)的),這應(yīng)該是最主要的區(qū)別吧,反正現(xiàn)在我是這么想的:cry:。

好了,本章的目的就是帶領(lǐng)大家寫一個(gè)簡易版的腳手架 xr-cli(名字愛取啥取啥),目標(biāo)是實(shí)現(xiàn)一個(gè) xr init template-name project-name 這樣的命令,廢話少說,開始進(jìn)入正題吧:rocket::rocket::rocket:。

源碼地址: https://github.com/lgq627628/xr-cli

前置知識

其實(shí)一個(gè)簡易版的 xr-cli 的代碼量并不多,所以這里我們先來小小介紹一下其中要依賴的包,如果你用過這些工具可以跳過,沒用過的請務(wù)必一定要瞟一眼。

commander

這是用來編寫指令和處理命令行的,具體用法如下:

const program = require("commander");
// 定義指令
program
 .version('0.0.1')
 .command('init', 'Generate a new project from a template')
 .action(() => {
 // 回調(diào)函數(shù)
 })
// 解析命令行參數(shù)
program.parse(process.argv);

回憶一下,我們曾用過的 vue init 的命令就是這樣聲明的。

inquirer

這是個(gè)強(qiáng)大的交互式命令行工具,具體用法如下:

const inquirer = require('inquirer');
inquirer
 .prompt([
 // 一些交互式的問題
 ])
 .then(answers => {
 // 回調(diào)函數(shù),answers 就是用戶輸入的內(nèi)容,是個(gè)對象
 });

想象一下我們用 vue init webpack project-name 之后是不是會有幾個(gè)交互問題,問你文件名啊、作者啊、描述啊、要不要用 eslint 啊等等之類的,就是用這個(gè)來寫的。

chalk

這是用來修改控制臺輸出內(nèi)容樣式的,比如顏色啊,具體用法如下:

const chalk = require('chalk');
console.log(chalk.green('success'));
console.log(chalk.red('error'));

ora

這是一個(gè)好看的加載,就是你下載的時(shí)候會有個(gè)轉(zhuǎn)圈圈的那種效果,用法如下:

const ora = require('ora')
let spinner = ora('downloading template ...')
spinner.start()

download-git-repo

看名字很明顯了,這是用來下載遠(yuǎn)程模板的,支持 GitHub、 GitLab 和 Bitbucket 等,用法如下:

const download = require('download-git-repo')
download(repository, destination, options, callback)

其中 repository 是遠(yuǎn)程倉庫地址;destination 是存放下載的文件路徑,也可以直接寫文件名,默認(rèn)就是當(dāng)前目錄;options 是一些選項(xiàng),比如 { clone:boolean } 表示用 http download 還是 git clone 的形式下載。

目錄搭建

ok,有了上面的知識儲備之后,我們就正式開始擼了。

首先我們要創(chuàng)建一個(gè)文件夾,并取名叫 xr-cli;

在該目錄下執(zhí)行 npm init 命令(你應(yīng)該有安裝 node 吧:joy:),一路回車,就會生成一個(gè)生成 package.json 文件,在 package.json 里面寫入以下依賴并執(zhí)行 npm install 安裝,如下:

"dependencies": {
 "chalk": "^2.4.2",
 "commander": "^2.19.0",
 "download-git-repo": "^1.1.0",
 "inquirer": "^6.2.2",
 "ora": "^3.2.0"
}

新建一個(gè) bin 文件夾,并在 bin 目錄下新建一個(gè)無后綴名的 xr 文件,并寫上:

#!/usr/bin/env node
console.log('hello');

這個(gè)文件就是我們整個(gè)腳手架的入口文件,我們用 node ./bin/xr 運(yùn)行一下,就能在控制臺打印出 hello,如下圖:

這里要注意開頭的 #!/usr/bin/env node

這個(gè)語句必須加上,主要是為了讓系統(tǒng)看到這一行的時(shí)候,會沿著該路徑去查找 node 并執(zhí)行,主要是為了兼容 Mac ,確??蓤?zhí)行。

bin 目錄初始化

當(dāng)前,bin 目錄下就只有一個(gè)文件,就是入口文件 xr。所以現(xiàn)在我們先來編寫這個(gè)文件,由于內(nèi)容較少,我們直接看代碼:

#!/usr/bin/env node
const program = require('commander')

// 定義當(dāng)前版本
// 定義使用方法
// 定義四個(gè)指令
program
 .version(require('../package').version)
 .usage('<command> [options]')
 .command('add', 'add a new template')
 .command('delete', 'delete a template')
 .command('list', 'list all the templates')
 .command('init', 'generate a new project from a template')
 
// 解析命令行參數(shù)
program.parse(process.argv)

這個(gè)文件的主要作用就是定義指令,現(xiàn)在我們用 node ./bin/xr 運(yùn)行一下,就能看到如下結(jié)果:

當(dāng)然,你可能會覺得每次輸入 node ./bin/xr

這個(gè)命令有點(diǎn)麻煩,沒關(guān)系,我們可以在 package.json 里面寫入已下內(nèi)容:

// bin 用來指定每個(gè)命令所對應(yīng)的可執(zhí)行文件的位置
"bin": {
 "xr": "bin/xr"
}

然后在根目錄下執(zhí)行 npm link (就是把命令掛載到全局的意思),這樣我們每次只要輸入 xr,就可以直接運(yùn)行了,so cool,就像下面這樣:

是不是好像有點(diǎn)樣子了呢:grin::grin::grin:,那就讓我們繼續(xù)完善下 bin 目錄吧!ok,讓我們在 bin 目錄下再新建四個(gè)文件,分別對應(yīng)上面的四個(gè)指令,然后分別處理四個(gè)指令要做的事情,如下圖:

同樣的,我們修改一下 package.json 里面的 bin 內(nèi)容,如下:

"bin": {
 "xr": "bin/xr",
 "xr-add": "bin/xr-add",
 "xr-delete": "bin/xr-delete",
 "xr-list": "bin/xr-list",
 "xr-init": "bin/xr-init"
}

然后執(zhí)行 npm unlink 解綁全局命令,再執(zhí)行 npm link 重新把命令綁定到全局,就像下面這樣:

最后順便在根目錄下新建一個(gè) template.json 文件,里面的內(nèi)容就是一個(gè) {}。

編寫具體指令

好了,一切準(zhǔn)備就緒,接下來就讓我們來寫下具體的四個(gè)指令吧。

xr-add

這個(gè)內(nèi)容也是比較少,直接看代碼:

#!/usr/bin/env node

// 交互式命令行
const inquirer = require('inquirer')
// 修改控制臺字符串的樣式
const chalk = require('chalk')
// node 內(nèi)置文件模塊
const fs = require('fs')
// 讀取根目錄下的 template.json
const tplObj = require(`${__dirname}/../template`)

// 自定義交互式命令行的問題及簡單的校驗(yàn)
let question = [
 {
 name: "name",
 type: 'input',
 message: "請輸入模板名稱",
 validate (val) {
  if (val === '') {
  return 'Name is required!'
  } else if (tplObj[val]) {
  return 'Template has already existed!'
  } else {
  return true
  }
 }
 },
 {
 name: "url",
 type: 'input',
 message: "請輸入模板地址",
 validate (val) {
  if (val === '') return 'The url is required!'
  return true
 }
 }
]

inquirer
 .prompt(question).then(answers => {
 // answers 就是用戶輸入的內(nèi)容,是個(gè)對象
 let { name, url } = answers;
 // 過濾 unicode 字符
 tplObj[name] = url.replace(/[\u0000-\u0019]/g, '')
 // 把模板信息寫入 template.json 文件中
 fs.writeFile(`${__dirname}/../template.json`, JSON.stringify(tplObj), 'utf-8', err => {
  if (err) console.log(err)
  console.log('\n')
  console.log(chalk.green('Added successfully!\n'))
  console.log(chalk.grey('The latest template list is: \n'))
  console.log(tplObj)
  console.log('\n')
 })
 })

這個(gè)文件主要目的就是添加模板并存儲起來,上面的注釋應(yīng)該都寫的挺清楚了。我們執(zhí)行 xr add 來看看效果:

這里的模板名稱(自己隨便?。┫喈?dāng)于 vue init webpack project-name 當(dāng)中的 webpack

;模板地址要注意一下,像下面這樣寫就可以,這里以 github 為例:

xr-delete

如果你理解了上面的那個(gè)步驟,這步對你來說應(yīng)該也是灑灑水啦!上代碼:

#!/usr/bin/env node

const inquirer = require('inquirer')
const chalk = require('chalk')
const fs = require('fs')
const tplObj = require(`${__dirname}/../template`)

let question = [
 {
 name: "name",
 message: "請輸入要刪除的模板名稱",
 validate (val) {
  if (val === '') {
  return 'Name is required!'
  } else if (!tplObj[val]) {
  return 'Template does not exist!'
  } else {
  return true
  }
 }
 }
]

inquirer
 .prompt(question).then(answers => {
 let { name } = answers;
 delete tplObj[name]
 // 更新 template.json 文件
 fs.writeFile(`${__dirname}/../template.json`, JSON.stringify(tplObj), 'utf-8', err => {
  if (err) console.log(err)
  console.log('\n')
  console.log(chalk.green('Deleted successfully!\n'))
  console.log(chalk.grey('The latest template list is: \n'))
  console.log(tplObj)
  console.log('\n')
 })
 })

應(yīng)該很好理解,就不過多解釋了,我們直接執(zhí)行 xr delete 看下效果:

xr-list

這個(gè)更簡單了,兩行代碼搞定:

#!/usr/bin/env node

const tplObj = require(`${__dirname}/../template`)
console.log(tplObj)

是不是簡單到爆:boom:。我們執(zhí)行 xr list 看看效果:

因?yàn)閯偛乓惶砑右粍h除,所以目前沒有模板,就輸出 {}。

xr-init

這應(yīng)該是最主要(但不難)的一步了,畢竟我們寫到現(xiàn)在還沒有通過命令初始化過一個(gè)項(xiàng)目呢:sob:。所以這步的重點(diǎn)就是執(zhí)行 download 方法,并傳入相應(yīng)參數(shù),具體看代碼:

#!/usr/bin/env node

const program = require('commander')
const chalk = require('chalk')
const ora = require('ora')
const download = require('download-git-repo')
const tplObj = require(`${__dirname}/../template`)

program
 .usage('<template-name> [project-name]')
program.parse(process.argv)
// 當(dāng)沒有輸入?yún)?shù)的時(shí)候給個(gè)提示
if (program.args.length < 1) return program.help()

// 好比 vue init webpack project-name 的命令一樣,第一個(gè)參數(shù)是 webpack,第二個(gè)參數(shù)是 project-name
let templateName = program.args[0]
let projectName = program.args[1]
// 小小校驗(yàn)一下參數(shù)
if (!tplObj[templateName]) {
 console.log(chalk.red('\n Template does not exit! \n '))
 return
}
if (!projectName) {
 console.log(chalk.red('\n Project should not be empty! \n '))
 return
}

url = tplObj[templateName]

console.log(chalk.white('\n Start generating... \n'))
// 出現(xiàn)加載圖標(biāo)
const spinner = ora("Downloading...");
spinner.start();
// 執(zhí)行下載方法并傳入?yún)?shù)
download (
 url,
 projectName,
 err => {
 if (err) {
  spinner.fail();
  console.log(chalk.red(`Generation failed. ${err}`))
  return
 }
 // 結(jié)束加載圖標(biāo)
 spinner.succeed();
 console.log(chalk.green('\n Generation completed!'))
 console.log('\n To get started')
 console.log(`\n cd ${projectName} \n`)
 }
)

ok,我們執(zhí)行一下 xr init simple test ,記得先執(zhí)行一下 xr add

現(xiàn)在我們就可以在左側(cè)的目錄中看到 test 項(xiàng)目了,如下圖:

至此,一個(gè)小小的腳手架就做完了。:rose::rose::rose:此處應(yīng)該有鮮花和掌聲:clap::clap::clap:

發(fā)布到 npm

既然以上命令都執(zhí)行成功了,那接下來我們就把它發(fā)布到 npm 上吧(寫都寫了,不能浪費(fèi):grimacing:)。

  • 刪除 test 文件夾,它就本地測試用的,用完就拋棄它(當(dāng)然做人不能這樣)
  • 在根目錄下新建 README.md 文件,隨便寫點(diǎn)使用說明,假裝正經(jīng)一下
  • 在根目錄下新建 .npmignore 文件,并寫入 /node_modules ,意思就是發(fā)布的時(shí)候忽略 node_modules 文件夾,
  • 去 npm 官網(wǎng)注冊個(gè)賬號(很簡單的),同時(shí)搜索一下 xr-cli 這個(gè)名字,看看有沒有人用,有的話就換一個(gè)羅

現(xiàn)在讓我們回到項(xiàng)目根目錄,執(zhí)行 npm login 登入 npm 賬號,再執(zhí)行 npm publish 發(fā)布,就像下面這樣:

沒錯(cuò),就是這樣兩個(gè)簡單的命令,我們就發(fā)布成功啦,真是可喜可賀:beer::beer::beer:。大概過一分鐘左右(反正挺快的),我們再去 npm 官網(wǎng)搜下 xr-cli,就可以看到自己的腳手架啦,哈哈哈哈,賊開心:+1::+1::+1:。

這里補(bǔ)充說明一點(diǎn):根據(jù)規(guī)范,只有在發(fā)包的24小時(shí)內(nèi)才允許撤銷發(fā)布的包,所以為了不污染 npm 網(wǎng)站,如果只是測試的話就執(zhí)行 npm unpublish --force 刪除吧,畢竟我們都是有素質(zhì)的人。

小試牛刀

別急,還沒有結(jié)束:no_good:‍♀️。發(fā)都發(fā)出去了,怎么也得驗(yàn)證一波撒。嗯,說的有道理,無法反駁,那就趕緊驗(yàn)收吧!這里我們記得先用 npm unlink 解綁一下命令,不然會相互影響。下面我們打開終端,輸入 npm i xr-cli -g 全局安裝一下腳手架,然后執(zhí)行 xr ,如果出現(xiàn)下圖中的模樣就說明已經(jīng)安裝成功了。

接下來進(jìn)入到桌面,執(zhí)行 xr init simple xr-test,不一會就可以在桌面上看到自己的項(xiàng)目啦。

:six::six::six:,大贊無疆,大。。贊。。。無疆?。?!

結(jié)語

上面的操作只要你熟悉了幾遍之后,再去看看vue-cli 的源碼結(jié)構(gòu),你就會有種撥開云霧見月明的感覺(它只是比我們這個(gè)腳手架完善很多很多很多而已:sob::sob::sob:)。

當(dāng)然了,這只是渣渣版本。你可以往里面添加更多的東西,比如自動化構(gòu)建和動態(tài)模板?。ㄆ鋵?shí)動態(tài)模板是個(gè)大頭),然后嘗試寫下更多更好的交互和功能,這樣你就也能擁有一個(gè)屬于自己的腳手架啦,心動不如行動,還等什么呢,不要998,只要有鍵盤,趕緊敲吧同志們,Let's go!:rainbow:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • element-ui中dialog彈窗關(guān)閉按鈕失效的解決

    element-ui中dialog彈窗關(guān)閉按鈕失效的解決

    這篇文章主要介紹了element-ui中dialog彈窗關(guān)閉按鈕失效的解決,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 一步一步實(shí)現(xiàn)Vue的響應(yīng)式(對象觀測)

    一步一步實(shí)現(xiàn)Vue的響應(yīng)式(對象觀測)

    這篇文章主要介紹了一步一步實(shí)現(xiàn)Vue的響應(yīng)式(對象觀測),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Vue中實(shí)現(xiàn)滾動加載與無限滾動

    Vue中實(shí)現(xiàn)滾動加載與無限滾動

    本文主要介紹了Vue中實(shí)現(xiàn)滾動加載與無限滾動,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Vue實(shí)現(xiàn)英文字母大小寫在線轉(zhuǎn)換功能

    Vue實(shí)現(xiàn)英文字母大小寫在線轉(zhuǎn)換功能

    在Web開發(fā)中,字符串處理是常見的需求之一,特別是在國際化應(yīng)用中,對于文本的格式化處理尤為重要,本文將介紹如何使用Vue.js來構(gòu)建一個(gè)簡單的在線英文字母大小寫轉(zhuǎn)換工具,需要的朋友可以參考下
    2024-09-09
  • vue 內(nèi)置過濾器的使用總結(jié)(附加自定義過濾器)

    vue 內(nèi)置過濾器的使用總結(jié)(附加自定義過濾器)

    這篇文章主要介紹了vue 內(nèi)置過濾器的使用總結(jié)(附加自定義過濾器),詳細(xì)的介紹了各種過濾器的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • 2023年最新的vue.js下載和安裝的3種方法詳解

    2023年最新的vue.js下載和安裝的3種方法詳解

    這篇文章主要介紹了2023年最新的vue.js下載和安裝的3種方法,每種方法結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • vue中路由驗(yàn)證和相應(yīng)攔截的使用詳解

    vue中路由驗(yàn)證和相應(yīng)攔截的使用詳解

    這篇文章主要為大家詳細(xì)介紹了vue中路由驗(yàn)證和相應(yīng)攔截的使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Vue中全局變量的定義和使用

    Vue中全局變量的定義和使用

    這篇文章主要介紹了vue中全局變量的定義和使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-06-06
  • vue的滾動條插件實(shí)現(xiàn)代碼

    vue的滾動條插件實(shí)現(xiàn)代碼

    這篇文章主要介紹了vue的滾動條插件實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • VUE解決微信簽名及SPA微信invalid signature問題(完美處理)

    VUE解決微信簽名及SPA微信invalid signature問題(完美處理)

    這篇文章主要介紹了VUE解決微信簽名及SPA微信invalid signature問題(完美處理),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03

最新評論