pnpm workspace管理monorepo項(xiàng)目使用過程詳解

本文記錄使用 monorepo 方案 pnpm workspace 的過程。
monorepo
首先要清楚,為什么要用到 monorepo?對于我來說,手上負(fù)責(zé)公司內(nèi)部的多個項(xiàng)目,其中除了業(yè)務(wù)模塊單獨(dú)使用外,例如系統(tǒng)管理、中間庫、工具等都是共用的。
而在開發(fā)的過程中,共用的模塊想要添加或修改,為了保持多項(xiàng)目一致性,那么就需要不斷地復(fù)制粘貼,這個過程不說有多繁瑣,還有可能造成依賴錯誤。
為了解決這個問題,對比了 learn+yarn / npm 等方案后,決定采用 pnpm workspace 方案對項(xiàng)目進(jìn)行管理。
下面將通過一個例子初步學(xué)會 pnpm workspace。
隨便找個文件夾創(chuàng)建 workspace 項(xiàng)目
D: && cd project/monorepo mkdir demo2 && cd demo2
新建 pnpm-workspace.yaml 文件并填入相關(guān)內(nèi)容以啟用 workspace
packages: - packages/* - apps/* - demo
首行 packages 代表 workspace 包,且該 workspace 由以下項(xiàng)目組成;而帶有 - 前綴的字符串,代表項(xiàng)目目錄,具體可通過 pnpm 官方文檔查看
完善項(xiàng)目目錄及包配置
現(xiàn)在的文件夾應(yīng)當(dāng)只有一個 pnpm-workspace.yaml 文件,接下來我們手動添加相關(guān)文件/文件夾和配置
新建相關(guān)文件夾
mkdir packages && cd packages mkdir components utils hooks space-play cd .. && mkdir apps && cd apps && mkdir play1
為文件夾新建 package.json 文件
// ./package.json
{
"description": "A pnpm workspace example."
}
// ./packages/components/package.json
{
"name": "@space-play/components",
"version": "0.0.1"
}
// ./packages/utils/package.json
{
"name": "@space-play/utils",
"version": "0.0.1"
}
// ./packages/hooks/package.json
{
"name": "@space-play/hooks",
"version": "0.0.1"
}
// ./packages/space-play/package.json
{
"name": "space-play",
"version": "0.0.1"
}
// ./apps/play1/package.json
{
"name": "play1",
"version": "0.0.1"
}可以從上面的內(nèi)容中看出, packages 文件夾里面除了 space-play 的 package.json 文件,其他文件夾里面的 name 命名都帶有一個 @space-play 前綴,那么這個是什么意思呢?這是代表 npm 發(fā)包后的安裝命名,也代表這些包都?xì)w屬于 space-play 包。
此時的項(xiàng)目目錄應(yīng)該是這樣的:
demo2 | apps | play1 | package.json | packages | components | package.json | hooks | package.json | utils | package.json | space-play | package.json | pnpm-workspace.yaml | package.json
一個簡陋的 monorepo 已經(jīng)完成,通過相關(guān) pnpm add 指令,我們可以進(jìn)行本地包的調(diào)用。
例如我們想要在 apps/play1 包里調(diào)用所有的本地包,可以先在 space-play 包里安裝其它本地包,再安裝該包行。
嘗試一下:
在 workspace 里查找 packages/space-play,并在該包里安裝 @space-play/components @space-play/hooks @space-play/utils 等依賴包
pnpm -r --filter ./packages/space-play add @space-play/components @space-play/hooks @space-play/utils
在 space-play 新建 index.ts 文件夾并導(dǎo)出所有依賴包
// packages/space-play/index.ts
import type { App } from 'vue'
export * from '@space-play/components'
export * from '@space-play/hooks'
export * from '@space-play/utils'
export default {
install(app: App) {
console.log('已使用 space-play 包,但該包里什么都沒有')
},
version: '0.0.1' // 這里只是作為示例,實(shí)際應(yīng)該獲取 package.json 里的版本
}到 apps/play1 里使用 space-play 包
pnpm -r --filter ./apps/play1 add space-play
在 apps/play1 新建一個簡單的項(xiàng)目結(jié)構(gòu)并安裝相關(guān)依賴
demo1/apps/play1 | app.vue | index.html | index.ts | package.json | vite.config.ts
可以看到,這個項(xiàng)目里面用到 vue、vite,這兩個依賴在 monorepo 里面的其它項(xiàng)目包里都會用到,所以我們在根目錄里面進(jìn)行安裝,同時安裝 vite 解析 vue 的插件
pnpm add -w vue pnpm add -w -D vite @vitejs/plugin-vue
可以看到這里用了兩條命令并在第二條命令中多了個 -D 參數(shù),因?yàn)?nbsp;vite 在編譯后不需要,而 vue 是需要的,所以一個安裝在常用依賴,一個開發(fā)依賴
打開 ./apps/play1/package.json,對他加點(diǎn)料,文件內(nèi)原本的參數(shù)不動,這里只顯示添加的,后續(xù)也如此
{
...,
"scripts": {
"dev": "vite"
}
}文件 app.vue 和 index.html
<!-- app.vue -->
<template>
<div>打開了 app.vue</div>
</template>
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.ts"></script>
</body>
</html>文件 apps/play1/index.ts 和普通 vue 項(xiàng)目的 main.ts 基本一致
import { createApp } from 'vue'
import SpacePlay from 'space-play'
import App from './app.vue'
createApp(App).use(SpacePlay).mount('#app')文件 apps/play1/vite.config.ts 和普通 vue 項(xiàng)目的 main.ts 基本一致
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
});到這里,一個基于 pnpm workspace 的 monorepo 項(xiàng)目基本完成,剩下的不過是在該項(xiàng)目內(nèi)的填充。
注意!項(xiàng)目目前還不能夠正常運(yùn)行,因?yàn)樵?nbsp;packages/components packages/hooks packages/utils 還沒有新建 index.ts 文件并這這些目錄下的 package.json 配置 main 入口
如果你在上面過程中發(fā)現(xiàn)了這個問題并手動創(chuàng)建并配置了,那么完成根目錄的 scripts 配置后就可以運(yùn)行項(xiàng)目試試效果了。
{
...,
"scripts": {
"play1": "pnpm -C apps/play1 dev"
}
}pnpm run play1 ? Local: http://localhost:5173/
通過瀏覽器打開,我們可以看到頁面顯示符合預(yù)期的內(nèi)容

以上就是pnpm workspace管理monorepo項(xiàng)目使用過程詳解的詳細(xì)內(nèi)容,更多關(guān)于pnpm workspace管理monorepo的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Node.js如何響應(yīng)Ajax的POST請求并且保存為JSON文件詳解
這篇文章主要介紹了關(guān)于Node.js是如何響應(yīng)Ajax的POST請求并且保存為JSON文件的相關(guān)資料,文中介紹的很詳細(xì),對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-03-03
node實(shí)現(xiàn)簡單的增刪改查接口實(shí)例代碼
在本篇文章里小編給大家整理的是關(guān)于node實(shí)現(xiàn)簡單的增刪改查接口的相關(guān)實(shí)例內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2019-08-08
Node.js全棧知識點(diǎn)超詳細(xì)整理(含代碼示例+前端結(jié)合實(shí)戰(zhàn))
在實(shí)時應(yīng)用程序領(lǐng)域,Node.js非常適合構(gòu)建聊天應(yīng)用、實(shí)時協(xié)作工具、在線游戲等,通過Socket.IO、WebSocket等技術(shù),能夠?qū)崿F(xiàn)實(shí)時數(shù)據(jù)傳輸和雙向通信,這篇文章主要介紹了Node.js全棧知識點(diǎn)(含代碼示例+前端結(jié)合實(shí)戰(zhàn))的相關(guān)資料,需要的朋友可以參考下2026-06-06
NodeJs使用webpack打包項(xiàng)目的方法詳解
這篇文章主要為大家詳細(xì)介紹了NodeJs使用webpack打包項(xiàng)目的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02
如何用node.js作為后臺,讀寫xml文件,Node.js的文件系統(tǒng)的Api
這篇文章主要介紹了如何用node.js作為后臺,讀寫xml文件,Node.js的文件系統(tǒng)的Api,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
詳解Node.js開發(fā)中的express-session
express-session?是基于express框?qū)iT用于處理session的中間件,本篇文章主要介紹了詳解Node.js開發(fā)中的express-session,有興趣的可以了解一下<BR>2017-05-05
node登錄生成token并驗(yàn)證的實(shí)現(xiàn)
token校驗(yàn)作為項(xiàng)目里的必要項(xiàng),其重要性不言而喻,本文主要介紹了node登錄生成token并驗(yàn)證的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-02-02
詳解node+express+ejs+bootstrap構(gòu)建項(xiàng)目
本篇文章主要介紹了詳解node+express+ejs+bootstrap構(gòu)建項(xiàng)目,非常具有實(shí)用價值,需要的朋友可以參考下2017-09-09
Nodejs封裝類似express框架的路由實(shí)例詳解
在本篇文章里小編給大家整理的是關(guān)于Nodejs封裝類似express框架的路由實(shí)例內(nèi)容,有需要的朋友們學(xué)習(xí)下。2020-01-01

