pnpm 原理
概念
要徹底理解pnpm是怎麼做的,需要有一些操作系統知識
- 文件的本質
在操作系統中,文件實際上是一個指針,只不過它指向的不是內存地址,而是一個外部存儲地址(這裏的外部存儲可以是硬盤、U盤、甚至是網絡)
當我們刪除文件時,刪除的實際上是指針,因此,無論刪除多麼大的文件,速度都非常快。
- 文件的拷貝
如果你複製一個文件,是將該文件指針指向的內容進行復制,然後產生一個新文件指向新的內容
- 硬鏈接 hard link
硬鏈接的概念來自於 Unix 操作系統,它是指將一個文件A指針複製到另一個文件B指針中,文件B就是文件A的硬鏈接
通過硬鏈接,不會產生額外的磁盤佔用,並且,兩個文件都能找到相同的磁盤內容
硬鏈接的數量沒有限制,可以爲同一個文件產生多個硬鏈接
windows Vista操作系統開始,支持了創建硬鏈接的操作,在cmd中使用下面的命令可以創建硬鏈接
mklink /h 鏈接名稱 目標文件
由於文件夾(目錄)不存在文件內容,所以文件夾(目錄)不能創建硬鏈接
由於種種原因,在windows操作系統中,通常不要跨越盤符創建硬鏈接
- 符號鏈接 symbol link
符號鏈接又稱爲軟連接,如果爲某個文件或文件夾A創建符號連接B,則B指向A。
windows Vista操作系統開始,支持了創建符號鏈接的操作,在cmd中使用下面的命令可以創建符號鏈接:
mklink /d 鏈接名稱 目標文件
# /d表示創建的是目錄的符號鏈接,不寫則是文件的符號鏈接
早期的windows系統不支持符號鏈接,但它提供了一個工具junction來達到類似的功能
符號鏈接和硬鏈接的區別
- 硬鏈接僅能鏈接文件,而符號鏈接可以鏈接目錄
- 硬鏈接在鏈接完成後僅和文件內容關聯,和之前鏈接的文件沒有任何關係。而符號鏈接始終和之前鏈接的文件關聯,和文件內容不直接相關
- 快捷方式
快捷方式類似於符號鏈接,是windows系統早期就支持的鏈接方式。
它不僅僅是一個指向其他文件或目錄的指針,其中還包含了各種信息:如權限、兼容性啓動方式等其他各種屬性
由於快捷方式是windows系統獨有的,在跨平臺的應用中一般不會使用
- node環境對硬鏈接和符號鏈接的處理
硬鏈接:硬鏈接是一個實實在在的文件,node不對其做任何特殊處理,也無法區別對待,實際上,node根本無從知曉該文件是不是一個硬鏈接
符號鏈接:由於符號鏈接指向的是另一個文件或目錄,當node執行符號鏈接下的JS文件時,會使用原始路徑。
pnpm原理
pnpm使用符號鏈接和硬鏈接來構建node_modules目錄
下面用一個例子來說明它的構建方式
假設兩個包a和b,a依賴b:
假設我們的工程爲proj,直接依賴a,則安裝時,pnpm會做下面的處理
- 查詢依賴關係,得到最終要安裝的包:a和b
- 查看a和b是否已經有緩存,如果沒有,下載到緩存中,如果有,則進入下一步
- 創建 node_modules 目錄,並對目錄進行結構初始化
- 從緩存的對應包中使用硬鏈接放置文件到相應包代碼目錄中
- 使用符號鏈接,將每個包的直接依賴放置到自己的目錄中
這樣做的目的,是爲了保證a的代碼在執行過程中,可以讀取到它們的直接依賴
- 新版本的pnpm爲了解決一些書寫不規範的包(讀取間接依賴)的問題,又將所有的工程非直接依賴,使用符號鏈接加入到了 .pnpm/node_modules 中
在本例中好像沒有必要,但是如果b依賴c,a又要直接用c,這種不規範的用法現在pnpm通過這種方式支持了。
但對於那些使用絕對路徑的奇葩寫法,可能永遠也無法支持
- 在工程的node_modules目錄中使用符號鏈接,放置直接依賴
- 完成
來源:渡一教育