尤大是如何發布vuejs的,學完可以應用到項目

大家好,我是若川。本文是讀者@NewName 投稿,看了我推薦的vuejs如何發布的源碼(200余行),并成功寫了一個小工具。推薦的當晚看到挺晚,這執行力這努力程度超過很多人啊。我本來是打算自己寫一篇這個文章的,沒想到他寫完了。


前言:第一次看源碼,感謝我川哥提供合適題材,給予細心指導。感覺學習源碼真的很有幫助,我第一次就品嘗到甜頭了,可以借鑒(抄襲)源碼的思想解決實際的問題,真好啊。本人著實菜鳥一枚,也不會寫作,把學習的筆記記錄一下而已。

1. 準備工作和主要精神

1.源碼地址:https://github1s.com/vuejs/vue-next/blob/HEAD/scripts/release.js

2.源碼主旨內容:vuejs 是如何發布

3.要思考學完了可以應用的地方:

1.比如學完這個源碼,優化自己項目的發布流程?
————真有點想法耶:
我們公司目前的前端發版本流程中有許多的git命令?,這些git命令我可以用腳本的方式運行,借鑒源碼中的run方法:
const?run?=?(bin,?args,?opts?=?{})?=>execa(bin,?args,?{?stdio:?'inherit',?...opts?})
目前已經寫了(CV)一個工具腳本,優化了我們公司前端項目發預發布版本的流程,詳見第六部分。

4.讀源碼特別要注意:

先看懂大局呀~?主線是main函數??先看懂大概?然后不懂的再查

2. 從main函數開始看

main 函數中主要代碼梳理一下,總體流程如下圖所示:

先簡單看下 vuejs 發布總體流程

2.1 版本號驗證相關流程 :40 - 77行

40行:獲取版本號

44 -49行 :如果版本號不存在則問是要升級大版本、小版本、 補丁版本 還是自定義

52-59 行 :如果用戶選擇的自定義則獲取自定義的版本

65-67行:檢查版本號是否合法

69-73行:問是否確定要發布版本

55-77: 如果選擇否 main函數執行結束, 返回

2.2 發布之前的測試:80-86行

2.3 更新依賴的版本號:88-90行

2.4 運行build命令 :93-101行

2.5 運行日志命令 :104行

2.6 提交代碼:106-113行

2.7 運行發布命令 :115-119 行

2.8 新的版本push到git:121-125行

2.9 提示跳過更新的包:131-139行

3. 一些變量和函數的定義細節

3.1 發布之前測試:

80-86行:

//如果沒有skipTests 跳過測試?并且沒有 isDryRun(空跑?)則運行測試
step('\nRunning?tests...')if?(!skipTests?&&?!isDryRun)?{//使用jest?,?清除緩存await?run(bin('jest'),?['--clearCache'])//yarn?test?await?run('yarn',?['test',?'--bail'])}?else?{console.log(`(skipped)`)}

3.2 構建所有的包

93—101行:

//其實是運行yarn?build?命令?
await?run('yarn',?['build',?'--release'])

3.3 運行日志命令

104行:運行 yarn 的log命令

await?run(`yarn`,?['changelog'])
//changelog定義在package.json 的 npm scripts 中:
"changelog":?"conventional-changelog?-p?angular?-i?CHANGELOG.md?-s",//這里使用到了conventional-changelog,見第五部分:使用的依賴

3.4 提交代碼

106-113行:git版本管理相關

//判斷文件是否有變化,如果有變化則提交到git
const?{?stdout?}?=?await?run('git',?['diff'],?{?stdio:?'pipe'?})if?(stdout)?{step('\nCommitting?changes...')await?runIfNotDry('git',?['add',?'-A'])await?runIfNotDry('git',?['commit',?'-m',?`release:?v${targetVersion}`])}?else?{console.log('No?changes?to?commit.')}

3.5 運行發布命令

115-119行: 發布

//?publish?packagesstep('\nPublishing?packages...')for?(const?pkg?of?packages)?{await?publishPackage(pkg,?targetVersion,?runIfNotDry)}
//publishPackage的定義在175-230行:
async?function?publishPackage(pkgName,?version,?runIfNotDry)?{//?如果某個包要跳過則直接返回if?(skippedPackages.includes(pkgName))?{return}//獲取路徑和內容const?pkgRoot?=?getPkgRoot(pkgName)const?pkgPath?=?path.resolve(pkgRoot,?'package.json')const?pkg?=?JSON.parse(fs.readFileSync(pkgPath,?'utf-8'))//如果是私有的則返回if?(pkg.private)?{return}//?For?now,?all?3.x?packages?except?"vue"?can?be?published?as//?`latest`,?whereas?"vue"?will?be?published?under?the?"next"?tag.//?定義一下發布的標記?(打tag)let?releaseTag?=?nullif?(args.tag)?{releaseTag?=?args.tag}?else?if?(version.includes('alpha'))?{releaseTag?=?'alpha'}?else?if?(version.includes('beta'))?{releaseTag?=?'beta'}?else?if?(version.includes('rc'))?{releaseTag?=?'rc'}?else?if?(pkgName?===?'vue')?{//?TODO?remove?when?3.x?becomes?defaultreleaseTag?=?'next'}//?TODO?use?inferred?release?channel?after?official?3.0?release//?const?releaseTag?=?semver.prerelease(version)[0]?||?null//?執行發布:?運行yarn的發布命令step(`Publishing?${pkgName}...`)try?{await?runIfNotDry('yarn',['publish','--new-version',version,...(releaseTag???['--tag',?releaseTag]?:?[]),'--access','public'],{cwd:?pkgRoot,stdio:?'pipe'})console.log(chalk.green(`Successfully?published?${pkgName}@${version}`))}?catch?(e)?{if?(e.stderr.match(/previously?published/))?{console.log(chalk.red(`Skipping?already?published:?${pkgName}`))}?else?{throw?e}}
}

3.6 更新依賴的細節

88-90: 更新所有的依賴

updateVersions(targetVersion)
//updateVersions?是定義的一個更新版本的函數,里面調用了?updatePackage函數
function?updateVersions(version)?{//?1.?update?root?package.jsonupdatePackage(path.resolve(__dirname,?'..'),?version)//?2.?update?all?packagespackages.forEach(p?=>?updatePackage(getPkgRoot(p),?version))
}
//packages的定義在第16行;
//updatePackag在157行:大概意思是找到路徑下的package.json文件然后讀取文件內容,轉成對象,更新版本,再寫回文件。
function?updatePackage(pkgRoot,?version)?{const?pkgPath?=?path.resolve(pkgRoot,?'package.json')const?pkg?=?JSON.parse(fs.readFileSync(pkgPath,?'utf-8'))pkg.version?=?versionupdateDeps(pkg,?'dependencies',?version)updateDeps(pkg,?'peerDependencies',?version)fs.writeFileSync(pkgPath,?JSON.stringify(pkg,?null,?2)?+?'\n')
}
//這里用到的updateDeps在 159-173行定義:
function?updateDeps(pkg,?depType,?version)?{const?deps?=?pkg[depType]if?(!deps)?returnObject.keys(deps).forEach(dep?=>?{//大概含義是檢查依賴,如果其中有vue則提示并且替換版本。if?(dep?===?'vue'?||(dep.startsWith('@vue')?&&?packages.includes(dep.replace(/^@vue\//,?''))))?{console.log(chalk.yellow(`${pkg.name}?->?${depType}?->?${dep}@${version}`))deps[dep]?=?version}})
}

4. 總體的流程總結回顧

main 函數中主要代碼梳理一下,總體流程如下圖所示:

先簡單看下 vuejs 發布總體流程

5. 使用的依賴

5.1 minimist

const?args?=?require('minimist')(process.argv.slice(2))

minimist輕量級的命令行參數解析引擎

https://blog.csdn.net/fangxuan1509/article/details/107469465

https://www.npmjs.com/package/minimist

5.2 chalk

const?chalk?=?require('chalk')

chalk是一個顏色的插件

https://blog.csdn.net/sqrtsix/article/details/76615630

https://www.npmjs.com/package/chalk

5.3 semver

const?semver?=?require('semver')

Semver是一個專門分析Semantic Version(語義化版本)的工具,“semver”其實就是這兩個單詞的縮寫。Npm使用了該工具來處理版本相關的工作。

語義化版本掃盲 ?https://segmentfault.com/a/1190000014405355

https://www.npmjs.cn/misc/semver/

5.4 enquirer

const?{?prompt?}?=?require('enquirer')

命令行提示的?

https://www.npmjs.com/package/enquirer

5.5 execa

const?execa?=?require('execa')

execa是可以調用shell和本地外部程序的javascript封裝。會啟動子進程執行。支持多操作系統,包括windows。如果父進程退出,則生成的全部子進程都被殺死。

http://abloz.com/tech/2018/08/21/nodejs-execa/

https://www.npmjs.com/package/execa

5.6 yarn的相關命令

https://yarn.bootcss.com/docs/getting-started/

5.7 conventional-changelog

在約定式提交的基礎上來自動生成changelog

https://blog.csdn.net/weixin_34326179/article/details/91382865

https://www.npmjs.com/package/conventional-changelog

6. 應用:優化發“預發布版本”的流程

6.1 問題描述

“預發布版本”是我們發正式版本之前的一個驗證版本,目前我們公司前端項目發“預發布版本”的時候要通過如下圖所示的流程,這里面有很多操作git的命令,受閱讀源碼啟發,我想寫一個工具腳本,把這些命令變成自動執行的方式,需要的信息只需要開發者輸入或者選擇即可。

其中生成tag的時候需要根據tag命名規范來生成。下圖中 12 為固定值 ,20代表年份,30代表是一年中的第幾周,01代表第幾次發版。

6.2 解決方案

所以我需要寫的腳本中就需要做這幾件事情:

(1)要獲取當前年份,當前第幾周:這兩個值用JS基本代碼就ok,

(2)需要和開發者交互獲取第幾次發版和服務名:可以使用 release.js 中使用的 依賴:enquirer;

(3)需要運行git命令:release.js 中使用的 依賴:execa,以及定義的 run()方法。

(4)如果控制臺中要高亮提示信息則使用依賴:chalk ,當然這個是可選的

6.3 具體實現

6.3.1 首先項目根目錄下新建scripts文件夾,然后新建 release.js文件

6.3.2 安裝依賴

npm?install?chalk?--save-dev?
npm?install?execa?--save-dev?
npm?install?enquirer?--save-dev?

6.3.3 寫代碼

const?chalk?=?require('chalk')
const?execa?=?require('execa')
const?{prompt
}?=?require('enquirer')const?step?=?msg?=>?console.log(chalk.cyan(msg))const?run?=?(bin,?args,?opts?=?{})?=>execa(bin,?args,?{stdio:?'inherit',...opts})async?function?main()?{console.log('歡迎使用發版小助手腳本')step('\n驗證是否提交代碼...')const?{?yes?}?=?await?prompt({type:?'confirm',name:?'yes',message:?`確定已經提交代碼并將代碼push到develop分支了嗎?`})if?(!yes)?{return}//?切換到?develop?分支,拉取最新代碼await?run('git',?['checkout',?'develop'])await?run('git',?['pull',?'origin',?'develop'])//?切換到?release?分支,拉取最新代碼await?run('git',?['checkout',?'release'])await?run('git',?['pull',?'origin',?'release'])//?本地?release?分支合并?develop?分支代碼await?run('git',?['merge',?'develop'])//?合并完成后,推送到遠程?release?分支await?run('git',?['push',?'origin',?'release'])//?以下邏輯為拼寫tag號,打tag用//?獲取當前年份后兩位const?yearLastTwoBit?=?getLastTwoBitYear()console.log(yearLastTwoBit)//?獲取當前是一年中的第幾周const?currentWeek?=?theWeek()console.log(currentWeek)//?本次的版本號const?targetVersion?=?(await?prompt({type:?'input',name:?'version',message:?'這次是本周第幾次發版?(請輸入數字)',})).versionconsole.log(targetVersion)//?前端服務名字const?serviceName?=?(await?prompt({type:?'input',name:?'serviceName',message:?'請輸入這個前端服務名字?(例如 fe_beg)',})).serviceNameconsole.log(serviceName)//?拼接tag名?const?tagName?=?`Cloud_R-12.${yearLastTwoBit}.${currentWeek}.${targetVersion?>?10???targetVersion?:?`0${targetVersion}`}-${serviceName}`//?拼接注釋const?comment?=?`${serviceName}服務${currentWeek}周/迭代第${targetVersion}次版本發布`//?本地打?Tag,生成版本await?run('git',?['tag',?tagName,?'-m',?comment])//?推送?Tag?到遠程代碼庫,觸發構建await?run('git',?['push',?'--tags'])console.log('稍等片刻,即可完成預發布環境版本發布,詳細查看Jenkins')//?重新切換到develop分支await?run('git',?['checkout',?'develop'])
}//?獲取當前年份后兩位
function?getLastTwoBitYear()?{const?date?=?new?Date()const?currentYear?=?date.getFullYear().toString()return?currentYear.substr(currentYear.length?-?2,?2)
}function?theWeek()?{var?totalDays?=?0;now?=?new?Date();var?days?=?new?Array(12);days[0]?=?31;days[2]?=?31;days[3]?=?30;days[4]?=?31;days[5]?=?30;days[6]?=?31;days[7]?=?31;days[8]?=?30;days[9]?=?31;days[10]?=?30;days[11]?=?31;//判斷是否為閏年,針對2月的天數進行計算if?(Math.round(now.getYear()?/?4)?==?now.getYear()?/?4)?{days[1]?=?29}?else?{days[1]?=?28}if?(now.getMonth()?==?0)?{totalDays?=?totalDays?+?now.getDate();}?else?{var?curMonth?=?now.getMonth();for?(var?count?=?1;?count?<=?curMonth;?count++)?{totalDays?=?totalDays?+?days[count?-?1];}totalDays?=?totalDays?+?now.getDate();}//得到第幾周var?week?=?Math.round(totalDays?/?7);return?week;
}
main().catch(err?=>?{console.log(err)
})

6.3.4 然后在package.json 中增加一個npm script:

"release":?"node?scripts/release.js",

6.3.5 測試

運行命令:

npm?run?release??

下圖為腳本運行效果:

小工具腳本運行還算順利,只需要運行1次命令,確認1次,輸入2次,避免了輸入很多git命令。還有就是發完“預發布”之后,我們很容易忘了切回develop分支,這個小工具腳本最后把代碼切到了develop分支,可以減少不必要的麻煩。

當然這里,我沒有考慮許多的異常case , 健壯性不太好,有待優化。

最后我非常感謝川哥,細心耐心給予我指導,解答我的問題。川哥人好又心善,勤勉又聰慧,實在是我學習的楷模~


最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進群。


推薦閱讀

我在阿里招前端,該怎么幫你(可進面試群)
我讀源碼的經歷

在字節做前端一年后,有啥收獲~
老姚淺談:怎么學JavaScript?

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》多篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,活躍在知乎@若川,掘金@若川。致力于分享前端開發經驗,愿景:幫助5年內前端人走向前列。

點擊方卡片關注我、加個星標

今日話題

付費課程一定程度上可以幫助到一些自律愛學習的人,同時也確實會節省不少時間。打個可能不是那么恰當的比方。如果說學習是爬山,那么付費學習可以理解為是適當的花錢坐纜車,坐上纜車節省了時間和體力,更容易攀登到更高的山峰,但前提是體力較好。自己走山路上山當然也很好,但如果爬更高的山峰,后續就有可能到達不了最頂峰。歡迎分享、收藏、點贊、在看我的公眾號文章~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275644.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275644.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275644.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php ip2long 32 64位,詳談php ip2long 出現負數的原因及解決方法

php提供了ip2long與long2ip方法對ip地址處理。1、ip2long — 將一個IPV4的字符串互聯網協議轉換成數字格式int ip2long ( string $ip_address )參數&#xff1a; ip_address 一個標準格式的地址。返回值&#xff1a; 返回IP地址轉換后的數字 或 FALSE 如果 ip_address 是無效的…

(轉)從零實現3D圖像引擎:(6)向量函數庫

1. 數學分析 1) 基本定義&#xff1a; 向量由多個分量組成&#xff0c;2D/3D向量表示一條有向線段。下面的ux,uy就是兩個分量。 向量u <ux, uy>&#xff0c;如果從點P1(x1, y1)指向點P2(x2, y2)&#xff0c;則&#xff1a; U p2 - p1 (x2-x1, y2-y1) <Ux, Uy> …

chrome黑暗模式_黑暗模式-并非時尚

chrome黑暗模式In this post I’ve shared my research and views on how the extremely popular “Dark Mode” has moved beyond it’s initial label of “The App Design Fad of 2019”.在這篇文章中&#xff0c;我分享了我的研究和看法&#xff0c;探討了非常受歡迎的“黑…

A.華華聽月月唱歌

鏈接&#xff1a;https://ac.nowcoder.com/acm/contest/392/A 題意&#xff1a; 月月唱歌超級好聽的說&#xff01;華華聽說月月在某個網站發布了自己唱的歌曲&#xff0c;于是把完整的歌曲下載到了U盤里。然而華華不小心把U盤摔了一下&#xff0c;里面的文件摔碎了。月月的歌曲…

花了一天精選了20多篇好文,只為與你分享

大家好&#xff0c;我是若川。很多小伙伴因工作繁忙而沒有很多自己的時間去學習新知識&#xff0c;更多的是通過一些碎片化的時間來閱讀一些他人的技術文章來提升自己的技術視野以及擴展自己的知識儲備。這次我精心整理了一批大佬們的優秀文章&#xff0c;感興趣的可以閱讀關注…

matlab判斷電話播鍵音,MATLAB電話撥號音的合成與識別

1.實驗目的1.本實驗內容基于對電話通信系統中撥號音合成與識別的仿真實現。主要涉及到電話撥號音合成的基本原理及識別的主要方法&#xff0c;利用 MATLAB 軟件以及 FFT 算法實現對電話通信系統中撥號音的合成與識別。并進一步利用 MATLAB 中的圖形用戶界面 GUI 制作簡單直觀的…

jquery插件之無縫循環新聞列表

一、效果圖&#xff1a; tips源碼下載&#xff1a;http://files.cnblogs.com/waitingbar/newslist.rar 二、jquery源碼: (function($){$.fn.extend({newsList:function(options){var defaults {actName:li, //顯示條數名&#xff1b;maxShowNum:6, //最多的顯示…

素描的幾大基礎知識點_2020年讓您感到驚奇的5大素描資源

素描的幾大基礎知識點Sketch is my favorite stand-alone software that I use every day. It is simple, stable, and fast. During my working process, I use other resources that allow me to create UX/UI design faster. These tools have a different direction, but s…

ESMap+Html5+SpringBoot+FastDFS實現導航導購App

github鏈接 項目實現的簡要概述 服務器部分 測試階段使用的是雙系統的開發模式&#xff0c;在Linux服務器上部署了輕量級分布式文件系統fastdfs&#xff0c;且整合了高性能的HTTP和反向代理服務器nginx&#xff1b;在本地的服務器上使用Spring Boot框架&#xff0c;使用其內置的…

你不知道的 Chrome DevTools 玩法

大家好&#xff0c;我是若川。今天再分享一篇 chrome devtools 的文章。之前分享過多篇。Chrome DevTools 全攻略&#xff01;助力高效開發 前端容易忽略的 debugger 調試技巧?筆者在前段時間的開發時&#xff0c;需要通過 Chrome DevTools來分析一個接口&#xff0c;調試中發…

matlab擬合四次函數表達式,用matlab編寫程序求以冪函數作基函數的3次、4次多項式的最小二乘曲線擬合,畫出數據散點圖及擬合曲線圖...

共回答了18個問題采納率&#xff1a;83.3%x[0.0 0.1 0.2 0.3 0.5 0.8 1.0]; %輸入數組>> y[1.0 0.41 0.50 0.61 0.91 2.02 2.46];>> f1inline(poly2sym(polyfit(x,y,3))); %polyfit擬合得到系數,poly2sym由系數得到多項式,inline轉換內聯函數>> f2inline(pol…

排版人員 快速排版_選擇排版前應了解的事項

排版人員 快速排版Design is everywhere, and with design comes text and the content that you’re trying to reach the user with. But before creating your design and choosing what font you want to use, there are some things you should know that will help you a…

matlab光順拐點,基于MATLAB的最大誤差雙圓弧逼近曲線的算法及實現.pdf

基于MATLAB的最大誤差雙圓弧逼近曲線的算法及實現.pdf第31卷第6期 基于MⅢB的最大誤差雙圓弧逼近曲線的算法及實現文章編號&#xff1a;1004—2539120町】06一唧一∞基于MAⅡ&#xff0e;AB的最大誤差雙圓弧逼近曲線的算法及實現淮海工學院機械工程系&#xff0c;扛蘇連云港笠a…

若川誠邀你加源碼共讀群,幫助更多人學會看源碼~

小提醒&#xff1a;若川視野公眾號面試、源碼等文章合集在菜單欄中間【源碼精選】按鈕&#xff0c;歡迎點擊閱讀&#xff0c;也可以星標我的公眾號&#xff0c;便于查找。回復pdf&#xff0c;可以獲取前端優質書籍。最近我創建了一個源碼共讀的前端交流群&#xff0c;希望嘗試幫…

體育木地板的施工

文章來源&#xff1a;http://www.bjfhrd.com 體育木地板上有許多暗門&#xff0c;以制造特殊效果&#xff0c;如火焰、煙霧&#xff0c;使房屋、樹木、山或人物在一瞬間出現或銷售。這種特殊的要求&#xff0c;對于專業體育木地板德施工就有了一定的要求。 專業體育木地板施工&…

imessage_重新設計iMessage以獲得更好的用戶體驗— UX案例研究

imessage體驗設計 (EXPERIENCE DESIGN) Communication is a vital part of our everyday lives. We almost don’t even have to think about it. With social media and our devices as prime tools, we’re constantly finding new ways to stay connected. Instant messagin…

mysql 生成時間軸,MYSQL 時間軸數據 獲取同一天數據的前3條

創建表數據CREATE TABLE praise_info (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ID,pic_id varchar(64) DEFAULT NULL COMMENT 圖片ID,created_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 創建時間,PRIMARY KEY (id),KEY pic_id (pic_id) USING BTREE) ENGINEInn…

【招聘】永輝招前端

大家好&#xff0c;我是若川。這應該招聘第六期。友情幫好友宣傳招聘。之前在跟各位讀者朋友分享下公眾號運營策略 文中提到 公眾號主旨是幫助5年內前端小伙伴提升&#xff0c;找到好工作&#xff0c;所以有招聘文。上海 高級前端 本科 25k-50k 16薪崗位職責&#xff1a;1、…

C語身教程第三章: C說話挨次籌算匹面(1)

&#xff23;說話挨次籌算本課先容&#xff23;說話挨次籌算的根基要領和根基的挨次語句。從挨次流程的角度來看&#xff0c;挨次可以分為三種根基構造&#xff0c; 即挨次構造、分支構造、循環構造。 這三種根基構造可以組玉成部的種種重年夜挨次。&#xff23;說話供給了多種…

插圖 引用 同一行兩個插圖_插圖的目的

插圖 引用 同一行兩個插圖If you’re a designer in tech you’ve likely come across them. Any search for UI or product design on Dribbble will yield at least a few. Amid the sea of pastel blues and pinks, accented neon purples and gamboge yellows, these facel…