Vue3.0中的monorepo管理模式的實現(xiàn)
前言
前段時間9月21日參加了在成都舉辦的第五屆FEDAY, 印象比較深刻的是白鷺引擎首席架構(gòu)師@王澤分享的《框架開發(fā)中的基礎(chǔ)設(shè)施搭建》 ,提到了在下一代白鷺引擎中使用到monorepo模式,以用來管理多個模塊,協(xié)調(diào)各個模塊之間的依賴更新。
正好在國慶期間10月5日尤大公開了vue3.0已完成的源碼,也是采用了monorepo管理模式,看來monorepo確實有其獨到的優(yōu)勢,再加上以前在項目中遇到過相關(guān)的痛點,所以深入地了解了一下這種模式,本文將基于vue3.0討論如何通過monorepo模式來管理代碼的。
什么是 monorepo?
monorepo是一種將多個package放在一個repo中的代碼管理模式,摒棄了傳統(tǒng)的多個package多個repo的模式。
目前 Babel, React, Angular, Ember, Meteor, Jest等許多開源項目都使用該種模式來管理代碼。
解決的問題
- 多個repo難以管理,編輯器需要打開多個項目;
- 某個模塊升級,依賴改模塊的其他模塊需要手動升級,容易疏漏;
- 公用的npm包重復(fù)安裝,占據(jù)大量硬盤容量,比如打包工具webpack會在每個項目中安裝一次;
- 對新人友好,一句命令即可完成所有模塊的依賴安裝,且整個項目模塊不用到各個倉庫去找;
帶來的問題
- 所有package代碼集中在一個項目,單個項目體積較大;
- 所有package代碼對所有人可見,無法做權(quán)限管理;
如何實現(xiàn) monorepo?
目前業(yè)界最佳實踐是采用yarn workspace + lerna 來實現(xiàn),vue3.0也是采用兩者結(jié)合的方式來實現(xiàn)。
yarn workspace可以實現(xiàn)在一個項目中實現(xiàn)多個模塊的依賴新增和共用,而lerna的功能則更完善,不僅可以管理多個模塊,還有清除模塊node_modules,發(fā)布模塊到npm,自動更新模塊間版本依賴,并支持全量發(fā)布和根據(jù)改動單獨發(fā)布等功能。
yarn官方推薦用yarn來處理依賴安裝,用lerna來處理依賴更新和發(fā)布問題。
下面開始基于monorepo模式來搭建一個仿vue3.0的項目
1. 全局安裝 yarn 和 lerna
$ npm i -g yarn lerna
2. 初始化項目
$ mkdir vue-next && cd vue-next $ lerna init // 此時項目結(jié)構(gòu) vue-next |-packages |-lerna.json |-package.json
3. 添加yarn workspace配置
// vue-next/package.json "private": true, // 項目根目錄下的private必須設(shè)置成true,否則workspace不會被啟用 "workspaces": [ // 指定需要管理的模塊 "packages/*" ],
4. 添加模塊內(nèi)容
// 此時項目結(jié)構(gòu) vue-next |-packages // packages下的所有包結(jié)構(gòu)類似,下面僅展示了compiler-core包的目錄結(jié)構(gòu) |-compiler-core // 與平臺無關(guān)的編譯器 |-__tests__ // 測試用例 |-src // 源文件 |-index.js // 根文件 |-package.json // 包配置 |-compiler-dom // 與瀏覽器相關(guān)的編譯器 |-reactivity // 數(shù)據(jù)響應(yīng)式系統(tǒng) |-runtime-core // 與平臺無關(guān)的runtime |-runtime-dom // 與瀏覽器相關(guān)的runtime |-runtime-test // 為了測試的輕量級runtime |-server-renderer // 服務(wù)端渲染 |-shared // 內(nèi)部幫助方法 |-template-explorer // 預(yù)覽模版轉(zhuǎn)化成render函數(shù)的工具 |-vue // 用于構(gòu)建完整的vue版本 |-lerna.json |-package.json
5. 安裝相關(guān)依賴
項目中一般只會用到以下3種安裝形式
5.1 給根項目安裝依賴(一般是公用的開發(fā)工具)
// yarn 使用 workspace 模式安裝 npm 包時必須加 -W 參數(shù) $ yarn add -W -D rollup typescript jest prettier ...
5.2 給package安裝外部npm包
// @vue/compiler-core 是取 vue-next/packages/compiler-core/package.json 的 name 字段 $ yarn workspace @vue/compiler-core add acorn estree-walker source-map $ yarn workspace @vue/template-explorer add monaco-editor
5.3 給package安裝內(nèi)部npm包
// @vue/compiler-core 是取 vue-next/packages/compiler-core/package.json 的 name 字段 $ yarn workspace @vue/compiler-dom add @vue/compiler-core@3.0.0-alpha.1 // 一定要指定正確的版本號,不然會到npm查找包 $ yarn workspace @vue/runtime-core add @vue/reactivity@3.0.0-alpha.1 $ yarn workspace @vue/runtime-dom add @vue/runtime-core@3.0.0-alpha.1 $ yarn workspace @vue/runtime-test add @vue/runtime-core@3.0.0-alpha.1 $ yarn workspace vue add @vue/compiler-dom@3.0.0-alpha.1 @vue/runtime-dom@3.0.0-alpha.1 // 可同時安裝多個
至此已經(jīng)完成了項目的基礎(chǔ)搭建(打包等工程化內(nèi)容略過,本文主要介紹monorepo相關(guān)),似乎主要是yarn在工作,lerna沒有沒有派上用場,下面來介紹lerna在哪些地方可以賦能vue3.0。
lerna介紹
A tool for managing JavaScript projects with multiple packages.
一個在js項目中用來管理多個package的工具。
主要是便于開發(fā)者更加高效簡便地管理package本身,依賴,發(fā)布。
1. 初始化項目
// 生成基本項目結(jié)構(gòu)和 lerna 配置 $ lerna init
2. 安裝依賴
如果需要重新安裝依賴,切記在刪除項目根路徑的node_modules前進(jìn)行g(shù)it提交保存,因為monorepo模式是以軟鏈接的形式來實現(xiàn)內(nèi)部 package 引用的,直接刪除整個node_modules的同時會把所有package的文件刪掉,難以恢復(fù)!
建議永不進(jìn)行刪除整個node_modules的操作,可以進(jìn)入node_modules全選后再取消勾選內(nèi)部package軟鏈接再刪除。
// 給所有 package 安裝依賴,在對于的目錄生成 node_modules,并在 node_modules 中為內(nèi)部package生成軟鏈接 $ lerna bootstrap // 默認(rèn)會使用 npm 安裝,但是本項目使用 yarn,可以指定使用 yarn $ lerna bootstrap --npm-client=yarn // 或者在 lerna.json 配置 {"npmClient": "yarn"} // 上述安裝方式如果不同package之間安裝了同一個npm包,會造成重復(fù)安裝,增加安裝時間和項目體積 // 可以利用 node_modules 向上查找的特性,將所有依賴安裝到項目根路徑的 node_modules 中,lerna 加上 --hosit即可 $ lerna bootstrap --hosit // 使用lerna bootstrap --npm-client=yarn --hoist // 會有沖突,報錯--hoist is not supported with --npm-client=yarn, use yarn workspaces instead ------------------------------------------------ $ yarn // 推薦?。?用 yarn workspace 特性替代 lerna bootstrap
3. 清除pacakge中多余的node_modules
// 在 6.2 安裝依賴時,部分npm包會給當(dāng)前的package目錄安裝 node_modules // 同時根路徑中的 node_modules 也會安裝項目 $ lerna clean
4. 查看所有pacakge
// package.json 中設(shè)置了 "private": true 的 package 不會展示 $ lerna ls
5. 查看有改動的pacakge
// package.json 中設(shè)置了 "private": true 的 package 不會展示 // 在 Independent mode 下只有改動過的 package 才會被發(fā)布 // vue3.0 采用的是 Fixed/Locked mode (default),每次都會發(fā)布所有 package,package 版本跟隨項目的版本走 $ lerna changed
6. 推送到git和發(fā)布到npm(重要)
// 根據(jù)當(dāng)前的 lerna 模式(Fixed/Locked mode (default) 或者 Independent mode)來進(jìn)行整包發(fā)布或者有改動的 package 單獨發(fā)布 // 每次發(fā)布會自動更新相關(guān)package的版本號,并且會更新引用該package的其他package依賴 $ lerna publish
總結(jié)
本文介紹了vue3.0中monorepo管理模式的實現(xiàn),通過yarn workspace和lerna兩者相結(jié)合,達(dá)到了在一個repo 中高效便捷地管理多個package的目的。
在我們?nèi)粘9ぷ髦锌赡軟]有開發(fā)白鷺引擎,vue這類大型框架的需求,但是這不代表我們用不到該模式,下面我總結(jié)了幾種適合monorepo管理模式的場景:
- 大型框架,依賴自身開發(fā)的多個獨立底層模塊支撐;
- 后臺項目,技術(shù)棧統(tǒng)一的多個后臺系統(tǒng),每個系統(tǒng)作為獨立的package單獨開發(fā),優(yōu)化開發(fā)和打包時間,同時共用的組件和js方法可以作為一個package;
- ui組件庫,各個組件之間獨立實現(xiàn)按需加載,例如餓了么的移動端組件庫mint-ui;
- sdk,接入同一sdk的不同渠道代碼統(tǒng)一管理;
- ...
參考資料
框架開發(fā)中的基礎(chǔ)設(shè)施搭建
Vue 3 源碼導(dǎo)讀
基于lerna和yarn workspace的monorepo工作流
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue element-ui el-tooltip組件失效問題及解決
這篇文章主要介紹了vue element-ui el-tooltip組件失效問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10vue如何使用watch監(jiān)聽指定數(shù)據(jù)的變化
這篇文章主要介紹了vue如何使用watch監(jiān)聽指定數(shù)據(jù)的變化,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04用electron 打包發(fā)布集成vue2.0項目的操作過程
這篇文章主要介紹了用electron 打包發(fā)布集成vue2.0項目的操作步驟,把electron 加入到自己項目中各種不兼容,升級版本踩坑無數(shù)個,今天通過本文給大家分享下詳細(xì)過程,需要的朋友可以參考下2022-10-10vue中動態(tài)渲染數(shù)據(jù)時使用$refs無效的解決
這篇文章主要介紹了vue中動態(tài)渲染數(shù)據(jù)時使用$refs無效的解決方案,具有很好的參考價值。希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01