你想知道關於package-lock.json的一切,但是太害怕了問了?

簡介

如果你已經將節點包管理(npm)更新到版本5.x.x,看起來一切似乎都很順利。等等,這是什麼?用 npm 初始化項目的會自動創建了一個新文件 package-lock.json。如果打開它,它看起來有點像 package.json 的依賴項,但更冗長。我們決定忽略它,繼續開發項目。最終,我們有時會遇到依賴項的問題,找不到,或者安裝了錯誤的版本。大多數人最終都會刪package-lock.json和運行“npm install”。那麼,爲什麼要有它呢? 它應該做什麼? 它實際上是做什麼的?

總結

  • 如果你使用的 npm 版本 爲 ^5.x.x , package-lock.json 會默認自動生成
  • 你應該使用 package-lock 來確保一致的安裝和兼容的依賴關係
  • 你應該將 package-lock 提交到源代碼控制
  • 從npm ^ 5.1.x開始,package.json能夠勝過 package-lock.json,所以你遇到較少讓人頭痛的問題
  • 不再刪除 package-lock 只是爲了運行npm install並重新生成它

背景

語義版本控制

在你瞭解 package-lock 甚至 package.jso n之前,你必須瞭解語義版本控制(semver)。 這是npm背後的天才,是什麼使它更成功。 你可以在 此處 閱讀有關npm如何使用它的更多信息。簡而言之,如果你正在構建與其他應用程序接口的應用程序,你應該告知你所做的更改將如何影響第三方與你的應用程序交互的能力。這是通過語義版本控制完成的,版本由三部分組成:X,Y,Z,分別是主要版本,次要版本和補丁版本。

例如:1.2.3,主要版本1,次要版本2,補丁3。

補丁中的更改表示不會破壞任何內容的錯誤修復。 次要版本的更改表示不會破壞任何內容的新功能。 主要版本的更改代表了一個破壞兼容性的大變化。 如果用戶不適應主要版本更改,則內容將無法正常工作。

管理包

npm 存在使管理包變得容易。你的項目可能有數百個依賴項,每個依賴項都有一百個,爲了讓你的注意力遠離依賴地獄,通過 npm 管理,使用一些簡單的命令,你可以安裝和管理這些依賴關係,幾乎不必考慮它們。

當您使用npm安裝包(並保存它)時,會在 package.json 中添加一個包含包名稱和應該使用的 semver的條目。默認情況下,npm 安裝最新版本,並預先插入版本號,例如 “^1.2.12”,這表示至少應該使用版本 1.2.12,但任何高於此版本的版本都可以,只要它具有相同的主要版本,由於次要版本和補丁編號僅代表錯誤修正和非破壞性添加, 你可以安全地使用任何更高版本的同一主要版本。閱讀更多關於semver通配符的信息,請看 這裏

共享項目

在 package.json 中定義這樣的依賴項的真正好處是,任何有權訪問 package.json 的人都可以創建一個包含運行應用程序所需模塊的依賴項文件夾,但是讓我們來看看事情可能出錯的具體方式。

假設我們創建了一個將使用 express 的新項目。 運行npm init後,我們安裝express:npm install express - save。在編寫代碼時,最新的版本是4.15.4,所以 “express”:“^ 4.15.4”作爲我的package.json中的依賴項添加,並且我的電腦安裝了確切的版本。

現在也許明天,express 的維護者會發布 bug 修復,因此最新版本變爲4.15.5。 然後,如果有人想要爲我的項目做貢獻,他們會克隆它,然後運行`npm install。'因爲4.15.5是具有相同主要版本的更高版本,所以爲它們安裝。 我們都安裝 express ,但我們卻是不同的版本。

從理論上講,它們應該仍然是兼容的,但也許bugfix會影響我們正在使用的功能,而且當使用Express版本4.15.4和4.15.5運行時,我們的應用程序會產生不同的結果。

Package-lock

目的

package-lock.json 的目的是避免上述情況,其中從同一 package.json 安裝模塊會導致兩種不同的安裝。 在 npm 版本 5.x.x 中添加了 package-lock.json,因此如果你使用的是主要版本 5 或更高版本,除非您禁用它,否則它會自動生成。

內容結構

package-lock 是 package.json 中列出的每個依賴項的大型列表,應安裝的特定版本,模塊的位置(URI),驗證模塊完整性的哈希,它需要的包列表 ,以及依賴項列表。 讓我們來看看 express 的列表是什麼:

"express": {
      "version": "4.15.4",
      "resolved": "https://registry.npmjs.org/express/-/express-4.15.4.tgz",
      "integrity": "sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE=",
      "requires": {
        "accepts": "1.3.3",
        "array-flatten": "1.1.1",
        "content-disposition": "0.5.2",
        "content-type": "1.0.2",
        "cookie": "0.3.1",
        "cookie-signature": "1.0.6",
        "debug": "2.6.8",
        "depd": "1.1.1",
        "encodeurl": "1.0.1",
        "escape-html": "1.0.3",
        "etag": "1.8.0",
        "finalhandler": "1.0.4",
        "fresh": "0.5.0",
        "merge-descriptors": "1.0.1",
        "methods": "1.1.2",
        "on-finished": "2.3.0",
        "parseurl": "1.3.1",
        "path-to-regexp": "0.1.7",
        "proxy-addr": "1.1.5",
        "qs": "6.5.0",
        "range-parser": "1.2.0",
        "send": "0.15.4",
        "serve-static": "1.12.4",
        "setprototypeof": "1.0.3",
        "statuses": "1.3.1",
        "type-is": "1.6.15",
        "utils-merge": "1.0.0",
        "vary": "1.1.1"
      }
    },

可以在“requires”部分中列出的每個包中找到等效條目。

npm(^5.x.x.x)後的做法,npm 使用package-lock.json,而不是使用 package.json 來解析和安裝模塊。因爲 package-lock 爲每個模塊及其每個依賴項指定了版本,位置和完整性哈希,所以它每次創建的安裝都是相同的。 無論你使用什麼設備,或者將來安裝它都無關緊要,每次都應該給你相同的結果,這非常有用。

爭議

因此,如果引用 package-lock 是希望解決一個常見問題,爲什麼它的頂級搜索結果(除了npm文檔)都是關於禁用它或質疑它扮演的角色?

在npm 5.x.x之前,package.json 是項目的真實來源,npm 用戶喜歡這個模型,並且非常習慣於維護他們的包文件。 但是,當首次引入 package-lock 時,它的行爲與有多少人預期的相反。 給定一個預先存在的包和package-lock,對package.json的更改(許多用戶認爲是真實的來源)沒有同步到package-lock 中。

示例:包A,版本 1.0.0 在 package.json 和 package.lock.json 中。 在package.json中,A被手動編輯爲1.1.0版。 如果認爲 package.json 是真實來源的用戶運行 npm install,他們會期望安裝 1.1.0版。 但是,安裝了1.0.0版,即使列出的 v1.1.0 是 package.json, 他們也希望安裝是 1.0.0版。

示例: package-lock.json 中不存在模塊,但它存在於 package.json 中,作爲一個將package.json 視爲真實來源的用戶,我希望能夠安裝我的模塊。 但是,由於 package-lock.json 不存在該模塊,因此未安裝該模塊,並且我的代碼因無法找到模塊而失敗。

大部分時間,因爲我們無法弄清楚爲什麼我們的依賴關係沒有被正確安裝,要麼刪除了package-lock.json 並重新安裝,要麼完全禁用 package-lock.json 來解決問題。

期望與真實行爲之間的這種衝突在 npm repo中引發了一個非常有趣的問題線索。 有些人認爲package.json 應該是事實的來源,有些人認爲,因爲 package-lock 是 npm 用來創建安裝的東西,所以應該被認爲是事實的來源。 這場爭議的解決方案在於 PR#17508。 如果 package.json 已更新,Npm 維護者添加了一個更改,導致package.json 覆蓋 package-lock。 現在,在上述兩種情況下,都會正確安裝用戶期望安裝的軟件包。 此更改是作爲npm v5.1.0的一部分發布的,該版本於2017年7月5日上線。

你的點贊是我持續分享好東西的動力,歡迎點贊!

一個笨笨的碼農,我的世界只能終身學習!

更多內容請關注公衆號《大遷世界》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章