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