npm和yarn(一)

早期的npm(npm v2)
  • 在安裝依賴的時(shí)候會(huì)將依賴放到 node_modules文件中今妄;
  • 如果某個(gè)包A依賴于B,B作為間接依賴犬性,會(huì)被安裝到A的文件夾的node_modules中,遞歸進(jìn)行日裙,直到子依賴中不再依賴其他模塊受神;
    優(yōu)點(diǎn):層級(jí)結(jié)構(gòu)明顯联四,每次安裝的目錄結(jié)構(gòu)都是相同的

存在的問題

  • 如果項(xiàng)目過大,必然會(huì)形成一棵巨大的依賴樹,嵌套層級(jí)非常深排吴。
  • 不同層級(jí)中存在相同的模塊,導(dǎo)致大量冗余双藕。
  • 在windows系統(tǒng)中近范,文件路徑最大長(zhǎng)度為260個(gè)字符,嵌套層級(jí)過深可能導(dǎo)致不可預(yù)知的問題虱颗。


扁平結(jié)構(gòu)

為解決上面的問題 npm3.x版本做了一次較大的更新畦粮,將早期的嵌套結(jié)構(gòu)改為了扁平結(jié)構(gòu):

  • 安裝模塊時(shí)瞪浸,不管其是依賴還是子依賴的依賴钩蚊,優(yōu)先將其安裝在 node_modules根目錄
  • 當(dāng)安裝到相同模塊時(shí)瓤狐,判斷已安裝的模塊是否符合新的模塊的版本范圍勺美,符合則跳過,不符合則在當(dāng)前模塊的node_modules下安裝該模塊。
{
  "name": "my-app",
  "dependencies": {
    "buffer": "^5.4.3",
    "ignore": "^5.1.4",
     "base64-js": "1.0.1",
  }
}
{
  "name": "buffer",
  "dependencies": {
    "base64-js": "^1.0.2",
    "ieee754": "^1.1.4"
  }
}

npm 3.x版本帶來了新的問題叭喜。
由于在執(zhí)行 npm install 的時(shí)候是按照 package.json 里依賴的順序依次解析,依賴包在 package.json 的放置順序則決定了 node_modules 的依賴結(jié)構(gòu),依賴結(jié)構(gòu)的不確定性可能會(huì)給程序帶來不可預(yù)知的問題腊嗡。

Lock文件

為了解決npm install的不確定性問題卡者,npm 5.x 版本中新增了package-lock.json文件底挫,安裝方式還是沿用npm 3.x的扁平化方式。package-lock.json的作用是鎖定依賴結(jié)構(gòu)外遇,即只要項(xiàng)目目錄下有package-lock.json捐晶,那么每次執(zhí)行 npm install后生成的node_modules目錄結(jié)構(gòu)一定是完全相同的
例如谨究,我們有如下的依賴結(jié)構(gòu):

{
  "name": "my-app",
  "dependencies": {
    "buffer": "^5.4.3",
    "ignore": "^5.1.4",
    "base64-js": "1.0.1",
  }
}
{
  "name": "my-app",
  "version": "1.0.0",
  "dependencies": {
    "base64-js": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz",
      "integrity": "sha1-aSbRsZT7xze47tUTdW3i/Np+pAg="
    },
    "buffer": {
      "version": "5.4.3",
      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
      "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
      "requires": {
        "base64-js": "^1.0.2",
        "ieee754": "^1.1.4"
      },
      "dependencies": {
        "base64-js": {
          "version": "1.3.1",
          "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
          "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
        }
      }
    },
    "ieee754": {
      "version": "1.1.13",
      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
    },
    "ignore": {
      "version": "5.1.4",
      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
      "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A=="
    }
  }
}

最外面的兩個(gè)屬性 name 把敢、versionpackage.json 中的 nameversion 柏副,用于描述當(dāng)前包名稱和版本蕉饼。

dependencies 是一個(gè)對(duì)象创肥,對(duì)象和 node_modules 中的包結(jié)構(gòu)一一對(duì)應(yīng)塔猾,對(duì)象的 key 為包名稱睦擂,值為包的一些描述信息:

  • version:包版本 —— 這個(gè)包當(dāng)前安裝在 node_modules 中的版本
  • resolved:包具體的安裝來源
  • integrity:包 hash 值,基于 Subresource Integrity 來驗(yàn)證已安裝的軟件包是否被改動(dòng)過蕉毯、是否已失效
  • requires:對(duì)應(yīng)子依賴的依賴坷澡,與子依賴的 package.jsondependencies的依賴項(xiàng)相同着降。
  • dependencies:結(jié)構(gòu)和外層的 dependencies 結(jié)構(gòu)相同妆偏,存儲(chǔ)安裝在子依賴 node_modules 中的依賴包愉烙。
npm的緩存機(jī)制

緩存位置: /Users/xxx/.npm


  • content-v2 目錄用于存儲(chǔ)tar包的緩存
  • index-v5 目錄用于存儲(chǔ)tar包的hash
  • npm在執(zhí)行安裝時(shí)省核,可以根據(jù)package-lock.json中存儲(chǔ)的intergiryversion陪毡、name生成一個(gè)唯一的key對(duì)應(yīng)到index-v5目錄下的緩存記錄慧耍,從而找到tar包的hash定庵,然后再根據(jù)hash取找緩存的tar包直接使用
npm的安裝流程
  1. 執(zhí)行 npm install 后绎晃,首先檢查和獲取npm的配置,優(yōu)先級(jí)為:

項(xiàng)目級(jí)的.npmrc文件 > 用戶級(jí)的.npmrc文件 > 全局的.npmrc文件 > npm內(nèi)置的.npmrc 文件

  1. package-lock.json文件:
  • 從 npm 遠(yuǎn)程倉(cāng)庫(kù)(registry)獲取包信息
  • 根據(jù) package.json 構(gòu)建依賴樹硼砰,構(gòu)建過程:
    1)構(gòu)建依賴樹時(shí),不管其是直接依賴還是子依賴的依賴括授,優(yōu)先將其放置在 node_modules 根目錄。
    2)當(dāng)遇到相同模塊時(shí)俭茧,判斷已放置在依賴樹的模塊版本是否符合新模塊的版本范圍,如果符合則跳過红氯,不符合則在當(dāng)前模塊的 node_modules 下放置該模塊。
    3)在緩存中依次查找依賴樹中的每個(gè)包,不存在緩存就從 npm 遠(yuǎn)程倉(cāng)庫(kù)下載包(下載壓縮包后绷雏,存放到 ~/.npm 目錄)早歇,將包按照依賴結(jié)構(gòu)解壓到node_mudules
    4)生成 lock 文件
  1. package-lock.json 文件:

檢查 package.json 中的依賴版本是否和 package-lock.json 中的依賴有沖突逝段。
如果沒有沖突莫瞬,直接跳過獲取包信息、構(gòu)建依賴樹過程尝哆,開始在緩存中查找包信息姥敛,后續(xù)過程相同

yarn

當(dāng)npm還處于v3時(shí)期的時(shí)候(當(dāng)時(shí)還沒有package-lock.json)玄糟,yarn作為一個(gè)新的包管理工具出現(xiàn)贰军,解決了npm的一些問題(lock词疼、緩存等問題舵盈,npm后續(xù)也進(jìn)行了優(yōu)化)

  1. 確定性: 用過yarn.lock 機(jī)制书释,即使是不同的安裝順序扯再,相同的依賴關(guān)系在任何環(huán)境和容器中都以相同的方式安裝。
  2. 模塊扁平化:將不同版本的依賴包拗小,按照一定的策略界牡,歸結(jié)為單個(gè)版本,避免冗余漾抬。
  3. 網(wǎng)絡(luò)性能:yarn采用了請(qǐng)求排隊(duì)的理念宿亡,類似于并發(fā)池連接,能夠更好的利用網(wǎng)絡(luò)資源纳令,同時(shí)引入了一種安裝失敗的重試機(jī)制
  4. 采用緩存機(jī)制挽荠,實(shí)現(xiàn)了離線模式
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市平绩,隨后出現(xiàn)的幾起案子圈匆,更是在濱河造成了極大的恐慌,老刑警劉巖捏雌,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跃赚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)纬傲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門满败,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叹括,你說我怎么就攤上這事算墨。” “怎么了汁雷?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵净嘀,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我摔竿,道長(zhǎng)面粮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任继低,我火速辦了婚禮,結(jié)果婚禮上稍走,老公的妹妹穿的比我還像新娘袁翁。我一直安慰自己,他們只是感情好婿脸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布粱胜。 她就那樣靜靜地躺著,像睡著了一般狐树。 火紅的嫁衣襯著肌膚如雪焙压。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天抑钟,我揣著相機(jī)與錄音涯曲,去河邊找鬼。 笑死在塔,一個(gè)胖子當(dāng)著我的面吹牛幻件,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛔溃,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼绰沥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了贺待?” 一聲冷哼從身側(cè)響起徽曲,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎麸塞,沒想到半個(gè)月后秃臣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喘垂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年甜刻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绍撞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡得院,死狀恐怖傻铣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情祥绞,我是刑警寧澤非洲,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站蜕径,受9級(jí)特大地震影響两踏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兜喻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一梦染、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧朴皆,春花似錦帕识、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至扒接,卻和暖如春伪货,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钾怔。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工碱呼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蒂教。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓巍举,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親凝垛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子懊悯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容