<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          yarn.lock 你鎖明白了嗎?

          共 6676字,需瀏覽 14分鐘

           ·

          2021-08-29 12:32

           大廠技術(shù)  高級前端  Node進(jìn)階

          點擊上方 程序員成長指北,關(guān)注公眾號

          回復(fù)1,加入高級Node交流群

          前言

          你是否遇到過這種場景,項目拉下來后執(zhí)行yarn install安裝依賴,yarn.lock 卻提示有變更,我明明什么都沒做呢,這是為啥?但是基于以往的經(jīng)驗(出過 case),yarn.lock 不應(yīng)該有 diff 才對,一定是哪里出了問題!但是git diff yarn.lock發(fā)現(xiàn)自己也看不明白(我好菜 ??)

          舉個 ??

          還原一下我出過的 Case ?? 項目里原本有個依賴foo

          • package.json 里定義的foo@^1.0.1
          • yarn.lock 里的版本是1.0.1

          同學(xué) A 是負(fù)責(zé)foo這個庫的開發(fā),一次發(fā)版后,到項目里升級這個依賴到 1.1.0,但是提交代碼時,只變更了 package.json,沒有更新 yarn.lock

          • package.jsonfoo@^1.0.1``foo@^1.1.0
          • yarn.lock 沒變,還是1.0.1

          然后大家每次拉新代碼并安裝依賴后,本地總有個煩人的 yarn.lock 文件變更,大家心想應(yīng)該是有人升級依賴的時候忘記提交 yarn.lock 了于是同學(xué) B 行動了:

          • 先看了下 foo 這個庫現(xiàn)在有哪些版本,最新版本是1.1.2,跟 package.json 里定義的^1.1.0差了兩個版本,不能保證線上是1.1.0,因為每次上線,都會去找符合^1.1.0這個 version range 里的最新版本
          • 所以去看了下最后一次上線的構(gòu)建日志,發(fā)現(xiàn)下載的是1.1.2
          • 于是提交了 yarn.lock,把版本鎖在了1.1.2

          然后過了一天,拉群了 ??

          • 1.1.2 版本有 bug,修復(fù)后發(fā)布了 1.1.3

          • 但是項目里,由于 B 把版本鎖在了 1.1.2,鎖住了 bug ??

          • 同學(xué) A 質(zhì)問 B 為什么要鎖別人的庫的版本 ??

          • 這個 case 記了幾個 TODO

            • 因為沒有提交 yarn.lock,不確定同學(xué) A 是通過yarn upgrade升級的版本,還是手動去改了 package.json,所以——不要手動修改 package.json 升級版本
            • 升級依賴后,一定要同時提交 package.json 和 yarn.lock

          About yarn.lock

          yarn.lock 的作用?

          鎖定唯一版本!

          • package.json 里定義的是版本區(qū)間,如^1.0.0
          • 而 yarn.lock 里的version字段是唯一的版本號,如1.0.0

          yarn.lock 長啥樣?

          里面都是一塊一塊的,每一塊大概長下面這樣:

          core-js-compat@^3.0.0:
            version "3.14.0"
            resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.14.0.tgz#b574dabf29184681d5b16357bd33d104df3d29a5"
            integrity sha1-tXTavykYRoHVsWNXvTPRBN89KaU=
            dependencies:
              browserslist "^4.16.6"
              semver "7.0.0"

          Identifier(s)

          第一行的core-js-compat@^3.0.0是依賴的 identifier。和 package.json 里對應(yīng)的包名和版本區(qū)間,用@連接。這邊的標(biāo)題里帶了(s),是因為多個 Identifier 最終可能都指向同一個版本(具體例子可以看下文### dependencies里給出的例子)

          version

          第二行version是實際安裝的版本。通常是滿足版本區(qū)間里的一個版本,比如上一行 identifier 里版本區(qū)間是^3.0.0,這里實際安裝的是3.14.0,符合要求。但是為什么要說是“通常”呢,因為有例外,在后文### resolutions部分會講到。

          resolved

          第三行resolved的是一個鏈接,是下載這個包的地址。這個 url 里的域名部分跟項目里配置的 .npmrc你本地的 npm 配置的 registry有關(guān)。

          integrity

          第四行integrity是對resolved下載下來的文件進(jìn)行完整性校驗。如果出現(xiàn) diff,說明同一個下載鏈接對應(yīng)的文件被修改過。

          dependencies

          第五行dependencies是這個包自己的依賴。如這里依賴的browserslist "^4.16.6",你想看下實際安裝的哪個版本,就可以把它拼成 Identifierbrowserslist@^4.16.6",以此為關(guān)鍵字在 yarn.lock 中搜索,就能找到對應(yīng)的“塊”了。

          [email protected], browserslist@^4.0.0, browserslist@^4.11.1, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6, browserslist@^4.3.6, browserslist@^4.6.2, browserslist@^4.6.4, browserslist@^4.7.2, browserslist@^4.9.1:
            version "4.16.6"
            resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
            integrity sha1-15ASd6WojlVO0wWxg+ybDAj2b6I=
            dependencies:
              caniuse-lite "^1.0.30001219"
              colorette "^1.2.2"
              electron-to-chromium "^1.3.723"
              escalade "^3.1.1"
              node-releases "^1.1.71"

          上面這個例子第一行有多個 Identifiers,最終都指向第二行的version "4.16.6",可以檢查下4.16.6版本滿足上面所有 Identifiers 里的版本區(qū)間:4.16.6^4.0.0...

          yarn.lock 是如何生成的?

          yarn.lock 是自動生成的,你不應(yīng)該去手動的修改

          依賴管理

          比如我們的常規(guī)操作,都會自動更新 package.json 和 yarn.lock

          • 新增依賴:yarn add

          • 升級依賴:yarn upgrade

          更多可參考https://classic.yarnpkg.com/en/docs/managing-dependencies

          霸道的resolutions

          假如你的項目依賴了foo,foo依賴了bar@^1.0.0。假設(shè)bar現(xiàn)在有兩個版本1.0.01.1.0。很不幸,bar在發(fā)布1.1.0的時候沒有做好向后兼容。導(dǎo)致foo[email protected]不能搭配使用。如果你可以等:

          • 要么等foo把依賴bar鎖成1.0.0并重新發(fā)版
          • 要么等bar修復(fù)兼容問題后重新發(fā)版

          那如果你等不了呢,你已知foo[email protected]可以正常工作。如果你能鎖住foobar的依賴就好了,但是這定義在foo的 packge.json 里,你總不能去改 node_modules/foo/package.json 吧?這不合適。`resolutions`[1]可以解決你的問題,只要在你自己項目的 package.json 里定義:

          "resolutions": {
            "foo/bar""1.0.0"
          }

          這里的 key"foo/bar"表示foo直接依賴bar,把版本區(qū)間重寫成1.0.0。如果foo不是直接依賴的barfoo -> ... -> bar),我還需要把中間的鏈路都捋清楚嗎?不用那么麻煩!

          "resolutions": {
            "foo/**/bar""1.0.0"
          }

          如果你的項目里有很多依賴直接/間接的依賴了bar,每個定義的版本區(qū)間可能有差別,你知道某個版本可以讓他們都能正常工作,而不用安裝多個版本。也可以不用聲明前綴部分,只寫包名bar。這樣不管是哪里依賴到了bar都會指向你聲明的哪個版本。

          "resolutions": {
            "bar""1.0.0"
          }

          執(zhí)行yarn install后,在 yarn.lock 里搜索bar@

          bar@^1.0.0 [email protected] bar@^2.0.0:
            version "1.0.0"
            ...

          可以看到,resolutions可以違背版本區(qū)間的限制,比如上例中 Identifiers 里的[email protected]``bar@^2.0.0

          如何避免出現(xiàn)問題?

          yarn.lock 與 package.json 不 match

          場景

          只改動 package.json,忘記提交 yarn.lock

          問題

          執(zhí)行yarn install后,yarn.lock 有變更

          如何解決

          • 解決掉引入問題的人(PEACE & LOVE)

          • 確認(rèn) diff 并提交變更后的 yarn.lock

            • 確定是哪些依賴產(chǎn)生的 diff,并回歸相關(guān)功能(成本有點大,而且如果依賴關(guān)系比較復(fù)雜,那是很難確認(rèn)影響面的)

            • OR ?? 成最后一次上線的版本(?? 可能會 ?? 住 bug??)

          可以看到出現(xiàn)問題再解決還是很棘手的,而且有一定賭的成分,所以我們最好預(yù)防。

          如何預(yù)防

          即使現(xiàn)在項目是好的,我們是不是也應(yīng)該防患于未然!

          • 開發(fā)的同學(xué) &&CR 共同把關(guān) ????

          • 阻塞構(gòu)建 ??(有以下幾種方案可選)

            • 優(yōu)點:簡單粗暴 && 直觀(不會出現(xiàn)因為對命令 or 參數(shù)理解存在誤差造成不符合預(yù)期的情況)
            • 缺點:慢!效率低!因為會把包括需要更新的依賴也下載完,本來應(yīng)該在檢測到需要更新的時候就停止的(目前沒有想到什么好辦法)
            • resolutions里修改版本,不會報錯
            • Classic yarn (version 1) 在 package.json 里移除依賴,也不會報錯(v2 修復(fù)了這個問題,詳見https://github.com/yarnpkg/yarn/issues/5840)
            • `npm ci`[2]npm install類似,但是在安裝依賴的過程中如果發(fā)現(xiàn) package-lock.json 不匹配,則會拋錯并退出,而不去更新 lock file

            • `yarn install --frozen-lockfile`[3]等價于npm ci,但是在測試過程中發(fā)現(xiàn)幾個問題:

            • ?yarn install && git diff`--exit-code`[4]yarn.lock正常執(zhí)行 install 命令安裝依賴,再檢查 lock file 有無 diff

          把 lock file 刪掉,整個重裝

          場景

          當(dāng)你更新了某個依賴后,發(fā)現(xiàn)項目跑不起來了,推測可能是依賴的問題。有沒有嘗試過把 yarn.lock + node_modules 都刪了重新安裝,幸運的話可能“問題就解決了”(解決了,但是好像沒完全解決,反正項目跑起來了)

          問題

          把 yarn.lock 刪掉后,原本鎖住的版本都放開了,執(zhí)行yarn install的時候會根據(jù) package.json 里定義的版本區(qū)間去找最新版。所以,可能會造成你預(yù)期外的依賴也被更新了,不幸的話可能會引入 bug。

          解決思路

          可以單獨搞一個依賴empty-lock-lock

          • 什么都不做(一個空的庫),發(fā)版1.0.0
          • 定義一個postinstall腳本,直接拋錯,發(fā)版1.0.1

          在項目中安裝依賴yarn add [email protected] --dev,yarn.lock 里會鎖定版本為1.0.0。然后準(zhǔn)備一個陷阱:

          • 手動把 package.json 里的版本改成區(qū)間^1.0.0
          • 手動修改 yarn.lock 里,把 Identifier 部分的[email protected]也替換成empty-lock-lock@^1.0.0

          修改后提交,可以再執(zhí)行yarn install驗證下,yarn.lock 沒有 diff,證明我們手動修改后的 package.json 和 yarn.lock 仍然是 match 的。等小白鼠上鉤,如果把 yarn.lock 整個刪掉了,再執(zhí)行yarn install,安裝到empty-lock-lock的時候,會根據(jù) package.json 里定義的^1.0.0版本區(qū)間里找最新的,這時候會找到1.0.1版本,下載后觸發(fā)postinstall就報錯啦!

          Node 社群


          我組建了一個氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對Node.js學(xué)習(xí)感興趣的話(后續(xù)有計劃也可以),我們可以一起進(jìn)行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。


             “分享、點贊在看” 支持一波 

          THE END

          希望通過本文,可以瞄到 yarn.lock 神秘的面紗下的一角,當(dāng)下次再看到 yarn.lock 產(chǎn)生 diff 時不會那么迷茫和焦慮。如果各位大大在閱讀過程中發(fā)現(xiàn)了問題,請務(wù)必按頭改正!感恩 ?? 感謝團(tuán)隊內(nèi)的小伙伴們一起探討問題 && 提供小妙(筍)招。感恩 Plus ??????

          參考資料

          • https://robertcooper.me/post/how-yarn-lock-files-work-and-upgrading-dependencies

          擴展閱讀

          • package.json 中定義的各種依賴 ??https://classic.yarnpkg.com/en/docs/package-json

          參考資料

          [1]

          resolutions: https://classic.yarnpkg.com/en/docs/selective-version-resolutions/#toc-how-to-use-it

          [2]

          npm ci: https://docs.npmjs.com/cli/v7/commands/npm-ci

          [3]

          yarn install --frozen-lockfile: https://stackoverflow.com/questions/58482655/what-is-the-closest-to-npm-ci-in-yarn

          [4]

          --exit-code: https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---exit-code

          瀏覽 55
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费色情电影链接 | 国产特级毛片A片WWW | 91av成人 | 国产精品久久久久久久久夜色 | www.久久国产精品 |