日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

读完 Vue 发布源码,小姐姐回答了 leader 的提问,并优化了项目发布流程~

發布時間:2023/12/9 vue 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读完 Vue 发布源码,小姐姐回答了 leader 的提问,并优化了项目发布流程~ 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好,我是若川。這是 源碼共讀 第三期活動,紀年小姐姐的第三次投稿。紀年小姐姐學習完優化了自己的項目發布流程,而且回答了leader對她的提問,來看看她的思考和實踐。

第三期是 Vue 3.2 發布了,那尤雨溪是怎么發布 Vue.js 的?。不知不覺,源碼共讀已經進行了快一個月,有些小伙伴表示對面試和工作很有幫助,學完立馬能用。如果你也感興趣可以加我微信 ruochuan12參加。

1. 學習目標和資源準備

這一期閱讀的是 Vue3 源碼中的 script/release.js 代碼,也就是 Vue.js 的發布流程。在上一期源碼閱讀中從 .github/contributing.md[1] 了解到 Vue.js 采用的是 monorepo 的方式進行代碼的管理。

monorepo 是管理項目代碼的一個方式,指在一個項目倉庫 (repo) 中管理多個模塊/包 (package),不同于常見的每個 package 都建一個 repo。

剛好我最近搭建組件庫也是使用 monorepo 的方式去管理包。monorepo 有個缺點,因為每個包都維護著自己的 dependencies,那么在 install 的時候會導致 node_modules 的體積非常大。目前最常見的 monorepo 解決方案是使用 lerna 和 yarn 的 workspaces 特性去處理倉庫的依賴,我搭建的組件庫也是使用了 lerna 和 yarn。但 Vue3 的包管理沒有使用 lerna,它是怎么管理依賴包的版本號呢?讓我們跟著源碼一探究竟。

Lerna[2] 是一個管理工具,用于管理包含多個軟件包(package)的 JavaScript 項目,針對使用 git 和 npm 管理多軟件包代碼倉庫的工作流程進行優化。

學習目標:

1)學習 release.js 源碼,輸出記錄文檔。

資源準備:

Vue3 源碼地址:https://github.com/vuejs/vue-next

2. Yarn Workspace

//?vue-next/package.json?(多余的代碼已省略) {"private":?true,"version":?"3.2.2","workspaces":?["packages/*"],"scripts":?{"release":?"node?scripts/release.js"} }

Yarn 從 1.0 版開始支持 Workspace (工作區),Workspace 可以更好的統一管理有多個項目的倉庫。

  • 管理依賴關系便捷:每個項目使用獨立的 package.json 管理依賴,可以使用 yarn 命令一次性安裝或者升級所有依賴,無需在每個目錄下分別安裝依賴

  • 降低磁盤空間占用:可以使多個項目共享同一個 node_modules 目錄

3. release.js 文件解讀

先手動跑一遍 yarn run release --dry,控制臺會輸出以下信息(多余信息已省略),從控制臺日志看出來,發布 Vue.js 會經歷以下幾個步驟:

//?確認發布版本號 ??Select?release?type?... >?patch?(3.2.3)minor?(3.3.0)major?(4.0.0)custom //?執行測試用例 Running?tests... //?更新依賴版本 Updating?cross?dependencies... //?打包編譯所有包 Building?all?packages... //?生成?changelog conventional-changelog?-p?angular?-i?CHANGELOG.md?-s //?提交代碼 Committing?changes... //?發布包 Publishing?packages... //?推送代碼到?GitHub Pushing?to?GitHub...

初步了解發布流程后,來看看 release.js 源碼做了什么,先看入口函數 main()

main 函數

代碼太多就不貼代碼了,記錄一下思路和思考

  • 確認要發布的版本:

      • 如果從命令行獲取到了版本號,先驗證版本號規范,再次確認版本號

      • 如果命令行沒有輸入版本號,會讓用戶選擇一個版本發布

    確認版本號使用了一個庫叫 semver,它的作用是用于版本校驗比較。

    //?目的是獲取命令行參數(也就是允許用戶自定義輸入版本號,比如?yarn?release?v3.5.0) const?args?=?require('minimist')(process.argv.slice(2)) let?targetVersion?=?args._[0]
  • 執行測試用例

  • const?execa?=?require('execa') const?run?=?(bin,?args,?opts?=?{})?=>?execa(bin,?args,?{?stdio:?'inherit',?...opts?}) const?bin?=?name?=>?path.resolve(__dirname,?'../node_modules/.bin/'?+?name)if?(!skipTests?&&?!isDryRun)?{//?bin("jest")?先獲取?node_modules/.bin/jest?的目錄,run?的本質就是執行命令行//?這行代碼的意思就相當于在命令終端,項目根目錄運行 ./node_modules/.bin/jest 命令。await?run(bin('jest'),?['--clearCache'])await?run('yarn',?['test',?'--bail']) }?else?{console.log(`(skipped)`) }
  • 更新依賴版本

  • //?1)獲取?packages?目錄下的所有包 const?packages?=?fs.readdirSync(path.resolve(__dirname,?'../packages')).filter(p?=>?!p.endsWith('.ts')?&&?!p.startsWith('.')) //?1)獲取包的根目錄路徑 const?getPkgRoot?=?pkg?=>?path.resolve(__dirname,?'../packages/'?+?pkg) //?2)更新根目錄和?packages?目錄下每個包的?package.json?的版本號 function?updateVersions(version)?{} //?3)實現更新?package.json?版本號的,以及更新依賴包的版本號 function?updatePackage(pkgRoot,?version)?{} //?4)實現更新與?vue?相關依賴包的版本號 function?updateDeps(pkg,?depType,?version)?{}
  • 打包編譯所有包

  • 這部分涉及另外一個文件 script/build.js,這個文件主要是將各個包打包在對應的目錄下,比如打包一個依賴就運行一次yarn build,如果有多個包,就異步循環調用打包命令。核心代碼如下:

    /***?迭代打包*?@param?{*}?maxConcurrency?最大并發*?@param?{*}?source?目錄*?@param?{*}?iteratorFn?構建函數(核心就是運行?build?命令)*?@returns*/ async?function?runParallel(maxConcurrency,?source,?iteratorFn)?{const?ret?=?[];const?executing?=?[];for?(const?item?of?source)?{const?p?=?Promise.resolve().then(()?=>?iteratorFn(item,?source));ret.push(p);if?(maxConcurrency?<=?source.length)?{const?e?=?p.then(()?=>?executing.splice(executing.indexOf(e),?1));executing.push(e);if?(executing.length?>=?maxConcurrency)?{await?Promise.race(executing);}}}return?Promise.all(ret); }
  • 生成 CHANGELOG 文件

  • 主要運行的是這行命令:conventional-changelog -p angular -i CHANGELOG.md -s

  • 提交代碼

  • 先執行 git diff 命令,檢查文件是否有修改,如果有,執行 git add 和 git commit 命令

  • 發布包

  • 最后執行的命令是,yarn publish,發布新版本和打 Tag

  • 推送到 GitHub

  • 主要運行的命令:

      • 打 tag:git tag ${version}

      • 推送 tag:git push origin refs/tags/${version}

      • 提交代碼到遠程倉庫:git push

    至此,release 發布流程已經分析完了。

    release 發布流程

    4. 感想

    回答一下開篇的問題,Vue 是如何管理版本號呢?閱讀完源碼我們會分現,在發版的時候會統一更新所有包的 package.json 的版本號。對比我在搭建組件庫過程中使用的 lerna,其實 lerna 是把 release 這一套流程封裝成了一個包,它里面處理發包的流程跟 Vue Release 流程基本是一致的。

    這次的源碼解讀解答了我的一些疑惑。在我搭建組件庫的過程中,我一開始了解到的是一個組件一個目錄,單包推送到 npm 私庫。這樣做的缺點很明顯,需要在每個目錄安裝一遍依賴,單獨處理版本號。后來了解到了 yarn workspace,知道它可以處理依賴安裝的問題,但版本號的處理還是沒有解決方案。于是我去尋找業內比較流行的解決辦法,發現大部分是使用了 lerna。

    于是我向我的 TL 溝通詢問,可否采用 yarn + lerna 的方式來搭建組件庫。我記得特別清楚他反問我,問我 lerna 解決了什么問題,我支支吾吾回答了官網上的介紹,因為我當時對 lerna 的了解僅停留在官網以及它的常用命令,實際上我不知道它解決了什么問題。TL 見我答不上來,回復了我一句【如無必要,勿增實體】。

    通過這次的源碼閱讀,我可以回答 TL 反問我的那個問題了,lerna 解決的是發包流程中版本號處理,自動生成 CHANGELOG 文件,提交代碼,發布包,推送到倉庫這幾個問題,它把這幾個流程封裝成命令供用戶使用。它不是搭建組件庫非必要引入的工具,雖然引用了 lerna 會增加了新的復雜度,但在不了解發包流程的前期使用 lerna 可以使組件庫開發者更專注于組件開發的工作上,而不需要過度關注如何發包。

    5. 實踐

    經過一番思考,我認為引入 lerna 確實給系統增加了一些復雜度,因為它要求開發人員額外學習 lerna 的一些知識和命令,增加了學習成本以及系統復雜度。我覺得可以參考 Vue 的 release.js,寫一個適用于項目的構建發版腳本用來發包,降低系統復雜度。

    邏輯代碼基本與 Vue3 的 release.js 和 build.js 一致,去掉了一些沒必要的代碼,比如單元測試和一些環境判斷。還修改了一下 rollup.config.js 的配置,感覺用起來確實比 lerna 好用一些。最終效果如下:

    img

    參考資料

    [1]

    .github/contributing.md: https://github.com/vuejs/vue-next/blob/master/.github/contributing.md

    [2]

    Lerna: https://www.lernajs.cn/

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


    推薦閱讀

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

    初學者也能看懂的 Vue3 源碼中那些實用的基礎工具函數
    老姚淺談:怎么學JavaScript?

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

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

    識別方二維碼加我微信、拉你進源碼共讀

    今日話題

    略。歡迎分享、收藏、點贊、在看我的公眾號文章~

    總結

    以上是生活随笔為你收集整理的读完 Vue 发布源码,小姐姐回答了 leader 的提问,并优化了项目发布流程~的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。