最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端pnpm?workspace架構(gòu)實(shí)例詳解

 更新時間:2026年02月02日 09:55:10   作者:瓏墨  
pnpm作為新一代包管理工具,解決了npm和yarn在依賴管理中的效率問題,它采用獨(dú)特的網(wǎng)狀+平鋪結(jié)構(gòu),顯著提升安裝速度并優(yōu)化磁盤空間,這篇文章主要介紹了前端pnpm?workspace架構(gòu)的相關(guān)資料,需要的朋友可以參考下

前言

一篇幫你搞懂 pnpm workspace 的實(shí)戰(zhàn)向教程,從「為啥要用」到「怎么配」全給你捋清楚;每個知識點(diǎn)都會講清是什么、為什么、怎么用、注意啥,方便你系統(tǒng)學(xué)習(xí)、隨時查閱、直接落地。

一、先聊聊:我們到底遇到了啥問題?

做前端久了,多包、monorepo、組件庫聯(lián)調(diào)這些事一多,就會踩到一堆具體又磨人的坑。下面把這些痛點(diǎn)拆開說:具體表現(xiàn) → 典型場景 → 對你有啥影響。搞清楚這些,后面再看 pnpm workspace 解決啥就一目了然。

1.1node_modules膨脹,磁盤和時間都遭殃

具體表現(xiàn):用 npm 搞 monorepo 時,根目錄一個 node_modules,每個子包再來一個;或者多個獨(dú)立項(xiàng)目各自一份。每個 node_modules 里,npm 會做扁平化:把子依賴提升到頂層,同一份包可能在不同項(xiàng)目的 node_modules 里各存一份,重復(fù)拷貝。

典型場景:比如你有一個 monorepo,里面 5 個 app、3 個共享庫,都用 React、lodash、一堆 Babel/Webpack 相關(guān)包。單項(xiàng)目 node_modules 可能就 400~600MB,monorepo 里再乘上包數(shù)量、加上提升帶來的重復(fù),輕松破 2GB。npm install 第一次全量裝要幾分鐘,以后每次 npm ci 或清緩存重裝,體感也很慢。

影響:占磁盤、拉代碼慢、CI 緩存大、流水線耗時增加;本機(jī)多開幾個項(xiàng)目,node_modules 動不動幾十 GB。

1.2 依賴版本亂成一鍋粥:幽靈依賴與沖突

幽靈依賴的定義:某個包沒有在你自己的 package.jsondependencies / devDependencies 里聲明,你卻能在代碼里 importrequire 到它。常見原因就是 npm 的扁平化:你裝了 A,A 依賴 B,B 被提升到了項(xiàng)目根 node_modules,于是你的代碼「意外」地能直接用 B。

典型場景:你習(xí)慣性 import _ from 'lodash',但從沒在 package.json 里加過 lodash,因?yàn)樗悄硞€依賴的子依賴,被提升上來了。后來你升級了那個依賴,人家不再依賴 lodash,或者換了版本,你這邊沒改一行業(yè)務(wù)代碼就報(bào)錯:找不到 lodash。更坑的是「本地能跑、CI 掛」:本地可能還有別的路徑殘留或緩存,CI 干凈安裝就炸。同理,刪了某個你以為沒用的依賴,結(jié)果別的地方一直隱式用著,一刪就掛。

版本沖突:A 包要 React 18,B 包要 React 17,扁平化之后只能滿足一邊,另一邊可能用了「不對」的版本,運(yùn)行時才暴露問題,調(diào)試成本很高。

1.3 本地包聯(lián)調(diào)賊麻煩:npm link的坑

典型場景:你維護(hù)一個業(yè)務(wù)組件庫,要在另一個前端項(xiàng)目里聯(lián)調(diào)。通常做法是 npm link:在組件庫目錄 npm link,在業(yè)務(wù)項(xiàng)目里 npm link your-components。但經(jīng)常會遇到:

  • 雙實(shí)例問題:React、Vue 等對「單實(shí)例」有要求,link 過去可能出現(xiàn)兩個版本,引發(fā)詭異 bug。
  • bin 路徑:某些 CLI 或工具通過 node_modules/.bin 找可執(zhí)行文件,link 后路徑解析不對,跑不起來。
  • 不同 Node 版本 / 環(huán)境: link 的是「當(dāng)時本機(jī)」的構(gòu)建結(jié)果,換機(jī)器、換 Node、改點(diǎn)配置,行為可能不一致。

總之,改一下組件庫就要反復(fù) link、unlink、重裝,體驗(yàn)很差,也容易忘步驟導(dǎo)致聯(lián)調(diào)結(jié)果不可靠。

1.4 CI 又慢又占空間

典型場景:每次 CI 全量 npm install,沒有跨項(xiàng)目或跨 job 的 store 復(fù)用;緩存 key 設(shè)計(jì)不當(dāng)(例如只按 package.json 不按 lockfile),導(dǎo)致緩存命中率低,每次都幾乎全量裝。加上前面說的 node_modules 巨大,流水線耗時長、占用空間大,體驗(yàn)和成本都不好。

上面這些,本質(zhì)都可以歸為兩類問題:一是多包怎么組織、怎么一起開發(fā)、怎么發(fā)布(項(xiàng)目結(jié)構(gòu) + 工作流);二是依賴怎么存、怎么解析、怎么隔離(存儲與解析策略)。pnpm 的 workspace 就是在這兩方面同時發(fā)力的方案之一:多包管理 + 更合理的依賴存儲與解析。下面先把你可能最關(guān)心的——pnpm 底層是怎么干的——講清楚,再回頭看 workspace 具體解決了啥。

二、pnpm 底層原理:為啥能省空間、裝得快、依賴還干凈?

很多人只記住結(jié)論:「pnpm 省磁盤、快、沒幽靈依賴」,但不知道它到底咋做到的。這一節(jié)把存儲模型node_modules 結(jié)構(gòu)說透,你后面看配置、看優(yōu)缺點(diǎn)都會更有數(shù)。

2.1 全局 store:content-addressable + 硬鏈接

pnpm 有一個全局 store,所有安裝過的包都會先放進(jìn)這里,再通過硬鏈接掛到各個項(xiàng)目的 node_modules 里。

  • 存哪兒

    • Linux:默認(rèn) ~/.local/share/pnpm/store
    • macOS:默認(rèn) ~/Library/pnpm/store
    • Windows:默認(rèn) %LOCALAPPDATA%\pnpm\store(即 C:\Users\<你>\AppData\Local\pnpm\store
      若設(shè)置了 $XDG_DATA_HOME,Linux/macOS 會改用 $XDG_DATA_HOME/pnpm/store??赏ㄟ^ .npmrcstore-dir 覆蓋,例如 store-dir=D:\pnpm-store
  • content-addressable(按內(nèi)容尋址)
    包在 store 里按內(nèi)容哈希存,同一版本、同一份包只存一份。不同項(xiàng)目、不同 monorepo 子包,只要依賴的版本相同,都用這一份,去重、跨項(xiàng)目復(fù)用。

  • 硬鏈接
    硬鏈接可以理解為「同一份文件的多個路徑入口」,改一處全體生效,但不額外占磁盤。pnpm 從 store 把包硬鏈接到項(xiàng)目里的 node_modules/.pnpm/...,所以看起來每個項(xiàng)目都有一份,實(shí)際磁盤只存 store 里那一份。
    復(fù)制的區(qū)別:不占多余空間。和符號鏈接的區(qū)別:符號鏈接是「指向另一個路徑」的小文件,硬鏈接是文件系統(tǒng)層面的多路徑同一 inode,更省空間、也更穩(wěn)定(刪掉一個鏈接不會影響 store 里的那份,只要還有別的鏈接在)。

結(jié)果:同 monorepo、同樣依賴,用 pnpm 時磁盤占用往往只有 npm 的一半左右(常見 benchmark 結(jié)論),二次安裝時大量命中 store,pnpm install 明顯更快。

2.2node_modules的真實(shí)結(jié)構(gòu):非扁平 + 嚴(yán)格依賴

npm 會把依賴扁平化提升到頂層,所以你能「意外」用到子依賴;pnpm 不這么做,結(jié)構(gòu)是非扁平的。

目錄結(jié)構(gòu)示意(精簡版):

  • 項(xiàng)目根目錄的 node_modules/

    • 只放你直接聲明的依賴(dependencies / devDependencies 里的包)。
    • 這些「包名」多數(shù)是符號鏈接,指向 node_modules/.pnpm/<pkg>@<version>/node_modules/<pkg>。
  • node_modules/.pnpm/

    • 里面才是實(shí)際內(nèi)容(或鏈到 store)。
    • 每個 package@version 一個目錄,且每個包有自己的 node_modules,里面只裝它自己的依賴。
    • 子依賴不會提升到項(xiàng)目根 node_modules,所以你沒法在業(yè)務(wù)代碼里 require('某個未聲明的子依賴')

嚴(yán)格依賴就是這樣實(shí)現(xiàn)的:
只有package.json 里顯式聲明的包,才會出現(xiàn)在你項(xiàng)目的 node_modules 頂層(或子包自己的 node_modules 里)。未聲明的包根本不在你可訪問的路徑下,require / import 會直接報(bào)錯,從根上杜絕幽靈依賴。

有些老舊工具會假設(shè)「所有依賴都在根 node_modules 扁平展開」,在 pnpm 默認(rèn)結(jié)構(gòu)下會找不到包。這時可以用 public-hoist-patternnode-linker=hoisted有限提升,相當(dāng)于在「兼容舊工具」和「嚴(yán)格依賴」之間做權(quán)衡;提升多了,幽靈依賴風(fēng)險(xiǎn)又回來了,所以能窄就窄。

2.3 workspace 包怎么被鏈接進(jìn)來?

當(dāng)你在 package.json 里寫 "@my/ui": "workspace:*" 時,pnpm 會:

  1. pnpm-workspace.yaml 定義的目錄里找到對應(yīng)包(如 packages/ui);
  2. 該包所在目錄(源碼目錄)鏈接到 node_modules 里對應(yīng)位置,不拷貝、不先打包。

所以,你改 packages/ui 的源碼,消費(fèi)方(例如 apps/web立即可見,不用 npm link,也沒有雙實(shí)例、路徑錯亂那些破事。這就是 workspace 協(xié)議 帶來的「本地包即源碼」的聯(lián)調(diào)體驗(yàn)。

2.4 和 npm / Yarn 的存儲對比(簡要)

  • npm:扁平化 + 每項(xiàng)目各自拷貝,多項(xiàng)目多份;易幽靈依賴;安裝速度、磁盤占用都一般。
  • Yarn:經(jīng)典模式類似 npm;Plug’n’Play 可選,但生態(tài)兼容性要看工具。
  • pnpm:全局 store + 硬鏈接 + 非扁平 node_modules,省空間、安裝快、默認(rèn)嚴(yán)格依賴。

差異主要在存儲與解析策略,而不是「有沒有 workspace」這個概念。

三、pnpm workspace 解決了什么問題?(深化版)

有了第二節(jié)的原理打底,這里直接說 workspace 在「多包管理」場景下,具體幫你解決了啥;每個點(diǎn)都往「能用、能查」上靠。

3.1 磁盤與安裝

  • store + 硬鏈接:全 workspace 共享同一 store,同版本依賴只存一份;子包、apps 裝依賴都是鏈過去,磁盤占用明顯低于 npm 同規(guī)模 monorepo(約一半量級的說法很常見)。
  • workspace 包不占 store:像 @my/utils、@my/ui 這種本地包,pnpm 只做鏈接到源碼目錄,不往 store 里塞,也不拷貝,改完即生效。
  • 安裝速度pnpm install 在 monorepo 里通常比 npm install 快不少,尤其二次安裝、CI 命中 store 時。

3.2 依賴隔離與一致性

  • 幽靈依賴
    pnpm 默認(rèn)嚴(yán)格依賴,未聲明就不能用。你刻意避免隱式依賴,配合 code review,能從根本上消滅「刪了某依賴突然掛」「本地有 CI 沒有」這類問題。
    若必須兼容舊工具,再考慮 public-hoist-pattern 有限提升,并清楚這會帶來隱性依賴風(fēng)險(xiǎn)。

  • 版本統(tǒng)一

    • 單一 lockfile:整個 workspace 只有一個 pnpm-lock.yaml 在根目錄,所有子包、所有環(huán)境的依賴解析都以它為準(zhǔn),版本全倉庫一致,復(fù)現(xiàn)性高。
    • catalog(pnpm 9+):在 pnpm-workspace.yaml 里定義 catalog,給常用依賴約定版本(如 react: ^18.3.1),子包用 catalog: 引用,升級時只改一處,避免各包各自為政。
    • overrides:根 package.json 里可配 pnpm.overrides,強(qiáng)制某依賴在全 workspace 解析成指定版本,適合解決傳遞依賴沖突、安全修復(fù)等。

3.3 多包協(xié)作與發(fā)布

  • 統(tǒng)一裝依賴、統(tǒng)一跑腳本:根目錄一次 pnpm install,所有 workspace 包依賴都裝好;用 pnpm -r run buildpnpm --filter ... 批量或定向跑腳本,配合根 package.jsonscripts,協(xié)作流程清晰。
  • 按需發(fā)布pnpm publish -r 可遞歸發(fā)布,結(jié)合 --filter 只發(fā)布改動的包;配合 changesets 做 version + changelog + publish,適合多包獨(dú)立發(fā)版。
  • 權(quán)限與發(fā)包:可以按包名、按目錄做 access 控制,和現(xiàn)有 npm registry 權(quán)限模型配合使用。

四、pnpm workspace 架構(gòu)長什么樣?

4.1 目錄樹與職責(zé)

下面是一個常見的 pnpm workspace 根目錄結(jié)構(gòu),以及各部分的職責(zé)。

項(xiàng)目根目錄
├── pnpm-workspace.yaml    # 聲明哪些目錄是 workspace 包(唯一、僅根目錄)
├── package.json           # 根包:公共 devDependencies、批量腳本、overrides 等
├── pnpm-lock.yaml         # 全 workspace 唯一 lockfile,所有人、CI 共用一個
├── .npmrc                 # 可選:store-dir、node-linker、hoist 等
├── packages/
│   ├── ui/                # 如:組件庫
│   ├── utils/             # 公共工具
│   ├── config-eslint/     # 共享 ESLint 配置
│   └── ...
└── apps/
    ├── web/               # 前端應(yīng)用
    ├── docs/              # 文檔站
    └── ...
  • 根 package.json

    • 全倉庫共用的 devDependencies(如 TypeScript、ESLint、Vitest、Prettier)。
    • 定義 scripts,用 pnpm -r--filter 批量或定向執(zhí)行子包的 build、dev、test。
    • 根包通常 "private": true,不發(fā)布;可加 packageManager、pnpm.overrides 等。
  • pnpm-workspace.yaml

    • 唯一,只能放在根目錄。
    • 通過 packages 數(shù)組聲明哪些目錄算 workspace 包(如 packages/*、apps/*),只有這些才能被 workspace:* 引用。
    • pnpm 官方推薦用這個文件,而不是 package.jsonworkspaces 字段。
  • pnpm-lock.yaml

    • 全 workspace 共用一個,在根目錄。
    • 鎖死所有依賴(含 workspace 包解析結(jié)果),保證任意環(huán)境 pnpm install 結(jié)果一致。
  • packages/*

    • 一般放可復(fù)用庫:組件庫、工具庫、配置包等。
    • 各自有 package.json,通過 workspace:* 相互依賴或被 apps/* 依賴。
  • apps/*

    • 一般放應(yīng)用:前端項(xiàng)目、文檔站、Demo 等。
    • 依賴 packages/* 時用 workspace:*,改庫即生效。

有的項(xiàng)目還會加 tools/* 放腳本、CLI 等,本質(zhì)上一樣:在 pnpm-workspace.yaml 里寫上對應(yīng) glob 即可。

4.2 命名與布局約定

  • packages:可復(fù)用、可能發(fā)布到 npm 的庫;apps:入口應(yīng)用、不發(fā)布或只發(fā)構(gòu)建產(chǎn)物。
  • 何時拆 apps?當(dāng)你明確有「多個應(yīng)用 + 共享 packages」時,拆開更清晰;只有一兩個 app 時,全放 packages 也沒問題,按團(tuán)隊(duì)習(xí)慣來。
  • 依賴方向
    • 子包互相依賴、app 依賴子包,一律用 workspace:*。
    • 禁止循環(huán)依賴(A 依賴 B,B 又依賴 A),否則安裝、構(gòu)建都會出問題。
    • 根包通常作為業(yè)務(wù)依賴,只提供腳本和公共 devDependencies。

4.3 workspace 包的解析與匹配機(jī)制

靠啥匹配?

pnpm 解析 workspace:* 時,只看 package.json 里的 name,和目錄名、路徑都無關(guān)。你寫 "@my/ui": "workspace:*",pnpm 就會在 pnpm-workspace.yaml 聲明的那堆目錄里,找 name 為 @my/ui 的包;找到就把該包所在目錄鏈進(jìn) node_modules,找不到就直接報(bào)錯,不會悄悄去 npm 裝一個。

具體流程

  1. pnpm-workspace.yaml,收集所有匹配 packages 的目錄(如 packages/*apps/*);
  2. 逐個讀這些目錄下的 package.json,拿到 name,建成一張 「name → 目錄」 的映射;
  3. 解析依賴時,遇到 workspace:*、workspace:^ 等,用依賴?yán)锏?strong>包名去這張表里查;
  4. 查到了 → 用該包所在目錄做鏈接目標(biāo),鏈到當(dāng)前包的 node_modules 里;
  5. 查不到 → 報(bào)錯(例如 ERR_PNPM_NO_MATCHING_PACKAGE),安裝中止。

所以:包名必須和依賴?yán)飳懙囊荒R粯?/strong>。packages/uiname 要是 @my/ui,別的地方才能 "@my/ui": "workspace:*";寫成 @my/components 就匹配不上。

幾種寫法

  • workspace:*:匹配 workspace 里同名包的任意版本,并鏈到源碼目錄;開發(fā)聯(lián)調(diào)最常用。
  • workspace:^、workspace:~:按 semver 匹配 workspace 內(nèi)版本;發(fā)布時會被替換成具體版本號(如 1.0.0),發(fā)布出去的 package.json 里不會還帶著 workspace:。
  • workspace:../packages/utils(相對路徑):明確指向某個目錄,不靠 name 匹配;適合臨時調(diào)試或路徑敏感的布局。

別名

可以用 "別名": "workspace:真實(shí)包名@*" 把 workspace 包掛到另一個名字下,例如 "react": "workspace:my-react@*"。發(fā)布時同樣會替換成普通依賴形式。

找不到會怎樣?
只會報(bào)錯,不會回退到 npm 裝。這樣你才能確定:用的一定是本地的 workspace 包,沒有誤用遠(yuǎn)端的。

4.4 依賴圖與構(gòu)建順序

workspace 里包和包之間的依賴關(guān)系,會形成一張有向圖:誰依賴誰,一目了然。pnpm 跑 pnpm -r run build 這類遞歸命令時,默認(rèn)按這張圖的拓?fù)漤樞?/strong>執(zhí)行:先跑被依賴的,再跑依賴別人的,避免「還沒 build 完就被別人 require」的坑。

拓?fù)漤樞蚴巧叮?/strong>

簡單說:若 A 依賴 B,則一定執(zhí)行 B 的 build,執(zhí)行 A 的 build。例如 utilsuiweb,順序就是 utilsuiweb。同一層之間(比如多個 app 互不依賴)誰先誰后不保證,但層級不會亂。

默認(rèn)行為

  • pnpm -r run build(以及 pnpm -r run <script>):按依賴圖拓?fù)渑判?/strong>,再依次執(zhí)行;沒有 -r 時則只跑當(dāng)前包。
  • pnpm -r --parallel run build不管順序,所有包并行跑;跑 dev、test 時常用 --parallel,但 build 一般要保證順序,所以慎用 --parallel

怎么知道誰依賴誰?

  • 看各包 package.jsondependencies / devDependencies 里對 workspace 包、普通包的引用;
  • pnpm why <pkg> 看某包被誰依賴;pnpm list -r 看全 workspace 的依賴樹(注意 list 默認(rèn)不按拓?fù)湫?,按字母序)?/li>
  • 有些團(tuán)隊(duì)會接 Turborepo、Nx 等,用它們畫依賴圖、跑拓?fù)洳⑿?build(同一層并行,層與層之間仍按依賴順序)。

循環(huán)依賴

若出現(xiàn) A → B → C → A,依賴圖成環(huán),拓?fù)渑判蚋悴欢ǎ琾npm 會報(bào)錯;安裝、-r 執(zhí)行都可能掛。所以必須保證 workspace 內(nèi)無環(huán),設(shè)計(jì)時就要避免「包互相依賴」。

4.5 安裝與打包:workspace 如何工作

安裝(pnpm install
根目錄執(zhí)行 pnpm install 時,大致會做這幾步:

  1. 讀 workspace 定義:解析 pnpm-workspace.yaml,得到所有 workspace 包目錄(如 packages/*apps/*)。
  2. 收集包信息:逐個讀這些目錄下的 package.json,建 name → 目錄 映射,并算出整棵依賴樹(含對 npm 包的依賴)。
  3. 解析 workspace:*:遇到 workspace:* 等,按 4.3 的規(guī)則匹配到本地包目錄,從 registry 拉包。
  4. 鏈接 workspace 包:把匹配到的本地包目錄鏈到各包的 node_modules 里(符號鏈接或 junction),不拷貝、不往 store 塞;改源碼立即生效。
  5. 裝外部依賴:對 npm 上的包,按平時那套來:store + 硬鏈接,裝到 node_modules/.pnpm 等位置。
  6. 寫 lockfile:把所有依賴(含 workspace:* 的解析結(jié)果)寫入根目錄的 pnpm-lock.yaml

所以:workspace 包只做鏈接,不占 store;占磁盤、耗時的主要是外部依賴,而它們?nèi)宰?store 復(fù)用。

打包 / 構(gòu)建(pnpm -r run build

構(gòu)建改依賴安裝方式,只是按依賴圖順序跑各包的 build 腳本:

  1. 算依賴圖:根據(jù)各包 package.json 的依賴關(guān)系,得到有向圖。
  2. 拓?fù)渑判?/strong>:排出「被依賴的在前、依賴別人的在后」的順序(pnpm 內(nèi)部用類似 graph-sequencer 的方式處理)。
  3. 依次執(zhí)行:按該順序?qū)γ總€ workspace 包執(zhí)行 pnpm run build(或你配的其它 script)。
  4. 若某包沒有 build 腳本,pnpm 會報(bào)錯或跳過該包,視配置而定。

因此:先裝依賴,再構(gòu)建;裝依賴保證 node_modules 里 workspace 包、npm 包都就位,構(gòu)建則按依賴順序生成各包產(chǎn)物。
若用 --parallel,pnpm 會忽略拓?fù)漤樞?/strong>,所有包一起跑;適合 dev、test 等不嚴(yán)格要求「被依賴的先跑」的場景,但 build 一般別開 --parallel,否則可能用到尚未 build 的依賴。

和 Turborepo / Nx 的關(guān)系

pnpm 只負(fù)責(zé)依賴安裝 + 按拓?fù)湫蚺?script;緩存、增量構(gòu)建、遠(yuǎn)程緩存等,可交給 Turborepo、Nx。通常做法是:pnpm 管 install 和 workspace 鏈接,Turbo/Nx 管 build / test 的調(diào)度與緩存,兩者一起用沒問題。

五、優(yōu)缺點(diǎn)一覽(夠直白版)+ 逐條詳解

5.1 優(yōu)點(diǎn)總覽

點(diǎn)說明
省磁盤、安裝快全局 store + 硬鏈接,避免重復(fù)存包;workspace 包用鏈接,不復(fù)制。
依賴干凈嚴(yán)格依賴,無幽靈依賴;lockfile 唯一,版本一致。
本地聯(lián)調(diào)友好workspace:* 直接鏈到源碼,改即生效,無需 npm link。
monorepo 友好內(nèi)建 workspace 支持,-r--filter 過濾、并行跑腳本很方便。
易于做權(quán)限與發(fā)布配合 pnpm publish -r、changesets 做按包發(fā)布、權(quán)限控制。

詳細(xì)說明

  • 省磁盤、安裝快:原理即第二節(jié)的 store + 硬鏈接;workspace 包不進(jìn) store,只做鏈接。典型收益是 monorepo 磁盤占用和 pnpm install 耗時明顯下降。
  • 依賴干凈:嚴(yán)格依賴 + 單一 lockfile,少很多「刪了某包就掛」「本地有 CI 沒有」的玄學(xué)問題;注意若用了 public-hoist-pattern 等,要控制范圍,否則又引入隱性依賴。
  • 本地聯(lián)調(diào):改 packages/ui 立刻在 apps/web 里生效,無需 link;注意跑 dev 的終端要在根目錄或?qū)?yīng) app 目錄,且已執(zhí)行過根目錄的 pnpm install
  • monorepo 友好pnpm -r、--filter 能力足,再配合 Turborepo/Nx 做任務(wù)編排、緩存,體驗(yàn)更好。
  • 發(fā)布:按包發(fā)布、changesets 管理版本與 changelog,和現(xiàn)有 registry 流程兼容。

5.2 缺點(diǎn) / 注意點(diǎn)總覽

點(diǎn)說明
和 npm 不完全兼容部分工具假設(shè)「所有依賴扁平在根 node_modules」,可能報(bào)錯,需適配。
學(xué)習(xí)與遷移成本團(tuán)隊(duì)要搞懂 workspace、workspace:*、pnpm-workspace.yaml、--filter 等。
部分舊工具兼容性極端老舊的構(gòu)建/調(diào)試工具對 pnpm 的 node_modules 結(jié)構(gòu)可能不友好。
需統(tǒng)一包管理全 repo 必須用 pnpm,不能混用 npm/yarn,否則 lockfile、鏈接會亂。

詳細(xì)說明

  • 和 npm 不完全兼容
    有些 Webpack 插件、老版 Babel、個別 CLI 會直接去根 node_modules 找包,pnpm 默認(rèn)非扁平就可能找不到。處理辦法:

    • node-linker=hoisted.npmrc)切回類 npm 扁平結(jié)構(gòu),會犧牲嚴(yán)格依賴;
    • 或只用 public-hoist-pattern 把有問題的包提升上來,盡量窄配。
  • 學(xué)習(xí)與遷移成本
    團(tuán)隊(duì)至少要會:workspace 概念、pnpm-workspace.yaml、workspace:* 協(xié)議、根目錄 pnpm install、--filter-r 的用法。可以抽半小時過一遍本文 + 官方文檔,再在試點(diǎn)項(xiàng)目跑一遍。

  • 舊工具兼容性
    建議先小范圍試點(diǎn),遇到具體工具再查 pnpm 兼容性 或社區(qū) issue;大多數(shù)現(xiàn)代前端工具已支持。

  • 統(tǒng)一包管理
    全倉庫只用 pnpm,禁止 npm install / yarn。用 packageManager 鎖版本,CI 里 corepack enable && pnpm install,避免有人用錯包管理器導(dǎo)致 lockfile 或鏈接關(guān)系錯亂。

適合:中大型前端項(xiàng)目、組件庫 + 多應(yīng)用、多包復(fù)用的 monorepo。

不大適合:單應(yīng)用、沒有多包復(fù)用需求的小項(xiàng)目;用 pnpm 單倉也能受益,但 workspace 收益有限。

六、應(yīng)用場景(什么時候上 workspace?)

下面按場景拆:誰用、解決啥問題、推薦結(jié)構(gòu)、關(guān)鍵配置、日常工作流。你對照自己項(xiàng)目,能直接套用或微調(diào)。

6.1 UI 組件庫 + 多個業(yè)務(wù)項(xiàng)目

場景:你們有一個業(yè)務(wù)組件庫,要同時支撐 2~3 個前端項(xiàng)目;組件庫頻繁迭代,需要在各項(xiàng)目里即時驗(yàn)證,而不是先發(fā) npm 再裝。

推薦結(jié)構(gòu)

packages/
  ui/           # 組件庫
apps/
  web-admin/
  web-h5/
  web-docs/     # 組件文檔

web-admin、web-h5、web-docs 都依賴 @my/ui,用 workspace:*。

關(guān)鍵配置

  • pnpm-workspace.yamlpackages: ['packages/*', 'apps/*']
  • 各 app 的 package.json"@my/ui": "workspace:*"。
  • scripts:如 "dev:docs": "pnpm --filter web-docs run dev""build:ui": "pnpm --filter @my/ui run build"。

工作流

packages/ui → 在 apps/web-docs 或任意 app 里直接看效果;要發(fā)版時用 changesets 給 @my/ui 打 version、寫 changelog、publish,各 app 再決定何時把 workspace:* 換成固定版本(若你們發(fā) npm 的話)。

6.2 多應(yīng)用 + 公共 utils / config

場景:多條產(chǎn)品線、多個前端應(yīng)用,共享 utilsapi-client、eslint-config 等,希望統(tǒng)一版本、統(tǒng)一升級。

推薦結(jié)構(gòu)

packages/
  utils/
  api-client/
  config-eslint/
apps/
  app-a/
  app-b/

apps 按需依賴 @my/utils@my/api-client;config-eslint 被各 app 的 devDependencies 引用。

關(guān)鍵配置

  • pnpm-workspace.yaml:同上。
  • 各包用 workspace:* 互引;根 package.json 可放公共 devDependencies,或用 catalog 統(tǒng)一 React、TypeScript 等版本。
  • 根腳本:"build": "pnpm -r --filter './apps/*' run build",只構(gòu)建 apps。

工作流
公共邏輯在 packages/* 改,各 app 自動用到;發(fā)版用 changesets 按包發(fā)布,各 app 通過 workspace:* 或固定版本消費(fèi)。

6.3 文檔站 + 組件庫

場景:組件庫配套一個文檔站(如 VitePress、Docusaurus),文檔站要直接引用源碼里的組件做 Demo,而不是已發(fā)布的 npm 包。

推薦結(jié)構(gòu)

packages/
  ui/
apps/
  docs/

docs 依賴 @my/ui,workspace:*。

關(guān)鍵配置

  • 同上,packages + appsdocs"@my/ui": "workspace:*"。
  • 文檔站構(gòu)建配置里保證能解析 packages/ui 的源碼(通常 workspace 鏈接后沒問題)。

工作流

改組件 → 跑 docs 的 dev,文檔里實(shí)時看效果;發(fā)版時先發(fā) @my/ui,再更新文檔站里對版本的說明(若文檔站自己也要發(fā))。

6.4 全棧 monorepo(前后端同倉)

場景:前端 + Node 服務(wù)同倉,共享類型、常量或少量 utils,用同一套依賴管理。

推薦結(jié)構(gòu)

packages/
  types/
  shared-utils/
apps/
  web/
  api/          # Node 服務(wù)

apiweb 都依賴 @my/types、@my/shared-utils,workspace:*。

關(guān)鍵配置

  • pnpm-workspace.yaml 包含 packages/*apps/*。
  • package.jsonscripts 里分別 --filter web--filter api 跑 dev/build。

工作流

typesshared-utils,前后端同時生效;各自部署時只構(gòu)建對應(yīng) app,公共邏輯通過 workspace 鏈進(jìn)去。

只要你存在「多個包 + 互相依賴 + 要一起開發(fā)」的需求,workspace 就很值得上;上面四種可以組合,比如「組件庫 + 多應(yīng)用 + 文檔站」一起做。

七、詳細(xì)教程:從零搭一個 pnpm workspace

下面按步驟做一遍,每步會寫操作、預(yù)期結(jié)果、常見報(bào)錯與排查。路徑、包名和上文保持一致,你照抄就能跑通。

7.1 環(huán)境準(zhǔn)備

  • 安裝 pnpm

    npm install -g pnpm
    

    或用 Corepack(Node 16.9+):

    corepack enable
    corepack prepare pnpm@latest --activate
    

    建議用 pnpm 8.x 或 9.x,Node 18+ 更省心。

  • 校驗(yàn)

    pnpm -v
    node -v
    

    看到版本號即成功。

7.2 初始化根項(xiàng)目

mkdir my-workspace && cd my-workspace
pnpm init

會生成根目錄 package.json。編輯成類似:

{
  "name": "my-workspace",
  "version": "1.0.0",
  "private": true,
  "packageManager": "pnpm@9.0.0"
}
  • private: true:根包不會被 pnpm publish 發(fā)出去,避免誤發(fā)。
  • packageManager:鎖死 pnpm 版本,配合 corepack enable 使用;可選但推薦。

7.3 配置pnpm-workspace.yaml

項(xiàng)目根目錄新建 pnpm-workspace.yaml

packages:
  - 'packages/*'
  - 'apps/*'
  • packages/*packages/ 下每個子目錄(如 packages/ui、packages/utils)都算一個 workspace 包。
  • apps/*:同理。
  • 只有被列出來的目錄才會被 pnpm 當(dāng)成 workspace 成員,才能被 workspace:* 引用。

預(yù)期:保存后暫無輸出;之后 pnpm install 時 pnpm 會掃描這些目錄。

7.4 創(chuàng)建子包目錄并初始化

mkdir -p packages/ui packages/utils apps/web

然后逐個初始化(Windows 用戶可用 PowerShell,mkdir -p 若不可用就分步 mkdir):

cd packages/utils && pnpm init && cd ../..
cd packages/ui   && pnpm init && cd ../..
cd apps/web      && pnpm init && cd ../..

Windows:若 mkdir -p 報(bào)錯,可改為 mkdir packages\uimkdir packages\utils、mkdir apps\web 等分步創(chuàng)建;cd ../.. 在 PowerShell 中同樣適用。)

每個子包會多一個 package.json。接下來改包名、入口、exports。

packages/utils/package.json

{
  "name": "@my/utils",
  "version": "0.0.1",
  "main": "index.js",
  "exports": {
    ".": "./index.js"
  }
}

packages/ui/package.json

{
  "name": "@my/ui",
  "version": "0.0.1",
  "main": "index.js",
  "exports": {
    ".": "./index.js"
  }
}

apps/web/package.json

{
  "name": "web",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "dev": "echo \"dev placeholder\"",
    "build": "echo \"build placeholder\""
  }
}
  • exports:現(xiàn)代 Node 和打包器都認(rèn),用來明確入口,避免多余文件被引用;對 ESM、TS 等更友好。
  • webdev/build 先占位,后面驗(yàn)證完 workspace 再換成真實(shí)命令。

7.5 用workspace:*做包間依賴

packages/ui/package.json 里加依賴 @my/utils

{
  "name": "@my/ui",
  "version": "0.0.1",
  "main": "index.js",
  "exports": { ".": "./index.js" },
  "dependencies": {
    "@my/utils": "workspace:*"
  }
}

apps/web/package.json 里加依賴 @my/ui

{
  "name": "web",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "dev": "echo \"dev placeholder\"",
    "build": "echo \"build placeholder\""
  },
  "dependencies": {
    "@my/ui": "workspace:*"
  }
}

workspace:* 表示「用當(dāng)前 workspace 里的同名包,追蹤源碼」;裝完依賴后會鏈接到對應(yīng)包目錄,改代碼即時生效。

7.6 根目錄執(zhí)行pnpm install

務(wù)必在根目錄執(zhí)行(若不在根目錄,先 cd 到項(xiàng)目根):

pnpm install

預(yù)期

  • 根目錄出現(xiàn) node_modules/pnpm-lock.yaml;
  • packages/ui、apps/webnode_modules 里會有 @my/utils、@my/ui 的鏈接;
  • lockfile 里能看到對 workspace: 的解析,例如:
packages:
  '@my/utils@workspace:*':
    resolution: { directory: packages/utils, type: directory }
  '@my/ui@workspace:*':
    resolution: { directory: packages/ui, type: directory }

(省略其他字段;實(shí)際 lockfile 還有 nameversion 等。)

若報(bào) ERR_PNPM_NO_MATCHING_PACKAGE:檢查 pnpm-workspace.yamlpackages 是否包含對應(yīng)目錄,以及子包 name 是否和依賴?yán)飳懙囊恢隆?/p>

7.7 根package.json里加批量腳本

根目錄 package.json 增加:

{
  "name": "my-workspace",
  "version": "1.0.0",
  "private": true,
  "packageManager": "pnpm@9.0.0",
  "scripts": {
    "dev": "pnpm -r --parallel run dev",
    "build": "pnpm -r run build",
    "build:web": "pnpm --filter web run build"
  },
  "devDependencies": {
    "typescript": "^5.0.0"
  }
}
  • pnpm -r:遞歸在所有 workspace 包里執(zhí)行同名 script。
  • pnpm -r --parallel:并行跑,適合 dev。
  • pnpm --filter web run build:只對 web 包執(zhí)行 build。

Windows:若使用 PowerShell,scripts 里的雙引號、&& 等和 Unix 略有差異,一般上述寫法沒問題;若遇解析錯誤,可改為 node 跑一小段腳本封裝命令。

7.8 驗(yàn)證 workspace 鏈路

  • packages/utils/index.js 寫:
module.exports = { add: (a, b) => a + b };
  • packages/ui/index.js 寫:
const { add } = require('@my/utils');
module.exports = { add, hello: 'from ui' };
  • apps/web 里加個臨時腳本驗(yàn)證。給 apps/web/package.jsonscripts 增加一行 "run:check",例如:
"scripts": {
  "dev": "echo \"dev placeholder\"",
  "build": "echo \"build placeholder\"",
  "run:check": "node -e \"const x=require('@my/ui'); console.log(x.add(1,2), x.hello)\""
}

保存后,在根目錄執(zhí)行:

pnpm --filter web run run:check

預(yù)期輸出3 'from ui'

Cannot find module '@my/ui'

  • 確認(rèn)在根目錄執(zhí)行過 pnpm install;
  • 確認(rèn) apps/webdependencies 里有 "@my/ui": "workspace:*"
  • 看看 apps/web/node_modules/@my 下是否有 ui 的鏈接。

ENOENT 等路徑類錯誤:

  • 檢查 packages/utils、packages/ui 是否有 index.js,以及 package.jsonmain / exports 是否指向它。

驗(yàn)證通過后,可以把 webdev / build 換成真實(shí)命令(如 Vite、Next 等),繼續(xù)開發(fā)。

八、配置說明(可查閱手冊)

這一節(jié)把 pnpm workspace 相關(guān)配置 拆開講:每項(xiàng)是啥、怎么配、適用場景、注意點(diǎn)。方便你以后查。

8.1pnpm-workspace.yaml

  • 唯一性:整個倉庫只放一個在根目錄;pnpm 只認(rèn)根目錄這份。
  • packages
    • 字符串?dāng)?shù)組,每個元素是一個 glob 或具體路徑。
    • 例:'packages/*''apps/*'、'tools/*',或 'packages/ui'、'packages/utils'。
    • 只有匹配到的目錄且其中包含 package.json,才會被當(dāng)作 workspace 包。
  • 排除:部分版本支持 ! 排除,如 !'packages/legacy/*',以你用的 pnpm 文檔為準(zhǔn)。
  • package.jsonworkspaces:pnpm 官方推薦用 pnpm-workspace.yaml 定義 workspace,不用 workspaces 字段;若同時存在,以 pnpm-workspace.yaml 為準(zhǔn)。

示例

packages:
  - 'packages/*'
  - 'apps/*'
  - 'tools/*'

8.2 根目錄package.json

  • private: true:根包不發(fā)布,避免誤 pnpm publish。
  • packageManager:如 "pnpm@9.0.0",鎖包管理器 + 版本;需 corepack enable。
  • scripts:結(jié)合 pnpm -r--filter 做批量或定向執(zhí)行(見 8.6)。
  • pnpm.overrides:強(qiáng)制某依賴在全 workspace 解析成指定版本。
    {
      "pnpm": {
        "overrides": {
          "lodash": "4.17.21"
        }
      }
    }
    
    裝依賴時 pnpm 會按 overrides 解析,并反映在 lockfile;適合修安全漏洞、解決傳遞依賴沖突。
  • catalog(pnpm 9+):在 pnpm-workspace.yaml 里定義(不是 package.json),子包用 catalog: 引用;見下方示例。

catalog 示例pnpm-workspace.yaml):

packages:
  - 'packages/*'
  - 'apps/*'

catalog:
  react: ^18.3.1
  react-dom: ^18.3.1

子包 package.json

{
  "dependencies": {
    "react": "catalog:",
    "react-dom": "catalog:"
  }
}

升級時只改 catalog 即可,所有用 catalog: 的包一起變。

8.3workspace:協(xié)議

  • workspace:*:用當(dāng)前 workspace 里同名包任意版本,并鏈接到源碼目錄。開發(fā)聯(lián)調(diào)默認(rèn)用這個。
  • workspace:^workspace:~:按 semver 匹配 workspace 內(nèi)版本;發(fā)布時 pnpm 會把它替換成實(shí)際版本號(如 1.0.0),所以發(fā)布到 npm 的包不會還帶著 workspace:。
  • 鎖文件里的表現(xiàn)
    '@my/ui@workspace:*':
      resolution: { directory: packages/ui, type: directory }
    
    表示解析為本地 packages/ui 目錄。

日常開發(fā) workspace:* 就夠用;若你們有嚴(yán)格的 semver 約束再考慮 ^ / ~。

8.4pnpm-lock.yaml

  • 唯一:整份 workspace 共用一個 lockfile,放在根目錄。
  • 內(nèi)容:鎖住所有依賴(含 workspace 解析結(jié)果)的版本、完整性校驗(yàn)等。
  • 維護(hù):用 pnpm install、pnpm add 等變更依賴,不要手改。
  • CI:務(wù)必把 pnpm-lock.yaml 納入 git;CI 里 pnpm install --frozen-lockfile 可保證和 lockfile 完全一致,復(fù)現(xiàn)構(gòu)建。

8.5.npmrc(項(xiàng)目級)

放在項(xiàng)目根目錄,只影響當(dāng)前倉庫。

常見項(xiàng):

配置項(xiàng)含義示例
store-dir全局 store 路徑store-dir=D:\pnpm-store
node-linker鏈接方式isolated(默認(rèn))/ hoisted
hoisted已廢棄,用 node-linker
public-hoist-pattern哪些包提升到根 node_modulespublic-hoist-pattern[]=*eslint*
shamefully-hoist全部提升,類似 npmtrue,易幽靈依賴,慎用
auto-install-peers自動裝 peerDependenciestrue
strict-peer-dependenciespeer 未滿足時報(bào)錯true
  • node-linker=hoisted:切回類 npm 扁平結(jié)構(gòu);兼容性好,但失去嚴(yán)格依賴。
  • public-hoist-pattern:只把匹配的包提升,例如 ESLint、Prettier 等工具常見需求;能窄就窄,減少幽靈依賴。
  • resolution-mode:依賴解析策略(如 lowest-direct);lockfile-include-tty 等可按需查文檔。

示例(只提升部分工具):

public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*

8.6--filter完整語法

--filter 用來限定要對哪些 workspace 包執(zhí)行命令,常與 pnpm -r、pnpm add 等一起用。

寫法含義示例
--filter <pkg>指定包(按 name 或路徑)pnpm --filter web run build
--filter <pkg>...pkg 以及依賴了 pkg 的所有包(dependents)pnpm -r --filter '@my/ui...' run build
--filter ...<pkg>pkg 以及 pkg 依賴的所有包(dependencies)pnpm -r --filter '...web' run build
--filter ...^<pkg>依賴了 pkg 的包,不含 pkg 自身pnpm -r --filter '...^@my/ui' run test
@scope/*通配,所有 @scope 下包pnpm -r --filter '@my/*' run build

示例

# 只給 web 裝 lodash
pnpm add lodash --filter web

# 只給名字匹配 @my/* 的包跑 build
pnpm -r --filter '@my/*' run build

# 只給依賴了 @my/ui 的包跑 test(不含 @my/ui 自身,例如 web、docs)
pnpm -r --filter '...^@my/ui' run test

# 只給 web 及其依賴的 workspace 包跑 build(含 web 自身)
pnpm -r --filter '...web' run build

多 filter 可組合,例如 --filter '@my/ui...' --filter web 表示滿足任一條件的包。僅要「依賴了某包」的包且排除該包本身時,用 ...^<pkg>。

8.7 依賴提升(hoisting)

  • 默認(rèn):pnpm 不提升,依賴裝在各自包的 node_modules.pnpm 下,嚴(yán)格隔離。
  • public-hoist-pattern:把匹配的包額外提升到根 node_modules,方便某些工具查找;提升范圍越大,幽靈依賴風(fēng)險(xiǎn)越高。
  • shamefully-hoist:幾乎全部提升,和 npm 類似;不推薦,除非你只是臨時兼容舊工具。

對比

  • 不提升:根 node_modules 只有直接依賴,子依賴在 .pnpm 里,嚴(yán)格。
  • 提升后:根 node_modules 會出現(xiàn)被提升的包,未聲明也可能被引用,所以要想清楚再開。

8.8 只用 pnpm / 鎖包管理

  • 全倉庫統(tǒng)一用 pnpm,禁止 npm、yarn,否則 lockfile 和鏈接會亂。
  • package.json 設(shè) packageManager,如 "pnpm@9.0.0"
  • 啟用 Corepackcorepack enable;CI 里先 corepack enablepnpm install,保證版本一致。

九、和 npm / Yarn workspace 的簡單對比

能力npm workspacesYarn workspacepnpm workspace
磁盤占用高,多份拷貝一般低,store+硬鏈接
安裝速度一般較快
node_modules 結(jié)構(gòu)扁平扁平或 PnP非扁平,.pnpm
幽靈依賴易出現(xiàn)默認(rèn)嚴(yán)格,無
lockfile 格式package-lock.jsonyarn.lockpnpm-lock.yaml
workspace 協(xié)議workspace:*workspace:*workspace:*
配置方式package.json workspacespackage.json workspacespnpm-workspace.yaml
filter/scripts無內(nèi)置 filter有 workspaces 腳本-r--filter
CI 緩存友好度一般較好好(store 可復(fù)用)

何時選 pnpm workspace

  • 你打算認(rèn)真搞 monorepo、多包復(fù)用,且關(guān)注磁盤、安裝速度、依賴干凈。
  • 愿意統(tǒng)一用 pnpm,并接受一點(diǎn)學(xué)習(xí)與遷移成本。

何時繼續(xù)用 npm / Yarn

  • 現(xiàn)有 npm/Yarn 腳本、CI 已經(jīng)很成熟,團(tuán)隊(duì)不想動。
  • 單倉庫、包很少,workspace 收益有限,用 pnpm 單倉也不錯,不必非上 workspace。

pnpm 的差異主要來自存儲與解析策略,而不是「有沒有 workspace」本身。

十、進(jìn)階與延伸

10.1 發(fā)版:按包發(fā)布 + changesets

  • pnpm publish -r:遞歸發(fā)布所有 未 private 的 workspace 包;可加 --filter 只發(fā)改動的,例如先 pnpm -r --filter '@my/ui...' run buildpnpm publish -r --filter '@my/ui'
  • changesets
    • changeset 管理 version bumpchangelog;
    • 流程大致:改代碼 → pnpm changeset 選包、選版本類型、寫 changelog → pnpm changeset version 更新版本號 → pnpm publish -r 發(fā)布。
      這樣多包獨(dú)立發(fā)版、可追溯,很常見。

10.2 任務(wù)編排:Turborepo / Nx

  • package.jsonbuilddev 等可以交給 TurboNx 跑:他們按依賴圖做拓?fù)渑判?/strong>,只跑該跑的,且能做遠(yuǎn)程/本地緩存,加速 CI 和本地構(gòu)建。
  • pnpm workspace 只負(fù)責(zé)依賴安裝與鏈接;Turborepo/Nx 負(fù)責(zé)任務(wù)調(diào)度,兩者配合良好。

10.3 參考

十一、小結(jié)與 FAQ

11.1 小結(jié)

  • 問題:多包重復(fù)安裝、幽靈依賴、本地聯(lián)調(diào)麻煩、CI 又慢又占空間 → 本質(zhì)是多包管理 + 依賴存儲/解析沒做好;pnpm workspace 針對這兩點(diǎn)設(shè)計(jì)。
  • 原理:全局 store + 硬鏈接省空間、提速;非扁平 node_modules + 嚴(yán)格依賴防幽靈依賴;workspace 包鏈到源碼,改即生效。
  • 架構(gòu):根 pnpm-workspace.yaml + 根 package.json + 唯一 pnpm-lock.yaml + packages/* / apps/*;子包用 workspace:* 互引,禁止循環(huán)依賴。
  • 配置:弄清 pnpm-workspace.yaml、根 package.jsonworkspace: 協(xié)議、.npmrc 常用項(xiàng)、--filter 用法即可上手。
  • 建議:按第七節(jié)親手搭一遍,再在一個小項(xiàng)目里拆一個 utils 包用 workspace:* 引用,跑幾天 dev/build,體感會很明顯;后續(xù)再接 changesets、Turborepo 等。

11.2 FAQ

Q:子包的依賴裝到根還是裝到各自包?
A:各自 package.json 里聲明,各自裝;pnpm 會把實(shí)體放在 store、在對應(yīng)包的 node_modules/.pnpm 下鏈接。根 package.json 只放全倉庫共用的 devDependencies(如 TS、ESLint)和腳本。

Q:workspace:* 發(fā)布到 npm 前要改嗎?
A:不用。pnpm publish 時會把 workspace:* 等替換成實(shí)際版本號再發(fā)布,發(fā)布出去的 package.json 里是普通版本范圍。

Q:Windows 下路徑或腳本有問題怎么辦?
A:

  • 路徑盡量別帶中文、空格;store-dir 等用正斜杠或系統(tǒng)可識別的形式。
  • 若在 PowerShell 里 scripts 報(bào)錯,可試著用 node 寫一個小腳本封裝 pnpm -r / --filter 等命令,再在 scripts 里調(diào)該腳本。
  • 全局 pnpm、Node 建議用官方安裝包或 nvm-windows,避免權(quán)限、路徑異常。

如果你有具體的目錄結(jié)構(gòu)或 package.json 想優(yōu)化,可以貼出來,按你現(xiàn)在的項(xiàng)目一步步改也行。

到此這篇關(guān)于前端pnpm workspace架構(gòu)的文章就介紹到這了,更多相關(guān)前端pnpm workspace內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

涟水县| 喀喇沁旗| 蒙阴县| 临泽县| 秭归县| 紫阳县| 闸北区| 上饶市| 常宁市| 大埔县| 广汉市| 忻城县| 东阿县| 古田县| 丰都县| 沁阳市| 丽水市| 玉田县| 布尔津县| 凌海市| 阿城市| 从江县| 仁化县| 曲阳县| 成武县| 衡山县| 封开县| 永寿县| 平顺县| 秭归县| 英山县| 平顶山市| SHOW| 平定县| 罗源县| 枣阳市| 定远县| 哈尔滨市| 济阳县| 曲周县| 股票|