溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

什么時候不能在 Node.js 中使用 Lock Files

發(fā)布時間:2020-10-10 20:00:57 來源:腳本之家 閱讀:176 作者:前端先鋒 欄目:web開發(fā)

快速摘要

如果你開發(fā)像 Web 服務器之類的程序,那么 lock file 是非常有用的。但是如果將庫或 CLI 發(fā)布到 npm,則永遠不要發(fā)布 lock file。因為如果你使用它,則意味著你和你的用戶可能在使用不同版本的依賴項。

什么是Lock File?

lock file 描述了整個依賴關系樹,它在創(chuàng)建時被解析,包括具有特定版本的嵌套依賴關系。在 npm 名為 package-lock.json ,在 yarn 中名為 yarn.lock。在這兩個npm和yarn它們被放置旁邊你的package.json。
package-lock.json 的內容應該是這樣:

{
"name": "lockfile-demo",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
}
}
}

yarn.lock 的格式不同,但也包含類似的信息:

# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies:
color-convert "^1.9.0"
chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"

兩者都包含一些重要的信息:

  • 安裝的每個依賴項的實際版本
  • 每個依賴項的依賴項
  • 已解決的軟件包中用校驗和驗證軟件包的完整性

既然 lock file 中已經(jīng)列出了所有的依賴項,拿為什么還要將它們寫在 package.json 中呢?為什么我們需要兩個文件?

package.json vs. Lock File

package.json 中 dependencies 字段顯示你的項目應該安裝的依賴項,但不顯示這些依賴項的依賴項。依賴項可以指定精確版本或 semver 范圍。對于 semver 范圍,npm 或 yarn 將h會選擇最適合的版本。

這意味著,如果在發(fā)布新版本時多次運行 npm install ,有可能會得到相同版本的依賴項。例如用 npm install twilio 安裝 twilio 這樣的依賴項,那么 package.json 中的依賴項可能會存在類似于這樣的條目:

{
"dependencies": {
"twilio": "^3.30.3"
}
}

如果你查閱 npm 網(wǎng)站上的 semver 文檔,就會看到 ^ 意味著任何大于 3.30.3 的版本和小于 4.0.0 都是有效版本。因此,如果在發(fā)布新版本時你沒有鎖定文件,npm install 或 yarn install 會自動安裝一個,你的 package.json 將不會被更新。但是 lock file 的內容會有所不同。

如果 npm 或 yarn 找到它們各自的 lock file,將使用它們代替模塊安裝。這對于持續(xù)集成(CI)等情況尤其有用。對于此這種場景,你可以針對相應的包管理器使用特殊命令或標志:

npm ci # will install exactly what's in the package-lock.json
yarn install --frozen-lock-file # will install exactly what's in yarn.lock without updating it

當你在構建 Web 程序或服務器之類的應用時,這非常有用,因為我們希望在 CI 環(huán)境中模擬用戶的行為。因此,如果在源代碼控制(如 git)中跟蹤我們的 lock file,就可以確保每個開發(fā)人員以及服務器或構建系統(tǒng)還有 CI 系統(tǒng)都能夠使用相同版本的依賴項。

那么當我們編寫要發(fā)布到 npm 的庫時,為什么不能做同樣的事呢?要回答這個問題,首先要討論發(fā)布的工作原理。

如何發(fā)布模塊

與某些人想的相反,你發(fā)布到 npm 的內容并不總是與 GitHub 上或項目中的內容完全相同。發(fā)布模塊的方式是 npm 將通過檢查 package.json 和 .npmignore 文件中的 files 鍵或者如果沒有``來確定應該發(fā)布的文件。 gitignore文件。還有一些文件總是包含在內,有些文件將永遠被排除在外。你可以在 [npm page](https://docs.npmjs.com/files/package.json#files) 上找到這些文件的完整列表。例如,.git` 目錄始終會被忽略。

之后 npm 將會獲取文件列表,并用 npm pack 將它們一起打包成 tarball。如果要查看打包的文件,可以在項目中運行 npm pack --dry-run,能看到包含所有文件的輸出。

那個 tarball 將被上傳到 npm注冊表。運行此命令時你可能會注意到加入你已經(jīng)有了一個 package-lock.json,它實際上沒有被捆綁。這是因為 package-lock.json 將始終被忽略。

這意味著如果另一個開發(fā)人員安裝了你發(fā)布的軟件包,他們永遠不會下載你的 package-lock.json,因此在安裝過程中將會完全忽略它。

這可能會導致“在我的機器上能夠工作”的意外,因為你的 CI 和開發(fā)環(huán)境可能會選擇不同的依賴項版本。那么我們可以做些什么呢?

禁用 lock file 并收縮包裝

首先,應該停止跟蹤我們的 lock file。如果你用的是git,請將以下內容添加到項目中的 .gitignore 文件中:

yarn.lock
package-lock.json

Yarn 的文檔說即使你創(chuàng)建了庫,也應該簽入 yarn.lock,但是如果你想確保自己能夠保證與用戶相同的體驗,我建議將其添加到 .gitignore。

你可以通過在項目里的 .npmrc 文件中添加以下內容來關閉 package-lock.json 文件的生成:

package-lock=false

對于 yarn,你可以通過添加 yarn install --no-lockfile 標志保證不生成 lock file。

擺脫了 package-lock.json 并不意味著無法固定我們所擁有的依賴關系和子依賴關系。我們可以用另一個名為 npm-shrinkwrap.json 的文件。

它與 package-lock.json 基本相同,并由 npm shrinkwrap 生成并實際的打包并發(fā)布到 npm 注冊表中。
因此,通過將 npm shrinkwrap 添加到 npm 腳本作為 prepack 腳本甚至是 git commit hook,可以確保在你的開發(fā)環(huán)境中,與你的用戶和 CI 中使用相同版本的依賴項。

**一個重要的提示:**通過使用 shrinkwrap 文件,你可以確定精確的版本,但它也會阻止人們獲得自動安裝的關鍵補丁程序。 npm 強烈反對庫的 shrinkwrap 的用例。

了解更多信息

不幸的是,雖然 npm docs 中有很多相關內容,但有時很難找到你想要的東西。如果你想更好地了解安裝或打包的內容,那么你一個常見標志就是 --dry-run。運行該命令而不會影響你的系統(tǒng)。

例如 npm install --dry-run 并不會將依賴項安裝到你的文件系統(tǒng),或者 npm publish --dry-run 實際上也不會發(fā)布該包。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI