關於你想知道的package-lock.json的一切

前情提要

當你開心的將npm升到v5.x.x(原文時代)以後,一切都彷佛還挺順利。誒…等等,一個新文件被自動建立啦!這是啥?Package-lock.json。若是你有瀏覽它,會發現它長得相似package.json的依賴,可是冗長多啦。你想,乾脆無論它得了,但是最後老是會碰見關於依賴裝錯版本或者找不到依賴等等各式各樣的問題。許多人的解決方式都是刪掉package-lock.json,再跑一遍npm install。如果如此,package-lock.json存在的意義是啥?它的目的又是爲了解決什麼呢?html

概覽

  • 若是你用的是npm 5.0.0以上版本,package-lock.json文件會自動建立。
  • package-lock被用來確保穩定安裝和依賴兼容。
  • 爲確保源一致,你必須提交package-lock文件。
  • npm 5.1.x以上版本,package.json的權重大於package-lock.json,解決了一大頭疼源泉。
  • 不用手動刪去package-lock文件而後再npm install再從新生成它啦。
  • 使用並遵循semver語義化版本。

背景

語義化版本

在一探package-lock究竟以前,你必需要理解semver。它是npm背後的小小功臣。你能夠從這裏瞭解到npm是如何使用它的。歸納來說,倘若你在開發一個可供其它應用使用的應用,你必須說明每次升級變動會對第三方使用產生哪些影響。這就是語義化版本想要傳達的。一個版本有三部分:X, Y, Z,分別指代大版本,小版本,與查缺補漏版本。好比1.2.3,那麼就是大版本1,小版本2,bugfix版本3。bugfix版本不會影響任何功能,小版本變動每每是增長新功能,也不會影響使用。而大版本變動每每會帶來使用層面不兼容的狀況,須要再作調整。(想一想webpack每次升級的時候!)webpack

包管理

正是爲了讓包管理變簡單,npm出現了。一個項目可能有上百個依賴,每一個依賴又有上百個依賴。爲了你不陷入依賴地獄,只需簡單幾行命令,npm就能夠安裝並管理這些依賴,大大節省了時間。git

當你使用npm安裝一個包(並保存它)的時候,package.json裏就自動添加了一條信息,包括包名和其版本。npm固然也支持版本的通配符。npm默認安裝最新版本,而後在其版本號以前添加一個"^"符。好比「^1.2.12」,它代表最低應使用1.2.12版本,而且在這之上,擁有相同大版本號的任何版本都是OK的。畢竟小版本和bugfix版本不會對使用形成任何影響,因此用任何相同大版本的更高級版本都很安全。能夠從這裏瞭解semver通配符的更多信息,以及npm的semver計算器。github

多人項目

Package.json的真正好處在於,任何人均可以經過這個文件生成一個裝有項目所需全部依賴的文件夾。可是咱們來看一下,哪些地方可能出問題呢?web

就來新建一個使用express的項目吧。執行npm init後,安裝express:npm install express — save。我撰文時express最高版本是4.15.4。因此「express」: 「^4.15.4」被寫進package.json裏,依賴也已經裝好了。不過次日,可能express的維護者發佈了一個bugfix版本,因此最新版本又變成了4.15.5。若是這時我同事clone了這個項目,而且執行npm install,由於4.15.5的大版本號沒變,因此他裝的版本就會是最新的4.15.5。咱們都安裝了express,不過是不一樣的版本。按道理講他們是互相兼容的,可是可能好巧不巧,這個被修復的bugfix恰好就影響到咱們使用的功能了,那麼咱們分別運行本身的項目時就會出現不一樣的結果。這是個問題!express

Package-lock

目標

Package-lock的出現就是爲了解決上述問題的!也就是從同一份package.json文件可能安裝出不同的結果。Package-lock.json自npm 5.x.x後加入,因此只要你沒禁止掉它(注:能夠從.npmrc設置package-lock = false喔),它都會自動生成。npm

格式

Package-lock包括package.json裏所例舉的包的應安裝版本,安裝地址(URI),校驗包完整性的hash,其須要的子包,以及依賴列表。express的package-lock條目以下:json

"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下例舉的每一個包,都在package-lock下擁有一份一樣的條目。安全

因此npm其實如今是用package-lock.json來決定如何安裝依賴的!由於package-lock寫明瞭包的安裝版本,地址,也作了包完整性校驗,以及例舉了包的全部子依賴,因此按照package-lock來裝模塊的話,必定會獲得如出一轍的結果cookie

爭論

既然packge-lock是用來解決問題的,那爲何還有許多質疑它存在,以及關於如何禁止它生成的討論呢?

npm5.x.x之前,package.json是項目的惟一真理來源。package.json說啥就是啥!npm使用者喜歡並習慣僅維護package.json。可是,當package-lock出現後,它和不少人指望的背道而馳了!若是有同一份package和package-lock,package.json的修改並不會影響到package-lock。

因而就出現了更改package.json後,安裝未生效的狀況,須要移除package-lock再生成一份,由此引起了不少爭論。能夠從這份有趣的reop時間線上看出端倪。有的人以爲仍是得以package.json爲準,有的人又以爲既然package-lock被創造出來了,那就以新的爲準唄。最後這份爭論以PR#17508劃上句號。npm決定,若是package.json上發生過改動,安裝時package.json的權重就會超過package-lock。這個決定隨着npm v5.1.0發佈,自2017年7月5日起即日執行~

相關文章
相關標籤/搜索