天天看點

[譯] 了解 NPM 5 中的 lock 檔案了解 NPM 5 中的 lock 檔案

<b>本文講的是[譯] 了解 NPM 5 中的 lock 檔案,</b>

這個檔案目前取消了 <code>from</code> 字段。衆所周知,這個字段和時常發生不一緻的 <code>version</code> 字段一起,給代碼審檢視檔案改動差異時,帶來了不少痛苦。不過現在應該變得更加整潔了。

該檔案現在增加了 <code>lockfileVersion</code> 字段來指定的 lock 格式的版本,并将其設定為1。這是為了使将來的格式更新時,不用去猜測該檔案使用什麼特定版本。以前的 lock 格式仍然支援并被識别為版本 <code>0</code>。

你可能已經注意到了,指向特定 URI 的檔案的 <code>resolved</code> 字段仍然得到了保留。注意,NPM 現在可以(根據 .npmrc 中的設定)解析機器配置使用的不同倉庫,這樣的話,與 integrity 字段一起配合,隻要簽名是比對的,包的來源并無關緊要。

上面已經提到過 lock 檔案不止一個。當安裝新的依賴關系或檔案不存在時,NPM 将自動生成一個名為 <code>package-lock.json</code> 的 lock 檔案。如開始所述,lock 檔案是目前依賴關系樹的快照,允許不同機器間的重複建構。是以,建議将它添加到您的版本控制中去。

你可能會認為,使用 <code>npm shrinkwrap</code> 及其 <code>npm-shrinkwrap.json</code> 可以實作同樣的效果。你的想法沒錯,但建立新 lock 檔案的原因是,這樣能夠更好的傳達一個資訊,就是 NPM 真正支援了 locking 機制,這在以前确實是一個顯著的問題。

不過還是有一些差別。首先,NPM 強制該 <code>package-lock.json</code> 不會被釋出。 即使你将其顯式添加到軟體包的 <code>files</code> 屬性中,它也不會是已釋出軟體包的一部分。這種情況同樣不适用于<code>npm-shrinkwrap.json</code> 檔案,哪怕這個檔案可以是釋出包的一部分、即便存在嵌套的依賴關系,NPM 也會遵守它。你可以簡單的通過運作 <code>npm pack</code> 來檢視生成的歸檔内部的内容。

接下來,您可能會想知道在已經包含 <code>package-lock.json</code> 的目錄中運作 <code>npm shrinkwrap</code> 時會發生什麼。答案很簡單,NPM 僅僅會把 <code>package-lock.json</code> 重命名為 <code>npm-shrinkwrap.json</code>。因為檔案的格式是完全一樣的。

最好奇的還會問,當兩個檔案都存在時會發生什麼。 在這種情況下,NPM将完全忽略<code>package-lock.json</code>,隻使用 <code>npm-shrinkwrap.json</code>。 當隻使用 NPM 操縱檔案時,這種情況不應該發生。

NPM 會在安裝包時自動建立 <code>package-lock.json</code>,除非已經有 <code>npm-shrinkwrap.json</code>,并在必要時更新它。

新的 <code>package-lock.json</code> 永遠不會被釋出,而且應該将其添加到你的版本控制系統中去。

運作已經帶有 <code>package-lock.json</code> 檔案的 <code>npm shrinkwrap</code> 指令将隻會對其重命名為 <code>npm-shrinkwrap.json</code>。

當兩個檔案處于某些原因同時存在時,<code>package-lock.json</code> 将被忽略。

這很酷,但是什麼時候使用新的 lock 檔案而不是舊的 shrinkwrap? 它通常取決于您正在處理的包的類型。

這裡有一個警告。當你正在開發庫時,因為倉庫中存在 <code>package-lock.json</code> 或 <code>npm-shrinkwrap.json</code>,是以每次都會獲得完全相同的依賴關系,這對于你的持續內建伺服器也是如此。現在想象你的 <code>package.json</code> 指定某個包的依賴關系為 <code>^1.0.0</code>,也恰好是 lock 檔案中指定的版本,并且每次安裝。到目前為止一切正常。但如果依賴項釋出了一個新版本,并且意外的破壞了 semver 和你開發的包,這時候會發生什麼?

遺憾的是,在出現錯誤報告之前,你可能無法注意到這個問題。在沒有 lock 檔案的倉庫中,你的建構至少在 CI 伺服器上會失敗,因為它總是嘗試去安裝依賴的 <code>latest</code> 版本,進而運作出錯的版本(隻要該版本定期運作,而不僅僅是針對 PR)。 然而,當 lock 檔案出現後,它将始終安裝能正常工作的被 lock 的版本。

然而,對于這個問題有幾個其他的解決方案。 首先,你可以犧牲問題重制的精确性,而不将 lock 檔案添加到版本控制系統中。 其次,你可以做一個分離的配置來進行建構,在運作測試之前運作 <code>npm update</code>。 第三,你可以簡單的在你運作測試之前删除 lock。 如何處理發現的損壞依賴是另一個話題了,其主要原因是因為 NPM 實作的 semver 不僅沒有涉及如此廣範圍的問題,而且還不支援特定版本的黑名單特性。

這當然就會引起一個問題,在開發庫的時候,是否真的值得将 lock 檔案添加到版本控制中去。要記住的是,lock 檔案不僅包含依賴關系,還包含 dev 的依賴關系。在這種意義下來講,開發庫與開發應用時類似(見下一節),無論什麼時候都有着完全相同的 dev 依賴關系,并且不同裝置也算一種優勢。

好,那麼最終使用者在終端中使用的包或打包的可執行檔案會是個什麼情況?在這種情況下,包就是最終結果,即應用。你想要確定最終使用者總能獲得你釋出時所具有的确切依賴性。確定在安裝時讓 NPM 遵守規則,這就是您想要使用 shrinkwrap 的地方。 記住,使用 <code>npm pack</code>釋出包時,你可以随時檢視軟體包的情況。

注意,在 <code>package.json</code> 中指定一個特定版本依賴是不夠的,因為你希望確定最終使用者獲得完全相同的依賴關系樹,包括其所有子依賴關系。而 <code>package.json</code> 中的一個特定版本保證隻會發生在頂層。

其他類型的應用怎麼樣,比如在倉庫内啟動的項目?這種情況并不重要。重要的是安裝正确的依賴項,而兩個 lock 都滿足這一點要求。随你怎麼選。

沒了,就這麼多。如果有哪裡不對或者有一些一般性的意見,請随時在 Twitter 上聯系我。如果你發現拼寫錯誤或文法問題,則可以在 GitHub 上找到這個文章。感謝你的幫助!

<b></b>

<b>原文釋出時間為:2017年6月16日</b>

<b>本文來自雲栖社群合作夥伴掘金,了解相關資訊可以關注掘金網站。</b>

繼續閱讀