如何評價node_modules的設計?
比如冗餘問題還是不小的,路徑過長無解,特別是當A -&> node_modules -&> B -&> node_modules -&> C -&> node_modules -&> A -&> node_modules -&> B ...這樣的循環依賴的時候
npm3把包都拍出來到第一級了,然後裝個react-native後,node_modules裡面幾百個包的文件夾。醉了啊,我裝個第三方react-native庫,然後需要從裡面copy點ios代碼到項目里的時候,找半天。。。
PS:最近在大項目里升級了npm3,幾個問題:一個是很慢,不是網速慢。二是容易失敗,可靠性沒有之前好。npm 3.0 聲稱有優化,僅多個項目的依賴版本不兼容時會在下層嵌套。
npm/CHANGELOG.md at master · npm/npm · GitHub
據說 npm3 已經改了
題主只問node_modules這個設計,就說說npm模塊依賴裡面和這個文件結構相關的。
0. 循環依賴不會導致特別長的路徑,npm在install的時候,同版本模塊,如果parent path上有模塊安裝過了,那麼child則不會繼續安裝。可以`npn install npm-cycle-a`試下。 而npm3也解決了不在同一路徑下的module共享的問題。
1. 當初為什麼這樣設計, isaacs有在issue中討論過 Too many dependencies break the Windows file system · Issue #3697 · npm/npm · GitHub
記得其他的各種方式的實現,在相關的issues中都有討論過,不過整理的東西找不到了,有興趣可以找著看看isaacs的其他回復。
主要在於利用文件系統的結構來維護依賴樹,而不用使用另一套機制來維護依賴樹的信息,文件系統也足夠的穩健。考慮了symbol link不同平台實現的問題,而放棄symbol link;而如果完全扁平化,則需要一套模塊查找機制來在運行時對模塊的版本進行resolve。isaacs認為這樣增加複雜度,其實個人認為複雜度估計在可接受的範圍內。
一開始這麼設計在理論上是完全正確的,到了工程層面碰到各種問題,所以才會有之後的這些優化。
othiym23說npm組內以達成共識,會保留目前的設計結構 Downside to an entirely flat node_modules folder? · Issue #9660 · npm/npm · GitHub
但web是沒有nested structure這種環境的,npm也在考慮這個問題了,主要是為了在web這種本身就是大小很敏感的地方,這種嵌套所導致的文件冗餘是不能接受的. Roadmap area of focus: browser dependencies · npm/npm Wiki · GitHub
2. 關於路徑過長,個人看法,這個和android 65536,千年蟲之類是一個性質的,因為沒有做mathmatic prefect的方案,所以總有一天會碰到這類問題,只不過千年蟲是沒人可以避免,所以大家一起努力一把把問題延後了。而文件路徑過長和65536隻有那些超過了這個限制的程序才會碰到,只有自己去想各種辦法hack了。
3. 至於文件多,這是因為解決了dependency hell之後,程序的組織模式能夠瘋狂的擴展了,nodejs社區的活躍很大程度也是因為這個原因。一個nodejs項目裡面不是自己的模塊可以到數百個之多,而一個人就能夠輕鬆維護,在別的語言的package結構下這是不可能的。依賴衝突導致你使用超過一定數量的package的時候,程序已經不能編譯或者跑不起來了。為了快速開發的能力(盡最大程度的復用現有代碼),有些性能在這個過程中被犧牲掉了,因為這是一個disk cheap的年代。如果考慮高性能而不是快速開發的能力,應該考慮c++, golang, rust這類。
睡前看到這個題目寫個回答到現在了。對於npm的模塊設計來說,完美的利用了js的特性解決dependency hell這個超級難題,非常天才的設計!That"s awesome!
有興趣可以現在直接把 npm3 用起來(建議自己玩玩,官方未推薦使用前不建議用於正式環境)https://www.npmjs.com/package/npm3
npm install -g npm3
npm3 -v
3.2.2
npm3 install
npm3 search
其實可以用peerDependencies 比如一些核心的內核型模組 一般都會被加入到子模組的peerDenpendencies里 這樣就不會重複安裝了
node_modules 不是黑盒么?誰讓你看了?誰讓你暴露了?
有次安裝一個幾M的模塊,結果下載了幾百M的依賴模塊, 當時沒見過世面,內心無疑是震驚的!那種子子孫孫無窮無盡感覺, 讓我不禁產生這傢伙會不會重複下載模塊和無限循環引用模塊的疑問。
Limitations of npm"s Install Algorithm
There are some very rare and pathological edge-cases where a cycle can cause npm to try to install a never-ending tree of packages. Here is the simplest case:
A -&> B -&> A" -&> B" -&> A -&> B -&> A" -&> B" -&> A -&> ...
where A is some version of a package, and A" is a different version of the same package. Because B depends on a different version of A than the one that is already in the tree, it must install a separate copy. The same is true of A", which must install B". Because B" depends on the original version of A, which has been overridden, the cycle falls into infinite regress.
To avoid this situation, npm flat-out refuses to install any name@version that is already present anywhere in the tree of package folder ancestors. A more correct, but more complex, solution would be to symlink the existing version into the new location. If this ever affects a real use-case, it will be investigated.
npm安裝一個模塊時會順著目錄樹往上找父級有沒有安裝過相同版本的模塊,安裝過子級就不安裝了,要引用時就順著目錄樹往上找,這樣就防止了無限循環載入了。
但是幾條路徑中可能會出現重複下載了同一版本模塊的情況。
最新的npm3依賴包"扁平化"安裝的方式雖然解決了模塊深度嵌套重複下載且不能共用的問題,
但是也有副作用,舉個例子,安裝express,所有依賴模塊都被安裝在了項目node_modules下,同級,不嵌套了。當我卸載express的時候,問題來了,只卸載了express一個模塊,一開始安裝的幾十個依賴模塊都還在。要卸載冗餘的模塊莫非要一個一個人工找出來?╮(╯▽╰)╭原來npm卸載express,依賴模塊也一併卸載了的。我只知道Windows下面複製該目錄直接報錯:路徑長度超出限制。
我覺得還好。如果體驗過maven里多版本衝突的問題,就知道另一個極端也很可怕。回頭試試npm3再評價。
確實就是屎。
我看見我一個只有幾十行的項目下的 node_modules 目錄有將近十萬個文件,當時都嚇尿了……
後來我在本地就索性只留一個 node_modules 根目錄,直接 ln -s 讓不同項目共用那個 node_modules 目錄……生產中的項目已經升級到npm 3.3.9了,目前看來還是很穩定的。
npm3的升級會盡量幫用戶將node_modules目錄扁平化,只有在依賴版本號衝突時才會在下一級目錄下保留另一個版本。現在的設計感覺已經是大環境下最好的方案了。路徑太長無法刪除的給個小技巧:右鍵「壓縮文件」-選擇壓縮後刪除文件
後端:很好的設計,簡單 粗暴 穩定,對後端開發非常友好。前端:體積太大 這玩意開始就是給後端設計的吧
我認為應該用特殊的文件夾名,比如 express@4.9.8 這樣,並且當前項目的package.json里只能引用某一包的一種版本,這樣就不會有任何衝突了。如果像 npm3.0那樣,版本不同才在自己的node_modules下保存,仍然會有很多衝突問題,感覺這樣是比較爛的設計。
都不用看那麼長的評論,總之,node_modules是史上最噁心的設計
沒圖沒真相,官網有圖,直接去看吧,懶得做搬運工。npm2https://docs.npmjs.com/how-npm-works/npm2npm3:https://docs.npmjs.com/how-npm-works/npm3
推薦閱讀:
※我用js寫了一個冒泡排序法,怎麼用html和css把排序過程展現出來?
※關於具名的IIFE內部對函數自身再賦值問題?
※官網網站用什麼技術棧比較合理?
※關於angular在指令中無法獲取子元素的問題?
TAG:JavaScript | Nodejs |