pnpm 是又一個 Node.js 包管理工具。它能夠替換 npm, 並且 npm 更快更高效。html
能有多快? 3 倍! 能夠在這裏查看 benchmarks 。node
爲何更高效? 當你安裝一個軟件包,咱們把它保存在你的機器上的一個全局存儲目錄中,而後咱們建立一個硬連接而不是複製。 對於模塊的每一個版本,只會有一個副本保存在磁盤上。 例如,當使用 npm 或 yarn 時,若是有 100 個使用 lodash 的項目,你的磁盤上就會有有 100 份 lodash 的拷貝。pnpm 能幫助您節省千兆字節的磁盤空間!git
Yarn
老實說,當 Yarn
開始公開時,我真的很失望。 幾個月來我一直在爲 pnpm
做出重大貢獻,並且沒有任何關於 Yarn 的消息。 有關其發展的信息是不公開的。github
幾天以後,我意識到 Yarn 只是 npm 的一個小小的改進。 儘管它使得安裝速度更快,而且具備一些不錯的新功能,可是它使用了與 npm 相同的扁平 node_modules 結構(從版本 3 開始)。算法
扁平化的依賴關係樹帶來了一系列的問題:shell
此外,還有一些 Yarn 不打算解決的問題,如磁盤空間使用問題。 因此我決定繼續把時間花在 pnpm 上,並取得了巨大的成功。 截至目前(2017 年 3 月),pnpm 具備 Yarn 超過 npm 的全部附加功能:npm
正如我前面提到的,pnpm 不會拍平依賴關係樹。 所以,pnpm 使用的算法能夠更容易! 這就是爲何只有一名開發人員可以跟上 Yarn 的幾十位貢獻者的步伐。json
那麼,若是不依靠拍平的方式,pnpm 如何構造 node_modules 目錄呢? 爲了理解它,咱們應該回憶在 npm 版本 3 以前 node_modules 文件夾看起來是怎樣的。在 npm@3 以前,node_modules 結構是可預測和乾淨的,由於 node_modules 中的每一個依賴項都有本身的 node_modules 以及所包含依賴關係的 package.json 文件。緩存
node_modules └─ foo ├─ index.js ├─ package.json └─ node_modules └─ bar ├─ index.js └─ package.json
這種方法有兩個嚴重的問題:安全
爲了解決這些問題,npm 從新思考了 node_modules 結構,並提出了扁平化。 在 npm@3 中,node_modules 的結構如今看起來像這樣:
node_modules ├─ foo | ├─ index.js | └─ package.json └─ bar ├─ index.js └─ package.json
有關 npm v3 依賴關係解析的更多信息,請參見 npm v3 依賴關係解析。
與 npm@3 不一樣,pnpm 試圖解決 npm@2 所具備的問題,而不是將依賴關係樹展平。 在由 pnpm 建立的 node_modules 文件夾中,全部的軟件包都有本身的依賴關係,可是目錄樹永遠不會像 npm@2 那麼深。 pnpm 保持全部依賴關係平坦,但使用符號連接將它們組合在一塊兒。
-> - a symlink (or junction on Windows) node_modules ├─ foo -> .registry.npmjs.org/foo/1.0.0/node_modules/foo └─ .registry.npmjs.org ├─ foo/1.0.0/node_modules | ├─ bar -> ../../bar/2.0.0/node_modules/bar | └─ foo | ├─ index.js | └─ package.json └─ bar/2.0.0/node_modules └─ bar ├─ index.js └─ package.json
要查看實例,請訪問 示例 pnpm 項目。
雖然這個例子對於一個小項目彷佛太複雜了,可是對於更大的項目來講,結構看起來比 npm / yarn 建立的結構要好。 讓咱們看看爲何它不錯。
首先,您可能已經注意到,node_modules 根目錄下的包只是一個符號連接。 這很好,由於 Node.js 忽略符號連接並執行實際路徑。 因此 require('foo')會執行文件 node_modules/.registry.npmjs.org/foo/1.0.0/node_modules/foo/index.js
而不是 node_modules/foo/index.js
。
其次,沒有一個安裝的軟件包在其目錄中有本身的 node_modules 文件夾。 那麼 foo
怎麼引入 bar
? 讓咱們看看包含 foo
包的文件夾:
node_modules/.registry.npmjs.org/foo/1.0.0/node_modules ├─ bar -> ../../bar/2.0.0/node_modules/bar └─ foo ├─ index.js └─ package.json
如您所看到的
foo
的依賴關係(只有 bar
)被安裝,但在目錄結構中的一級。foo
能夠引入 bar
,由於 Node.js 在目錄結構中查找模塊直到磁盤的根目錄。 並且 foo
也能夠引入 foo
,由於它在一個名爲 node_modules 的文件夾中(沒錯,這正是一些軟件包所作的)。
只需經過 npm 安裝 pnpm:npm install -g pnpm。 只要你想安裝一些東西,就用它來代替 npm:pnpm i foo。
您也能夠在 pnpm GitHub repo 或 pnpm.js.org 中閱讀更多信息。 您能夠關注 pnpm on Twitter,或者在 pnpm Gitter Chat Room 尋求幫助。