今日軍事新聞聯(lián)播在線播放長沙百度快照優(yōu)化排名
Monorepo架構(gòu)可以把多個(gè)獨(dú)立的系統(tǒng)放到一起聯(lián)調(diào),本文記錄基于pnpm > workspace
功能,如何構(gòu)建將vitepress
和組件庫進(jìn)行聯(lián)調(diào),并且使用turbo
進(jìn)行任務(wù)順序編排。
技術(shù)棧清單: pnpm
、vitepress
、turbo
一、需求分析
1、最終目標(biāo)
我們最終需要實(shí)現(xiàn)這樣的一個(gè)Monorepo項(xiàng)目架構(gòu):
--project--package.json--packages--docs--package.json--project-one--package.json--pnpm-workspace.yaml
其中各個(gè)目錄功能如下:
project
:根目錄
packages
:子項(xiàng)目包
packages/docs
:基于vitepress的文檔項(xiàng)目
packages/project-one
:組件庫
2、Monorepo技術(shù)選型
實(shí)現(xiàn)Monorepo架構(gòu)的方式主要有以下兩種:
-
lerna+yarn
-
pnpm中workspace配置
這里選擇后者,因?yàn)榛?code>pnpm的包管理邏輯使用軟硬鏈接,并且重復(fù)使用本地依賴包緩存,可以大大提升安裝效率,節(jié)省依賴包存儲(chǔ)空間。而且pnpm
還繼承了npm
的所有功能,并且支持node
版本管理,這里非常推薦pnpm
。
3、為什么使用vitepress?
之前有使用過vuepress
,后來vite
伴隨vue3
一起被推出,體驗(yàn)后果斷切換到vite
,基于esmodule
的調(diào)試模式,調(diào)試效率直線提升。所以同理,這里也同樣推薦使用vitepress
,而不是vuepress
。
4、turbo的作用
turbo
全名turborepo
,本身也是一個(gè)Monorepo
管理工具。這里主要使用其任務(wù)編排能力,能夠按正確的順序執(zhí)行Monorepo
內(nèi)的項(xiàng)目的任務(wù)。
例如:Monorepo
里有三個(gè)項(xiàng)目A,B,C。A和C還需要依賴于B。也就是說B項(xiàng)目需要先構(gòu)建好后,A和C才能構(gòu)建。
正常每個(gè)項(xiàng)目都按照這個(gè)順序做任務(wù)編排:lint->build->test->deploy
。即檢查規(guī)范->構(gòu)建項(xiàng)目->測(cè)試項(xiàng)目->部署項(xiàng)目。
從上圖可以看到,使用lerna時(shí),A、B、Cd這三個(gè)項(xiàng)目中的lint、build、deploy都是并行進(jìn)行的。如果A、C都依賴B,那么A、C在build的時(shí)候,很可能 B d還沒有build完成,會(huì)拖慢A、C的build效率。
但是turbo能夠?qū)⒚總€(gè)項(xiàng)目里的任務(wù)進(jìn)行拓?fù)渑判蛟賵?zhí)行。即圖中B項(xiàng)目并行執(zhí)行l(wèi)int,test,build,之后A和C就可以更快的執(zhí)行構(gòu)建,大大提高了整體的效率。
二、開發(fā)
1、文件結(jié)構(gòu)
首先創(chuàng)建如下文件結(jié)構(gòu):
--project--package.json--packages--docs--package.json--project-one--package.json--pnpm-workspace.yaml--turbo.json
創(chuàng)建完project
根目錄、packages/docs
、packages/project-one
后,分別執(zhí)行pnpm init
做項(xiàng)目初始化,生成package.json
文件。
并且在跟目錄創(chuàng)建 pnpm-workspace.yaml
文件:
packages:- 'apps/*'- 'packages/*'
識(shí)別packages
和apps
目錄下的項(xiàng)目,作為子項(xiàng)目。這樣在執(zhí)行pnpm add XXX --workspace
時(shí),就會(huì)到子項(xiàng)目中去尋找。
2、turbo.json
{"$schema": "https://turbo.build/schema.json","pipeline": {"build": {"dependsOn": ["^build"],"outputs": ["dist/**"]},"lint": {},"dev": {"cache": false,"persistent": true},"clean": {"cache": false}}
}
3、根目錄script命令行代理
#package.json
"scripts": {"turbo-test": "turbo run test","turbo-build": "turbo run build","test": "echo \"Error: no test specified\" && exit 1","docs:dev": "pnpm --filter \"docs\" dev","docs:build": "pnpm --filter \"docs\" build","docs:serve": "pnpm --filter \"docs\" serve","docs:preview": "pnpm --filter \"docs\" preview","one:dev": "pnpm --filter \"project-one\" dev"
}#docs package.json
"scripts": {"dev": "vitepress dev","build": "vitepress build","serve": "vitepress serve","preview": "vitepress preview","test": "echo \"Error: no test specified\""
}#project-one package.json
"scripts": {"dev": "node index2.js","build": "node index2.js","test": "echo \"Error: no test specified\""
}
4、初始化project-one項(xiàng)目
代碼如下:
#index.js
const addOne = (x = 0, msg = '未填') => {console.log('調(diào)用project-one的項(xiàng)目是:', msg);return x + 1;
}
export default addOne#index2.js
console.log('nihao index2');
5、初始化docs項(xiàng)目
docs
使用vitepress
構(gòu)建,打開終端,進(jìn)入docs
目錄,執(zhí)行下面命令,對(duì)docs
初始化:
# 安裝vitepress
pnpm add -D vitepress # 初始化項(xiàng)目,這里會(huì)出現(xiàn)交互式命令行,默認(rèn)回車下一步就行
pnpm dlx vitepress init
調(diào)整docs/package.json
代碼如下:
{"name": "docs","version": "1.0.0","description": "","main": "index.js","scripts": {"dev": "vitepress dev","build": "vitepress build","serve": "vitepress serve","preview": "vitepress preview","test": "echo \"Error: no test specified\""},"keywords": [],"author": "","license": "ISC","dependencies": {"project-one": "workspace:^","vitepress": "1.0.0-rc.20","vue": "^3.2.45"},"devDependencies": {}
}
創(chuàng)建docs/index.md
文件,代碼如下:
---
layout: home
hero:name: VitePresstext: Vite & Vue powered static site generator.tagline: Lorem ipsum...actions:- theme: brandtext: Get Startedlink: https://github.com/jkkdeng- theme: alttext: View on GitHublink: https://github.com/jkkdengfeatures:- icon: 🛠?title: Simple and minimal, alwaysdetails: Lorem ipsum...- icon: 🛠?title: Simple and minimal, alwaysdetails: Lorem ipsum...- icon: 🛠?title: Simple and minimal, alwaysdetails: Lorem ipsum...
---
<script setup>
import addOne from 'project-one'
addOne(10,'docs')
</script>
import addOne from 'project-one'
,這行會(huì)在workspace
中尋找project-one
項(xiàng)目下的package.json
文件,識(shí)別"main": "index.js",
配置,然后獲取到export
的addOne
方法。最終打印到瀏覽器控制臺(tái)。
6、執(zhí)行
到這里就基本都配置完成了,這里我們把項(xiàng)目跑起來,看下運(yùn)行效果。
我們打開終端命令行,并進(jìn)入project
根目錄.
-
執(zhí)行
pnpm run turbo-build
#turbo.json "build": {"dependsOn": ["^build"] },
系統(tǒng)會(huì)找到
turbo.json
中pipeline>build
下的配置:"dependsOn": ["^build"]
,^build
含義是指上游的build
任務(wù)優(yōu)先執(zhí)行。猜測(cè)turbo
應(yīng)該對(duì)各個(gè)子包中的package.json
進(jìn)行掃描,查看是否存在依賴關(guān)系,例如我們這里是docs
項(xiàng)目依賴project-one
項(xiàng)目,所有優(yōu)先對(duì)proect-one
項(xiàng)目進(jìn)行build
,然后在對(duì)docs
進(jìn)行build
??聪旅娴倪\(yùn)行結(jié)果也的確如此。
-
執(zhí)行
pnpm run turbo-test
#turbo.json "test": {"dependsOn": ["build"] },
這里的
build
就是pipeline
中的build
任務(wù),含義是:每個(gè)項(xiàng)目要執(zhí)行自己的test
任務(wù),就要先執(zhí)行build
任務(wù)。可以看到執(zhí)行順序依次是:
- project-one -> build
- project-one -> test
- docs -> build
- docs -> test
-
執(zhí)行
pnpm run one:dev
-
執(zhí)行
pnpm run docs:dev
源碼