请教,为什么大部分框架,工具,脚手架等都需要在你的项目目录下重复的安装 node_modules?

2019-05-28 20:40:51 +08:00
 abcbuzhiming
NPM 明明是有所谓全局依赖存储路径的啊,为什么每个项目还需要单独一份 node_modules,非常的占空间。为啥不能像 maven,Gradle,Nuget 那样,只存一份完事了。是历史习惯,还是不得不这么做?
8908 次点击
所在节点    Node.js
53 条回复
changdy
2019-05-29 08:34:14 +08:00
这点没得洗,依赖管理非常不友好.尤其是没有`package-lock`的时候.
然后前端本来也变化多段..跑旧项目的时候别提有多糟心了.
unclemcz
2019-05-29 08:35:13 +08:00
这是最简单粗暴的解决依赖版本问题的办法。
unclemcz
2019-05-29 08:36:50 +08:00
@changdy 对的,我最开始用 4,那时候还没有 package-lock,后来一次升级到 8 有了 package-lock,感觉世界都晴朗了。
xg4
2019-05-29 09:19:53 +08:00
还有很多相同的功能的不同模块,被引用到项目中。(轮子太多)
比如判断是否是对象,有 isObj, is-object, isObject 等等,不同的作者可能使用的库都不一样,可能都被下载到我们的 node_modules
lzvezr
2019-05-29 09:26:17 +08:00
版本不同,并不是所有人都爱做向下兼容
StephenHe
2019-05-29 09:28:12 +08:00
Yarn 会在 c 盘缓存,发现的时候 6 个 G 了。都存一个地方没改目录,恐怕 C 盘马上就爆掉了
abcbuzhiming
2019-05-29 09:31:00 +08:00
@KuroNekoFan 请问一下,npm5 到底能不能实现共享的依赖?如何实现?
abcbuzhiming
2019-05-29 09:32:44 +08:00
@lzvezr 版本不同没关系啊,我的意思是,难道不能同版本只留一份吗?一个统一的存放目录,xx 框架 1.0,2.0,3.0 各一份,其它项目想引用哪个版本就引用哪个版本啊,为啥非要像现在这样,一个项目下下一次 xx 框架 1.0。换个项目又下一次 1.0 ?
KuroNekoFan
2019-05-29 09:56:01 +08:00
@abcbuzhiming 只考虑 npm 的话,你可以不使用 npm install,通过手工做软链之类的来把项目依赖链接到你指定的位置,以项目(repo)角度来说,有一些工具可以实现依赖共享比如 lerna(昨天刚好看过一下相关讨论),另外,webpack 本身也可以指定 resolve 的位置。所以说方法有很多,但是共享依赖在很多 corner case 里会带来很多问题,所以 npm 本身的策略是,不共享
zpf124
2019-05-29 10:28:46 +08:00
@KuroNekoFan
我只看到一个提及 jar, 也并没有说 java 如何,那个是在拿 maven 类比,
题主本身就提到了 maven, 然后请百度 maven 是什么, 看看到底谁有 ptsd

maven 采用的方式就是 本地一个存储仓库,存放所有下载下来的不同版本的依赖包, 除了编译 build 时会复制项目用到的依赖外,所有的项目里都不会存在完全相同的依赖包.

而且 npm 本身问题一直不少, 比如 namespace
lihongjie0209
2019-05-29 10:32:31 +08:00
@zpf124
还是有明白人啊
KuroNekoFan
2019-05-29 11:35:05 +08:00
@zpf124 我觉得某些 java 用户被迫写 js 之后患上了 ptsd 有问题吗? maven 是 java 的仓库管理工具需要你来科普给我吗? npm 本身也有 cache 需要我写明白吗?现在 npm 有 @org/pkgname,你不知道,就代表没有吗?
lzvezr
2019-05-29 11:47:06 +08:00
@abcbuzhiming 现在应该是可以了吧,同一版本只下载一次
kzfile
2019-05-29 11:53:50 +08:00
多占点地方我无所谓,不出现冲突省事就行.
我倒是一直想,npm 下载下来的包如果是一个 webpack 打包好的独立 js 就好了
photon006
2019-05-29 12:01:01 +08:00
项目单独安装依赖挺好的呀,python venv 就是这样,毕竟不同项目使用的同一 package 可能是不同版本,所以要单独安装。


如果嫌 npm 安装慢那是自己网络问题,可以用国内淘宝源:npm install --registry=https://registry.npm.taobao.org

或者用 openwrt 路由器彻底解决网络问题。
xihefeng
2019-05-29 12:02:18 +08:00
争吵没有意义,上来扣帽子无聊
现在我想知道的是,npm 的这类历史遗留问题还是否会进行改进
一种轮子如果不吸取别的地方的精华,只能是自己玩的欢
@KuroNekoFan #32
xihefeng
2019-05-29 12:09:47 +08:00
再补充一个 https://www.zhihu.com/question/41409670?sort=created
Java 在 20 年前就解决这个问题了,然后后面抄的语言没有一个完全抄对的
azh7138m
2019-05-29 12:35:57 +08:00
@xihefeng 不会改进
而且其他包管理器早晚会在每个项目本地搞一个依赖目录的(滑稽

npm 在这里试图解决的问题是
当你的项目 P 存在依赖 A、B、C、D 时,
P 依赖 D@1
A 依赖 D@2
B 依赖 D@3
C 依赖 D@4
这种问题是要考虑的


这里能优化的是两个场景
- 一个是已经被 yarn 和 npm 做掉的,一个项目内对一个依赖有多次依赖的时候,会尽量 resolve 到同一个版本(其实新版 npm 做的比 yarn 好,能让 node_modules 更扁平,但是带来了更多的问题(滑稽
- 另一个是楼主说的 不同的项目对一个依赖要求的版本相同的时候,能不能只存一份

后面这个有点尴尬,依赖是往上不断找 node_modules 的,按道理是可以做一个 "根 node_modules",但是
P1 P2 依赖 D@1
P3 P4 依赖 D@2
要怎么处理呢?
symlink 也不行,webpack 的 resolve.symlinks 可以使用文件的真实路径,如果这么搞,算是 break change,非常僵硬。


或者就等,真 break change,PnP 上线吧,完全由 js 来控制 resolve 依赖的行为,新的依赖布局不需要过多考虑兼容性,能有更多的操作空间。
libook
2019-05-29 12:45:48 +08:00
不黑不吹,也不说无关的事。

有人喜欢放在统一的目录里,有的人喜欢相互隔离,事实上确实不同应用场景下有不同的需求,不能说哪一种绝对好;工具只能提供一种默认方案(两种就不叫默认了),但工具也可以提供足够的灵活性来让人们自助解决需求差异。

Node 对与 node_modules 的搜索是有一个规则的,规则不满足需求也可以用 NODE_PATH 机制来指定,可以结合一些 Npm 的指令以及自动化脚本来 Hack 出一个基于 Npm 的集中包管理机制。
Npm 并不是 Node modules 的唯一管理工具,pnpm 就可以提供“ One version of a package is saved only ever once on a disk.”的特性。

实现整个系统环境或用户环境有一个共享的包目录所遇到的问题,肯定比实现每个项目下有一个包安装目录遇到的问题要复杂。举个例子,要删除一个包或一个版本的包的时候,肯定是基于一个项目的需求来删除的,但共享目录是所有项目都在用的,那仅当只有这一个项目依赖这个包的时候才可以删除这个包,这有点类似垃圾回收机制。类似的问题肯定是可以有解决方案的,只不过也一定是需要额外的成本的,将一个项目的问题封锁在项目目录内,相当于是将包管理的问题降维,这可能是 Npm 一直在用这个方案的一个历史原因。

对于 Node 服务开发来说,依赖包占用空间多的情况较少,问题主要集中在网页开发方面,这个其实不是 Npm 的锅,主要是现在网页开发应用的语言太多,每种都需要特定的编译程序的支持,比如 JSX、Vue、Sass、TypeScript 等等,空间占用大,编译时间长,最终生成的网站大小并不大(否则就会有流量问题和加载性能问题了)。

所以建议根据项目的具体情况来选择包管理方案。
lqzhgood
2019-05-29 12:46:07 +08:00
嗯。。。 我觉得硬盘不值钱呐。 那就用最简单的办法 node_modules 嵌套处理包依赖吧。
如果 node_modules 名字是 a 开头如 a_node_modules 就更好了~ 还能防 rm -rf ....
逃~~

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

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

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

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

© 2021 V2EX