爲何 npm 要爲每一個項目單獨安裝一遍 node_modules?

轉載:https://www.cnblogs.com/weiyinfu/p/8471407.html

其實也不用每次都安裝node_modules,直接使用軟鏈接便可:
windows 使用mklink /j node_modules %APPDATA%\Roaming\npm\node_modules
linux使用ls -s node_modules %APPDATA%\Roaming\npm\node_moduleshtml

nodejs中package.json中的依賴必須每一個項目都有本身的node_modules文件夾,而沒法在多個項目之間共用一套node_modules(像Java中的Maven那樣)。前端

依賴管理是每一個現代語言的標配。依賴管理和打包工具是兩個概念,npm是依賴管理,webpack是打包工具。
在Java中,maven既能實現依賴管理又能實現打包。node

何爲依賴管理?
依賴管理說白了就是構建一個有向無環圖。項目A依賴項目B,項目B依賴項目C,那麼當你的項目依賴A的時候,依賴管理工具會自動讓你的項目依賴B和C。
要想構建有向無環圖,最關鍵的是要將項目轉化爲有向無環圖中的結點。因此對於項目每每有description,做者信息,版本信息等額外信息。
依賴管理最難解決的問題就是版本問題。庫A依賴庫B,庫C也依賴庫B,可是庫A跟庫C所依賴的庫B不是同一版本,若是庫B的這兩個版本兼容還好,若是不兼容就坑大發了,這是無解的問題。python

下面說說Java,Python,Node三種語言中的依賴管理。linux

  • Java中的Maven倉庫在開發者電腦上是全局的,全部項目的依賴都集中存放在本地倉庫中。每一個項目都有pom.xml指明依賴本地倉庫中的哪些庫。
  • Python中的pip跟maven很像,在開發者電腦上也是集中存放包,可是它不存在版本問題。也就是說,在你的電腦上每一個python庫都只有一個版本。既然如此,當你依賴某個庫的時候,就無需指明版本號,直接引用包的名稱就能夠了。
  • Node中的依賴若是你不寫package.json,那麼依賴的就是全局的庫;若是寫了package.json,就會把全部依賴下載到node_modules文件夾。

Node這種node_modules文件夾的方式有利有弊。
最明顯的壞處是:webpack

  • 每次都須要安裝依賴,費流量,網速慢時很費時間
  • 浪費磁盤空間,每一個node_modules中包含的工具不少,動輒20M

最明顯的好處是:git

  • 使用package.json安裝好以後,node_modules文件夾中沒有版本信息,從而package.json能夠刪掉了。
    移動/複製/打包項目比較簡單,對於開發、部署都有好處
  • 對於設計npm的人來講,這是最省事的包依賴方法。這就比如maven安裝依賴以後自動將jar包安裝到項目的lib裏面。
  • 隨意改代碼。安裝在node_modules裏面的東西,你能夠隨便改,無需擔憂對其它項目的影響。在Java中使用maven管理項目時,若是想要定製某個庫,就須要更改這個庫的源代碼,這時就須要把這個庫的源代碼複製到項目中,跟node_modules是一個道理。npm的設計者大概認爲:前端都是常常修改庫的源代碼的。

我認爲不一樣語言對於依賴的定位不一樣。Java中的庫是嚴謹的庫,Python中的庫是玩具同樣、隨手寫就的庫,Node裏的庫是代碼片斷同樣的庫。Node裏面的庫既然定位就是代碼片斷,那麼固然要將代碼片斷跟你的項目放在一塊兒了,這樣才方便你修改這些代碼片斷。但是隨着時間推移,node中的庫愈來愈大、愈來愈嚴謹,這種對待代碼片斷的方式就有些很差了。web

總結:這是一種設計,這種設計有利有弊。express

如下是知乎上的回答片斷:npm

全局依賴的惟一好處就是省了硬盤空間。這種省毫無心義。首先若是你要爲幾十幾百兆的硬盤空間斤斤計較,那麼也許你已經窮得不適合作開發。其次若是須要支持全局多版本也省不了多少。至於有人說的,每次npm install時間太長,我認爲這也不是個事。npm install又不是每天搞,並且只是第一次全新checkout的時候比較慢,之後都是增量更新。實在嫌慢(好比由於防火牆的緣由),能夠把node_modules一塊兒提交到git裏去。
其實我以爲徹底能夠作成全局的,依賴模塊都裝到公共目錄,每一個項目在 npm install 時用符號鏈接把每一個模塊對應的版本目錄連過來,或者乾脆就在 require() 時去全局的模塊目錄裏去找,這樣也不麻煩。實際上我團隊就包了這樣一個命令,安裝時是全局安裝,項目 init 時符號鏈接過來,很省時間和空間。但 npm 沒有這麼作,我以爲一是在一開始沒考慮到,後面也就很差改了。實際上就連 node_modules 模塊多層嵌套致使路徑過長的問題,也是一開始設計時沒考慮周全,到了 npm3 才改。

Java在20年前就解決這個問題了,而後後面抄的語言沒有一個徹底抄對的


npm安裝出現警告,如何解決?


E:\node\promise>npm install bluebird
E:\node
`-- bluebird@3.5.0

npm WARN enoent ENOENT: no such file or directory, open 'E:\node\package.json'
npm WARN node No description
npm WARN node No repository field.
npm WARN node No README data
npm WARN node No license field.

E:\node\promise>複製代碼

爲何每次我npm安裝庫都會提示找不到 package.json? 我在node目錄下也確實找不到package.json.如何解決,求解。


由於你須要先 npm init,進行建立 package.json
package.json是對於這個項目的基本信息和描述,做者,倉庫地址,依賴項目,以及部分npm命令相關等等。


npm中package-lock.json的做用:npm install安裝時使用

簡單理解: XYZ 的格式

對應爲: 主版本號.次版本號.修訂號,版本號遞增規則以下:

主版本號:當你作了不兼容的 API 修改,

次版本號:當你作了向下兼容的功能性新增,

修訂號:當你作了向下兼容的問題修正。

  假設咱們建立了一個新項目,它將使用express。 在運行npm init以後,在撰寫本項目時,最新的express版本是4.15.4。 (默認狀況下,npm 將安裝最新版本)

所以在package.json中,"express":"^ 4.15.4"被添加做爲依賴項。 假設明天,express的維護者會發佈一個 bug 修復,因此最新版本變成了4.15.5。 而後,若是有人想要爲個人項目作貢獻,他們會克隆它,而後運行 npm install, 由於4.15.5是一個更高版本的主要版本,這是爲他們安裝的。 咱們都有express依賴,但咱們有兩個不一樣的版本。 理論上,它們應該仍是兼容的,可是也許這個 bug 會影響咱們正在使用的功能,而咱們的應用程序在使用Express版本4.15.4與4.15.5進行比較時會產生不一樣的結果.

  而package-lock.json的做用就是用來保證咱們的應用程序依賴之間的關係是一致的, 兼容的.

  當不存在package-lock.json文件時,使用npm install時,會自動生成這個文件。當存在這個文件時,使用npm install安裝,會安裝package-lock.json裏指定版本的插件,並且相比沒有package-lock.json文件時,安裝速度會快不少。由於package-lock.json文件裏已經存在插件的版本、下載地址、整個node_modules的結構等信息。

  當存在package-lock.json文件時,每次npm install安裝就會安裝package-lock.json裏對應插件的版本。這樣同一份package-lock.json文件,你們安裝的插件版本一致。

  若是某個插件版本變動。又不想刪除package-lock.json文件,從新生成。方法是:npm install plugin@version,及從新安裝這個插件,並指定插件的版本,這樣,package.json和package-lock.json會自動更新。固然,也能夠直接修改package-lock.json文件,這樣npm install時,也會安裝修改後的版本。可是若是隻修改package.json,不修改package-lock.json,npm install仍是會安裝package-lock.json裏的插件版本。

https://www.cnblogs.com/shengulong/p/9463176.html

相關文章
相關標籤/搜索