为什么 node 项目的依赖都要放在 node_modules 下,而不整个中心依赖库?

2020-06-02 20:53:13 +08:00
 asanelder

比如有 2 两个 node 项目,依赖同一个库,那么每个项目中的 node_modules 都有一份。这不是重复下载和浪费磁盘空间么?

java 就不这样,java 一般都是放在 repository 下面(我指的是使用 maven).

当然,我知道可以 node install -g 。

但是我了解到的实践中,都是每个项目一份 node_modules 。

难到把所有项目的依赖放在一起会有问题?

7453 次点击
所在节点    Node.js
48 条回复
Jirajine
2020-06-02 22:18:50 +08:00
我也觉得应该放一起,需要的时候再 vendor 出来
asanelder
2020-06-02 22:21:41 +08:00
@alan0liang #20 没有残留这点确是是优点
wusheng0
2020-06-02 22:26:32 +08:00
@renmu123
我也觉得这样挺不错,类似于 Python 虚拟环境
thtznet
2020-06-02 22:28:58 +08:00
.net 体系的 NuGet 不知道高到哪里去,但是看到微软就政治不正确,我懂的。
Austaras
2020-06-02 22:31:43 +08:00
别问,问就是上 berry

不过大概是因为 npm 上的包不靠谱方便随时改吧,我就这么用过不少次
asanelder
2020-06-02 22:42:39 +08:00
@thtznet #24 老铁真逗,不过因为不开发 windows 相关,所以不了解巨硬那一套哈,不过 vscode 让俺对微软好感增加不少。
love
2020-06-02 23:08:35 +08:00
主要是这么简单地做法成本也不高,除非你有大量的项目。
另外又不是没有象你说的,比如 pnpm / yarn2 都是共享文件的。
Mithril
2020-06-02 23:14:15 +08:00
@thtznet NuGet 真的是用过所有包管理里面最好用的。。。
asanelder
2020-06-02 23:33:34 +08:00
@love #27 ok,俺了解了解 yarn2
runze
2020-06-03 00:23:56 +08:00
因为最早 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">` 这样子。

为了兼容性,这种设计就这样保留到了现在。
asanelder
2020-06-03 00:37:11 +08:00
@runze #30 有理有剧,让人信服!总算看到一个说的通的答案了!!!
JayLin1011
2020-06-03 00:54:13 +08:00
你的问题设计者肯定考虑到了,但还是这样设计了,你想想这是为什么,就能得出结论了。
siganushka
2020-06-03 00:56:02 +08:00
第三方库要考虑各种各样的情况,比如项目 A 依赖 “lib@1.0“,项目 B 依赖 “lib@2.0”,这时候就不能放在一起(实际情况比这负责的多),当然你可以说放在一块再按版本号子目录存放,但这一是增加了深度,二是它的作用随着“多个项目的公共依赖部分的减少而减少”,况且硬盘的成本是很低的,所以最终还是取舍的问题。
nl101531
2020-06-03 08:48:08 +08:00
当初新建一个 hello world,下载了 1G 的依赖,惊了。。。
redbuck
2020-06-03 08:50:13 +08:00
我觉得不是包放哪里的问题.

而是包发布的时候就应该是完整可运行的.它依赖什么,发布的时候就应该打包好.变成它代码的一部分.

用包的人不应该关心某个包依赖什么.下载依赖的时候,也不应该下载它的依赖
jeeyong
2020-06-03 10:12:18 +08:00
上古时代是这么干的. 比如 python..但是都感受到了独立管理包的好处.
统一管理的时候会出现很多听起来不值得一提,但是发现->解决耗时不少的问题.
runze
2020-06-03 11:10:44 +08:00
@redbuck #35 这个也有历史原因,比如网页中用了三个 jQuery 的插件,肯定不可能每个插件自带一份 jQuery 。
现在也一样,一大堆 react-xxx 的库,也不能每个都自带 react 。
linrz
2020-06-03 11:46:20 +08:00
https://github.com/nodejs/node/issues/4584 早期也有人提出为什么不能像 maven 一样,或者自定义寻找依赖 resolve 的策略,但是回复是当时已经 lock 定稿了
julyclyde
2020-06-03 12:13:01 +08:00
感觉是“app 制度”而不是“env 制度”的
所以 node 用户和 docker 爱好者高度重叠
libook
2020-06-03 12:48:13 +08:00
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.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/678007

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX