Q: 為什么要遷移pnpm?
相比于npm,pnpm有一些優(yōu)勢:
-
更快的安裝速度: 在安裝包時,pnpm使用了硬鏈接的方式,將已安裝的包鏈接到新的目錄下,而不是復(fù)制或下載包。這樣,當你安裝一個包的不同版本或者不同項目使用同一個包時,它們會共享已經(jīng)安裝的包,減少了磁盤空間的占用,同時也加速了安裝的速度。
-
更少的磁盤空間占用: 由于pnpm使用硬鏈接的方式共享已安裝的包,因此相比于npm,pnpm占用更少的磁盤空間。
-
更好的本地緩存: pnpm會緩存包的元數(shù)據(jù)和二進制文件到本地緩存中,這樣再次安裝相同的包時,會從本地緩存中讀取,而不是重新下載。這樣可以提高安裝包的速度,并減少網(wǎng)絡(luò)帶寬的消耗。
-
更好的多項目管理: pnpm可以管理多個項目的依賴,可以將相同的依賴安裝在一個公共的位置,減少磁盤空間的占用,并且可以快速地切換項目之間的依賴關(guān)系。
-
更好的可重復(fù)性: pnpm使用了鎖文件來保證安裝包的版本一致性,同時也支持自定義的鎖文件名稱和路徑。這樣可以確保項目在不同的環(huán)境中的安裝結(jié)果一致,增強了可重復(fù)性。
需要注意的是,pnpm相比于npm也存在一些缺點,例如兼容性問題、社區(qū)支持不如npm等。因此,在選擇使用pnpm還是npm時,需要根據(jù)自己的實際需求和項目情況進行權(quán)衡。
Q: 上面提到的硬鏈接和符號鏈接是什么?
硬鏈接和符號鏈接都是文件系統(tǒng)中的鏈接方式,它們的作用是可以將一個文件或目錄鏈接到另一個文件或目錄上,從而實現(xiàn)共享或復(fù)制等功能。下面我來簡單介紹一下它們的區(qū)別和示例。
硬鏈接
硬鏈接是指在文件系統(tǒng)中,將一個文件名鏈接到另一個文件上,使它們指向同一個物理數(shù)據(jù)塊,也就是說,這兩個文件名共享同一個inode節(jié)點。硬鏈接的本質(zhì)是將一個文件名指向一個已存在的文件。
硬鏈接的特點:
- 硬鏈接不能跨越不同的文件系統(tǒng),因為inode節(jié)點只存在于一個文件系統(tǒng)中。
- 硬鏈接可以看作是原文件的一個副本,它們的文件權(quán)限、擁有者、修改時間等都是相同的。
- 刪除硬鏈接并不會刪除原文件,只有當所有的硬鏈接都被刪除后,原文件才會被真正刪除。
下面是一個硬鏈接的示例:
$ touch file1 # 創(chuàng)建一個文件
$ ln file1 file2 # 創(chuàng)建硬鏈接
$ ls -li file* # 查看文件inode節(jié)點
12345 -rw-r--r-- 2 user user 0 Apr 26 10:00 file1
12345 -rw-r--r-- 2 user user 0 Apr 26 10:00 file2
可以看到,file1和file2的inode節(jié)點是相同的,說明它們共享同一個物理數(shù)據(jù)塊。
符號鏈接
也稱之為軟鏈接,符號鏈接是指在文件系統(tǒng)中,創(chuàng)建一個特殊的文件,其中包含了另一個文件的路徑,通過這個特殊文件來鏈接到目標文件。符號鏈接的本質(zhì)是將一個文件名指向一個路徑。
符號鏈接的特點:
- 符號鏈接可以跨越不同的文件系統(tǒng),因為它們只是一個指向文件或目錄的路徑。
- 符號鏈接指向的是目標文件或目錄的路徑,而不是inode節(jié)點,因此,目標文件或目錄的屬性信息可以獨立于符號鏈接存在。
- 刪除符號鏈接不會影響目標文件或目錄,也不會刪除它們。
下面是一個符號鏈接的示例:
$ touch file1 # 創(chuàng)建一個文件
$ ln -s file1 file2 # 創(chuàng)建符號鏈接
$ ls -li file* # 查看文件inode節(jié)點
12345 -rw-r--r-- 1 user user 0 Apr 26 10:00 file1
67890 lrwxr-xr-x 1 user user 5 Apr 26 10:01 file2 -> file1
可以看到,file2是一個符號鏈接文件,它的inode節(jié)點和file1不同,而是一個指向file1的路徑。
Q: 看到一些文章里說pnpm走的是硬鏈接,有的說用了軟連接。到底走的是什么?
其實,pnpm是軟連接和硬鏈接都用了??梢赃@么理解,pnpm在機器上某個地方存放安裝好的所有依賴包,這些依賴包是獨立于我們代碼倉庫的,這也是前面說的pnpm在安裝速度和磁盤空間占用上的優(yōu)點。而我們的代碼庫確實是先通過硬鏈接的方式來建立代碼庫和已安裝過的依賴包之間的共享關(guān)系??梢源蜷_代碼庫看到node_modules
下有一個.pnpm文件夾,里面放的就是當前代碼庫建立的硬鏈接。
.pnpm
下的文件都是一些名字很長的,長這樣:
這里不用關(guān)心具體是什么,我們需要關(guān)心的是node_mpdules
下我們認識的npm
依賴包,它們正是通過軟連接的方式來鏈接到.pnpm
下的這些依賴包的。在vscode下,可以明顯看到npm
包后面的軟連接標識:
如果想看一下這些軟連接到底指向哪里的,可以:
# 進入node_modules目錄
cd node_modules
# 枚舉文件列表
ll
可以看到,這就是node_modules
下軟鏈接到.pnpm
下的。
Q: 這個模式跟npm dedupe是不是很相似,有什么不同?
pnpm的硬鏈接模式和npm的dedupe功能是類似的,都是通過共享已安裝的包來減少磁盤空間的占用,同時也可以提高安裝包的速度。但它們之間還是存在一些不同:
-
原理不同: pnpm使用硬鏈接的方式共享已安裝的包,而npm使用的是符號鏈接的方式共享已安裝的包。硬鏈接是文件系統(tǒng)的一種特殊鏈接,它可以將一個文件鏈接到另一個文件上,使它們共享相同的內(nèi)容。符號鏈接則是一個指向另一個文件或目錄的特殊文件。
-
適用范圍不同: pnpm的硬鏈接模式可以在多個項目之間共享已安裝的包,而npm的dedupe功能只能在單個項目內(nèi)共享已安裝的包。
-
優(yōu)勢不同: pnpm的硬鏈接模式可以減少磁盤空間的占用和提高安裝包的速度,而npm的dedupe功能只能減少磁盤空間的占用。
-
實現(xiàn)方式不同: pnpm使用了自己的包管理器和包存儲庫,而npm使用了公共的包管理器和包存儲庫。這也是導(dǎo)致它們之間存在差異的一個重要原因。
需要注意的是,無論是使用pnpm的硬鏈接模式還是npm的dedupe功能,都需要謹慎使用,以避免出現(xiàn)意外的錯誤。特別是在使用硬鏈接模式時,如果多個項目共享同一個包,需要注意不要在一個項目中修改了該包的文件,導(dǎo)致其他項目也受到影響。
Q: pnpm對于node版本有要求嗎?
pnpm有對node版本的要求。官方文檔中列出的最低支持版本是Node.js 10.x,推薦使用的版本是Node.js 14.x。如果使用的是較舊的Node.js版本,可能會導(dǎo)致安裝和使用pnpm時出現(xiàn)錯誤。
我這里本來用的是Node14.x。因為其他原因,本次也給Node升級到16.x了。
Q: pnpm有類似npm ci的命令嗎?
補充:
npm ci
主要是用于剛剛在download了一個倉庫后,還沒有node_modules的時候讓npm完全根據(jù)package.json和package-lock.json的規(guī)范來install依賴包。相比較于直接走npm i
,npm ci
會帶來更精確的小版本版本號控制,因為npm i對于一些"^1.0.2"這樣的版本號,可能會按照1.x.x這樣的規(guī)范給你無感升級了,造成和之前某些包版本號之間的差異。
但是當本地已有node_modules的時候,就沒辦法用npm ci
命令了。
是的,pnpm也有類似 npm ci
命令的功能,可以使用 pnpm install --frozen-lockfile
命令實現(xiàn)。它會根據(jù) package-lock.json
或 pnpm-lock.yaml
確定依賴關(guān)系,并且在安裝期間不會更新任何包。此命令類似于 npm ci
和 yarn install --frozen-lockfile
命令。
Q: pnpm@7搭配husky@8后commit一直失敗怎么辦?
這是因為hooks出問題了。某些代碼庫里會在commit時候會添加一些hook用來處理commit相關(guān)的事務(wù),比如生成commit-id之類的。
husky@8后需要處理一下這個:
husky add .husky/commit-msg 'sh .git/hooks/commit-msg "$@"'
手動把之前.git/hooks下的腳本拷貝到.husky下。文章來源:http://www.zghlxwxcb.cn/news/detail-558288.html
友情提示:.git和.husky一般都是在項目根目錄下的隱藏文件夾喲~文章來源地址http://www.zghlxwxcb.cn/news/detail-558288.html
到了這里,關(guān)于pnpm改造替換npm的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!