比如有 2 两个 node 项目,依赖同一个库,那么每个项目中的 node_modules 都有一份。这不是重复下载和浪费磁盘空间么?
java 就不这样,java 一般都是放在 repository 下面(我指的是使用 maven).
当然,我知道可以 node install -g 。
但是我了解到的实践中,都是每个项目一份 node_modules 。
难到把所有项目的依赖放在一起会有问题?
有些老铁没明白啊~~~
同一个库多个版本的话,每个版本放到一个文件夹下不就行了,就像下面这样

还有,有些老铁的习惯很不好啊。。。总是喜欢转移话题。。。
俺的问题是
   为什么不能有个中心依赖库
有的老铁到话题转移到
   磁盘够不够用的问题。。。。
磁盘够不够用和俺的问题无关吧。。。。
|  |      1yujiff      2020-06-02 20:57:31 +08:00 好处,你可以想象得到吧?! | 
|  |      2dalibaxiaoliba      2020-06-02 20:58:31 +08:00 难到把所有项目的依赖放在一起会没有问题吗?现在磁盘空间又不是问题 | 
|  |      3U7Q5tLAex2FI0o0g      2020-06-02 20:59:32 +08:00 版本问题。 来人,上吐槽 node_modules 文件夹的图 | 
|  |      4EPr2hh6LADQWqRVH      2020-06-02 20:59:56 +08:00 虽然同一个库但版本可能不同,你明白吧 | 
|  |      5ethusdt      2020-06-02 21:04:26 +08:00 @littleylv #3  <img src="" alt="node_module is like a black hole" /> | 
|      7forgottencoast      2020-06-02 21:10:26 +08:00 我记得 15 年的时候更恐怖,每一个库的依赖都放在自己库目录下的某个文件夹下(大概就是 node_modules ), 这样导致了路径很长的循环依赖。 我们在 Windows 上部署 CI 的时候,触发了路径超过 256 个字符的问题,当时我就震惊了,还能这样依赖的啊? 记得不是太清楚了,如有错误,欢迎指正。 | 
|  |      8abcbuzhiming      2020-06-02 21:14:23 +08:00 @dalibaxiaoliba 为啥总有人认为别人的电脑不是花钱买来的啊?你一个项目动则上 G 的依赖,还不是问题? | 
|  |      9gitjavascript      2020-06-02 21:16:30 +08:00 磁盘算个啥,再说了一个机器难道还会部署很多项目么 | 
|  |      10abcbuzhiming      2020-06-02 21:19:50 +08:00 @avastms 之前也有人用这个做理由,说依赖同一个库但是版本不同。但是我后来想想发觉不对啊,你是可以依赖同一个库版本不同啊,你每个版本保存一份不就行了?好,问题来了,npm 有个天坑在于同一个包在本地无法多版本共存。于是它才不得不搞这种每个项目里都要塞一个依赖的做法 | 
|      11TransAM      2020-06-02 21:26:46 +08:00 via Android 。。。谁告诉你不可以的? 全局目录在 NODE_PATH 中配置,node 会在检查本地目录之后检查这个目录。 | 
|      12renmu123      2020-06-02 21:40:56 +08:00 via Android 我觉得这个挺好的,版本管理很方便,如果各种库能少一点就更好了 | 
|  |      13JJstyle      2020-06-02 21:45:20 +08:00 via iPhone 多版本我只见过 homebrew 支持,虽然它不是依赖管理 | 
|      14wangxiaoaer      2020-06-02 21:49:48 +08:00 via Android @avastms maven 表示版本也成了问题? | 
|  |      15asanelder OP @dalibaxiaoliba #2  @avastms #4 @gitjavascript #9 java 就可以同一个库多版本并存啊,每个版本一个文件 夹不就行了  | 
|      16xiangwan      2020-06-02 21:57:27 +08:00 试试 lerna 或者 yarn workspace | 
|  |      17axihe      2020-06-02 22:01:13 +08:00 楼主可以试一下 yarn2.0  包管理这方面,虽然 npm 一直在努力和进步,但 yarn 还是走在前沿的。 | 
|      18qingo      2020-06-02 22:08:37 +08:00 via Android  2 java 还需要一些 wrapper 在项目中,rust 的 carge 用的更整洁,一步一步改过来 go mod 我不错,没有为什么,就是傻 B 而已 | 
|  |      20alan0liang      2020-06-02 22:16:50 +08:00 via Android 如 @axihe #17 所说,yarn 的 PnP 正解。 直接原因应该是实现简单(因为 npm 是完全独立于 Node 的,如果需要像 lz 附言里的图那样,要不改 Node (很不好改),要不自己运行时注入一个 resolver) 其实有一个很方便的地方,一个项目用完了可以放心的直接 rm -rf 掉,不用担心残留在本地的依赖项。(npm i -g 的包通常都是 cli,在项目里 require() 不到。) | 
|      21Jirajine      2020-06-02 22:18:50 +08:00 via Android 我也觉得应该放一起,需要的时候再 vendor 出来 | 
|  |      22asanelder OP @alan0liang #20 没有残留这点确是是优点 | 
|      24thtznet      2020-06-02 22:28:58 +08:00  2 .net 体系的 NuGet 不知道高到哪里去,但是看到微软就政治不正确,我懂的。 | 
|      25Austaras      2020-06-02 22:31:43 +08:00 别问,问就是上 berry 不过大概是因为 npm 上的包不靠谱方便随时改吧,我就这么用过不少次 | 
|  |      26asanelder OP @thtznet #24 老铁真逗,不过因为不开发 windows 相关,所以不了解巨硬那一套哈,不过 vscode 让俺对微软好感增加不少。 | 
|  |      27love      2020-06-02 23:08:35 +08:00 主要是这么简单地做法成本也不高,除非你有大量的项目。 另外又不是没有象你说的,比如 pnpm / yarn2 都是共享文件的。 | 
|      30runze      2020-06-03 00:23:56 +08:00  6 因为最早 web 端的依赖就是放在项目目录下。 比如你的页面引用了 jQuery,要么把它放在 CDN 上,要么放在项目的 web 目录下,如果放在系统级的中心仓库,那么要怎么通过 script 标签引用它呢? 后来有了 web 端的包管理工具,例如 bower,也是放在项目目录下的 bower_components,这样可以通过 /bower_components/xxx/xxx.js 这样子引用。 node_modules 只不过是继承了这种做法而已,在刚开始的时候,node 端的工具还不多,node 仓库里大部分还是前端库,有不少人拿 node_modules 当作 bower_components 使用,`<script src="/node_modules/jquery/dist/jquery.js">` 这样子。 为了兼容性,这种设计就这样保留到了现在。 | 
|  |      32JayLin1011      2020-06-03 00:54:13 +08:00 你的问题设计者肯定考虑到了,但还是这样设计了,你想想这是为什么,就能得出结论了。 | 
|  |      33siganushka      2020-06-03 00:56:02 +08:00 第三方库要考虑各种各样的情况,比如项目 A 依赖 “[email protected]“,项目 B 依赖 “[email protected]”,这时候就不能放在一起(实际情况比这负责的多),当然你可以说放在一块再按版本号子目录存放,但这一是增加了深度,二是它的作用随着“多个项目的公共依赖部分的减少而减少”,况且硬盘的成本是很低的,所以最终还是取舍的问题。 | 
|  |      34nl101531      2020-06-03 08:48:08 +08:00 via iPhone 当初新建一个 hello world,下载了 1G 的依赖,惊了。。。 | 
|  |      35redbuck      2020-06-03 08:50:13 +08:00 我觉得不是包放哪里的问题. 而是包发布的时候就应该是完整可运行的.它依赖什么,发布的时候就应该打包好.变成它代码的一部分. 用包的人不应该关心某个包依赖什么.下载依赖的时候,也不应该下载它的依赖 | 
|  |      36jeeyong      2020-06-03 10:12:18 +08:00 上古时代是这么干的. 比如 python..但是都感受到了独立管理包的好处. 统一管理的时候会出现很多听起来不值得一提,但是发现->解决耗时不少的问题. | 
|      37runze      2020-06-03 11:10:44 +08:00 @redbuck #35 这个也有历史原因,比如网页中用了三个 jQuery 的插件,肯定不可能每个插件自带一份 jQuery 。 现在也一样,一大堆 react-xxx 的库,也不能每个都自带 react 。 | 
|  |      38linrz      2020-06-03 11:46:20 +08:00  1 https://github.com/nodejs/node/issues/4584  早期也有人提出为什么不能像 maven 一样,或者自定义寻找依赖 resolve 的策略,但是回复是当时已经 lock 定稿了 | 
|      39julyclyde      2020-06-03 12:13:01 +08:00 感觉是“app 制度”而不是“env 制度”的 所以 node 用户和 docker 爱好者高度重叠 | 
|  |      40libook      2020-06-03 12:48:13 +08:00  1 1. 把所有项目依赖放在一起会有问题?答:看需求,贴合需求就没问题,与需求矛盾就有问题。 2. 每个项目中的 node_modules 都有一份依赖是不是 Node 的机制?答:不是,这是 npm 的机制,Node 并没有强制要求每个项目的依赖放在项目自己的 node_modules 里。 3. Node 是否支持把所有项目依赖放在一起?答:支持,npm 只是一种包管理方案,Node 的包管理器有很多种,比如 pnpm 就是采用了把所有项目依赖放在一起的方案。 4. node_module 是否支持你把依赖放在多个项目的公共父目录下供所有子项目使用?答:支持,实际上如果当前目录下找不到依赖,Node 会尝试到上一级目录来查找依赖,一直到根目录: https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders > If the module identifier passed to require() is not a core module, and does not begin with '/', '../', or './', then Node.js starts at the parent directory of the current module, and adds /node_modules, and attempts to load the module from that location. Node.js will not append node_modules to a path already ending in node_modules. > If it is not found there, then it moves to the parent directory, and so on, until the root of the file system is reached. | 
|      43readonly      2020-06-03 15:07:32 +08:00 这个问题我也想过,当年因为 npm 都崇尚语义化版本号,这样方便升级,比如 package.json 里依赖了 lodash ^1.0.0 版本,那么执行 npm update 之后可以自动升级到 ^1.9.9 这样的版本上,只要是满足语义化版本的就可以升级。那么如果两个项目都写了  lodash ^1.0.0,我升级其中的一个,另一个也就 resolve 到 ^1.9.9 了,会导致不可预期的事情。但后面出了个 package-lock.json,这个文件里面就完整的记录了当前项目所用的版本甚至是包的下载路径,所以完全可以 resolve 到正确的版本上了,之所以不做应该就是大家习惯了,毕竟这样比较好向主子申请更好的电脑配置不是~ | 
|  |      44linrz      2020-06-03 16:39:01 +08:00 @asanelder  哈哈哈,以前水过一篇博客,对这块略有了解  https://linrz.me/2019/11/11/the-future-of-javascript-package-managment/ | 
|  |      45LeslieWongH      2020-06-03 16:42:44 +08:00 node 的最初开发者在 JSConf Eu 2018 上表示自己挺后悔在 node 中加个 node_module 文件夹的,而且引用还不是以.js 后缀结尾,直接模块名。种种开发 node 时让他觉得很羞耻的东西,让他决定在离开了 node 团队多年后,再去开发另外一个 V8 运行时——deno 。;) 详见油管。10 things I regret about node.js -- Ryan Dahl | 
|  |      46cheny95      2020-06-03 17:18:11 +08:00 | 
|      47a132811      2020-06-06 16:11:08 +08:00 一句话就是,node 是为了解决多版本冲突引入的这家伙。 http://npm.github.io/how-npm-works-docs/npm3/how-npm3-works.html 为了解决 node 这个坑(还有超级多的其它坑),于是有了 deno |