node應用線上部署時鎖定包的依賴版本


npm shrinkwrap

我們使用node開發時,經常需要依賴一些模塊來完成功能需求,而我們所依賴的模塊也必然會依賴其他模塊,就這樣一級一級的依賴,而且這些依賴模塊並不為我們所控制。一個產品或項目的開發周期,少則幾個周,多則幾個月幾年。開發人員往往在一開始時下載了依賴包發現能夠正常工作后,便一直在依賴包的當前版本上工作,然而在線上服務器布屬時往往是根據依賴配置文件,重新下載依賴包。可這個時候依賴鏈中的包的開發者很可能已經將某個模塊升級了,而且並不能保證這些新的依賴包沒有bug。一旦依賴鏈上的某個包出現bug,可能對產品造成嚴重影響,而且這個時候往往無法找回開發時所用的正確依賴,以及依賴的依賴的版本。
我們來看一個經典的例子:
假設有包A依賴包B,包B依賴包C:

//包A
{
  "name": "A",
  "version": "0.1.0",
  "dependencies": {
    "B": "<0.1.0"
  }
}
//包B
{
  "name": "B",
  "version": "0.0.1",
  "dependencies": {
    "C": "<0.1.0"
  }
}
//包C
{
  "name": "C",
  "version": "0.0.1"
}

假設在開發時,我們運行npm install A得到以下的依賴鏈:

A@0.1.0
`-- B@0.0.1
    `-- C@0.0.1

而在項目需要部署上線時,我們不可能把所有node_modules放到線上服務器中,所以將項目代碼放到服務器時,我們便會運行npm install A,而恰恰這階段,包B的版本更新到了0.0.8,所以我們在服務器上得到的依賴鏈就是:

A@0.1.0
`-- B@0.0.8
    `-- C@0.0.1

如果B的新版本有問題,這時就會對產品造成難以預估的損失。
所以我們推薦當開發環境中,所有依賴模塊都能正常工作時,便在部署到服務器之前將依賴包的版本鎖住,這時候就運行這個命令:

npm shrinkwrap

我們會得到一個npm-shrinkwrap.json的文件,這個文件保存了所有當前使用的依賴模塊的版本:

{
  "name": "A",
  "version": "0.1.0",
  "dependencies": {
    "B": {
      "version": "0.0.1",
      "from": "B@^0.0.1",
      "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
      "dependencies": {
        "C": {
          "version": "0.0.1",
          "from": "org/C#v0.0.1",
          "resolved": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4"
        }
      }
    }
  }
}

將這個文件連同項目源碼一同部署到服務器上,然后運行npm install這時候,npm會首先檢查有沒有npm-shrinkwrap.json文件,有的話會根據該文件中依賴包的版本以及resolve字段下載依賴包,這樣就能夠保證線上環境與開發環境一致。

from 與 resolve

這個文件時根據我們當前項目中的node_modules中的模塊的當前版本生成的。version代表當前模塊版本,from表示的是package.json中對該依賴模塊的版本描述,resolve代表當前模塊的實際來源。
比如當你的package.json中對於某個依賴模塊有如下描述:

"dependencies": {
    "acorn": "^3.0.0",
....................................
  }

acorn模塊安裝后,它的package.json文件中會出現如下字段:

  "_from": "acorn@>=3.0.0 <4.0.0",
  "_resolved": "https://registry.npmjs.org/acorn/-/acorn-3.2.0.tgz",

這時候運行npm shrinkwrap便會出現:

  "dependencies": {
    "acorn": {
      "version": "3.2.0",
      "from": "acorn@>=3.0.0 <4.0.0",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.2.0.tgz"
    },

對於npm-shrinkwrap.json來說,這其中最重要的就是resolve字段。

使用npm shrinkwrap的注意事項

  • 如果要安裝新的依賴模塊,一定要使用npm install --save 模塊,這樣保證package.json與npm-shrinkwrap.json文件同步更新。
  • node_modules中的模塊必須能夠包含package.json中的依賴模塊,如果node_modules中不存在package.json中指定的依賴模塊,運行npm shrinkwrap會報錯;如果node_modules中包含有package.json中未指定的模塊,根據官方說法是也會報錯,但根據我的實驗(windows7系統)並沒有報錯,npm-shrinkwrap.json會包含所有在node_modules中的模塊。
  • npm-shrinkwrap.json中並不會包含devDependencies字段中的模塊。

參考文章:

npm-shrinkwrap-Lock down dependency versions


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM