Monorepo風(fēng)格的組件工程搭建示例詳解
Monorepo概念
隨著各種技術(shù)的發(fā)展和超級應(yīng)用的出現(xiàn),人們開始考慮怎么才能將所有的小應(yīng)用都集成在一個大項目中,特別是在這些項目互相影響時,在實現(xiàn)過程中,工程師們最關(guān)注的兩點是:項目功能分離 和 避免重復(fù)代碼。
如果將每個功能作為獨立的項目打包,隨著業(yè)務(wù)的發(fā)展,項目會越來越多,根本沒法管理,項目與項目之間的協(xié)作也會越來越困難,所以Monorepo的概念并產(chǎn)生了。
在Monorepo中我們可以在一個項目下進(jìn)行功能拆分,他們互相獨立不影響,但是又可以通過引用來達(dá)到互相協(xié)助。
Monorepo的優(yōu)缺點
優(yōu)點:
- 簡化依賴的管理。
- 跨組合作更加方便。
- 代碼復(fù)用簡單。
缺點:
- 項目構(gòu)建時間過長。
- 版本信息雜糅不清晰。
我也會基于Monorepo的方式搭建屬于自己的組件庫工程。
項目工程的搭建
技術(shù)選型
- 基于
pnpm的Monorepo工程,項目打包工具vite、gulp,使用sass處理樣式。 Vue組件寫法會支持Jsx和template的方式。項目支持Typescript。lint規(guī)范的接入,prettier的格式化統(tǒng)一,husky的卡點校驗。- 組件單元測試使用
vitest+happy-dom。
基于以上的技術(shù)開始搭建我們的項目。
項目的大概結(jié)構(gòu)
// vb-design
|—— config //放置一些腳本
|—— examples //存放演示包
|—— demo
|—— taro-demo
...
|—— packages //存放npm庫的包
|—— hooks
|—— icon
|—— ui-h5
|—— ui-taro
...
.eslintignore
.eslintrc.js
.gitignore
.lintstagedrc.cjs
.npmrc
.prettierrc.cjs
package.json
pnpm-workspace.yaml
README.md
tsconfig.root.json
...
項目配置
Monerepo工程的起步
pnpm搭建Monorepo是非常簡單的,只需要我們配置pnpm-workspace.yaml文件即可。具體的配置可參考pnpm-workspace.yaml | pnpm
lint、prettier、eslint的接入
lint、prettier、eslint的配置大部人應(yīng)該都很熟練了,在這我就不一一貼代碼說明了。還不清楚的小伙伴可參考我的代碼或者找篇相關(guān)的教程自己跟著試試。
統(tǒng)一開發(fā)環(huán)境
開發(fā)環(huán)境的統(tǒng)一,主要是統(tǒng)一Node版本和pnpm,我們可以通過在package.json中配置一些字段來統(tǒng)一開發(fā)環(huán)境。
1、限制Node版本和pnpm通過配置volta和engines限制Node和pnpm的版本
//package.json
"volta": {
"node": "16.13.0"
},
"engines": {
"node": "16.13.0",
"pnpm": ">=6"
}
2、限制項目只能通過pnpm初始化依賴
//package.json
"scripts": {
"preinstall": "npx only-allow pnpm",
}
packages子包搭建
對于子包的搭建,不會詳細(xì)地一一講解,需要深入了解的可以自行到源代碼里看。
ui-h5搭建
- 目錄結(jié)構(gòu)設(shè)計
//ui-h5
components //組件目錄
|—— Button
|—— demo //demo演示存放目錄
|—— base.vue
...
|—— index.md //組件使用文檔
|—— index.scss //組件樣式
|—— index.ts //vue組件
|—— index.taro.ts //taro組件
|—— Icon
...
style //公共樣式存放
|—— index.scss
...
ui.h5.ts //vue組件對外暴露
ui.taro.ts //taro組件對外暴露
為了開發(fā)方便,把vue端、taro端的組件都放在該包下,以及examples需要的演示文檔和demo也放在該包下。至于各端寫好的組件、demo、演示文檔是怎么使用,后續(xù)會說明。
- 構(gòu)建產(chǎn)物
// dist
components //單個組件
|—— Button
|—— index.scss
|—— index.css
|—— index.js
|—— index.taro.js
|—— Icon
...
style
|—— index.scss
...
types
|——
...
style.css
vb-ui.es.js
vu-ui.umd.js
vb-ui.taro.es.js
vb-ui.taro.umd.js
ui-taro搭建
該包其實沒有做更多的事情,只是初始化之后把package.json做了相關(guān)配置。最重要的地方是在根目錄下的package.json配置了腳本,在ui-h5包構(gòu)建之后,通過腳本copy了該包需要的東西。
- 腳本文件都在根目錄
config里
icon搭建
在ui-h5中,Icon組件的設(shè)計支持了iconfont和svg的方式,這也是參考了element-ui的Icon組件設(shè)計。所以該包主要是處理svg圖標(biāo),把圖標(biāo)轉(zhuǎn)化成vue組件統(tǒng)一向外暴露的過程。
另外,我并不會用設(shè)計軟件,沒有svg可用,所以借用了字節(jié)arco-design的圖標(biāo)Arco Design Icons – Figma
hooks搭建
該包主要是一些公共方法的包,目前也沒有更多的想法,所以也只是先放著。
examples瀏覽器端演示包搭建
因為搭建的是移動端組件庫,所以演示包需要有兩個入口,H5端和PC端。整個搭建的過程大致是:
- 通過vite-plugin-md解析md文件。
- 通過vite-plugin-pages和vite-plugin-vue-layouts管理路由,頁面的存放路徑是在
ui-h5包下。
vite-plugin-pages和vite-plugin-vue-layouts的配置
//vite.config.js
Pages({
dirs: [
{
dir: resolve(__dirname, '../../packages/ui-h5/components'),
baseRoute: 'component',
},
],
exclude: ['**/components/*.vue'],
extensions: ['vue', 'md'],
}),
Layout({
layoutsDirs: 'src/layouts',
defaultLayout: 'preview',
})
項目的構(gòu)建與npm包發(fā)布
這么多的子包,打包構(gòu)建以及推送到npm是不是需要到每個子包下執(zhí)行完打包和執(zhí)推送的命令?針對這個問題pnpm官方是有解決方案的:
首先所有的子包都定義個build命令來執(zhí)行當(dāng)前包的所有打包構(gòu)建事情,最后項目根目錄package.json的配置如下:
//package.json
"scripts": {
"build": "pnpm --filter './packages/**' run build && pnpm run build:taro", //執(zhí)行packages下所有子包的build方法
"release": "pnpm run build && pnpm run release:only",
"release:only": "changeset publish --tag=beta --access=publish", //發(fā)布所有子包
"build:taro": "node ./config/build-taro.js",
"build:demo": "pnpm --filter './examples/**' run build"
}
上方build這個地方的配置pnpm官方有很詳細(xì)的說明。再就是關(guān)于npm publish的,主要是通過@changesets/cli這個cli工具去解決。
changeset publish 只是一個很純凈的發(fā)包命令,手動提升/修改版本后再 changeset publish他會將所有包都publish一次。
- 寫到這,順便再給大家說下這個項目的代碼發(fā)布流吧。
- 版本號是手動修改的。
- 通過打
tag的方式會觸發(fā)workflows去執(zhí)行打包構(gòu)建,然后publish和部署演示的demo。
很多開源的項目通過changeset-bot + changesets/action + @changesets/cli能玩出各種各樣的工作流。
關(guān)于單元測試
單測在開源項目里是不可缺少的存在,雖然我不一定會去寫單測??,但是該有的東西還是得搭起來。
Vitest是基于vite的原生快速單元測試,完全兼容Jest的Api,還能共用vite的配置。所以針對當(dāng)前項目使用Vitest是最快接入單元測試的方式,但是很遺憾,針對小程序端還沒有更好的接入單元測試方案。
最后
寫到這,組件庫的搭建過程也差不多了,有什么不了解的可以留言或私信我。歡迎大家提出更好的意見或想法,還有寫作水平差,有問題請輕噴。
最后因為沒有一些設(shè)計規(guī)范,所以UI組件的產(chǎn)出并不會很理想。但是從0到1實現(xiàn)的過程才是重點,這能讓我們以后在碰到相同問題時能快速解決。
相關(guān)文章
代碼倉庫:vb-design
以上就是Monorepo風(fēng)格的組件工程搭建示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Monorepo組件搭建的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue3.0 CLI - 2.3 - 組件 home.vue 中學(xué)習(xí)指令和綁定
這篇文章主要介紹了vue3.0 CLI - 2.3 - 組件 home.vue 中學(xué)習(xí)指令和綁定的相關(guān)知識,本文通過實例代碼相結(jié)合的形式給大家介紹的非常詳細(xì) ,需要的朋友可以參考下2018-09-09
在vscode 中設(shè)置 vue模板內(nèi)容的方法
這篇文章主要介紹了在vscode 中設(shè)置 vue模板內(nèi)容的方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09

