Nodejs npm node_modules 为什么会是现在这样

发布于 1周前 作者 yuanlaile 来自 nodejs/Nestjs

Nodejs npm node_modules 为什么会是现在这样

都在吐槽 npm 的设计,依赖地狱、小文件多、占用空间大、慢。

那是什么导致了 npm 必须设计成现在这样呢,其它语言的包管理工具为什么没有这些问题(比如 manven)?

node 包管理有没有新的方案在开发中?

35 回复

我觉得 npm 的报管理还行啊,
包的依赖是有改进地方,但没到地狱那么夸张吧,
小文件多是什么意思呢
项目 node_module 占用空间应该在 500M 以内吧,发布环境再指定环境安装再砍掉一半空间,就现在的硬件条件这个空间不是什么吧
慢是什么慢呢

其他语言不了解,至少比 go 好用,哈哈


新版本的 npm 还行吧。或者换 yarn 。node_modules 里东西多,依赖复杂主要还是 js 生态没有一个比较强的 std lib 吧。啥都要导个包。依赖能少么。

#1 慢应该是从 npm 服务器去找详细下载地址慢,如果有 lock 文件会快很多。

是 java dotnet php… 等等以前古典语言的模块管理机制导致 npm 设计成现在这个样子的

也就是 npm 是一个纯粹为了工程上行得通, 没太考虑优美的方案

反正我经常 npm install 报错, 改用 yarn install 就没有问题。

其他语言也有这些问题的,有些是靠编译解决了一部分。
但是主要还是前端库太多了,依赖链条一长就变成这样了。

“项目 node_module 占用空间应该在 500M 以内吧”

这个吧 好家伙 500M 算是可以接受的空间了么 是真没见过别的语言的包管理机制?

新版本的 npm 已经不错了,老版本的才是恶心,那时候真是地狱
也可以试下 yarn 和 pnpm,我感觉没有差太多
慢的问题可以看下网络和数据源的选择,国内可以使用淘宝或其他的数据源,会快一些

npm 本身还是没有规范。doc, src 为什么要上传。Github/gitlab 地址给出,让用户自己去看就好了。展平+单文件估计可以省很多空间。

看了下,感觉 npm install --global 又回来了

Ruby 默认是安装到语言目录而不是项目目录的,而且很久以前就有 lock 文件

倒也不是,global 只能 install 一个版本吧,pnpm 好歹让你感觉上和 local install 没有区别

go 感觉是比较完美的,特别是容器化后专门一个 volume 挂载 module 目录,所有项目通用。npm 黑洞真的心疼硬盘,不能理解为什么要一个项目一个包,PHP 是特殊的运行机制决定的,而 Node 工程化变成编译型语言后,为啥不和 go 那样设计成 “从仓库里找工具包” 的感觉。

小文件多是因为 js 语言本身标准库不怎么样,挺多简单的功能不想自己写就得找个现成依赖。

捕捉 bangumi 大佬(之前有在论坛问过爬虫的问题🤣

node_modules 无底洞这口锅分给谁都行,恰恰只有 npm 一点都分不上。反而是因为 npm 设计得非常优秀,各种循环依赖重复依赖版本问题都能得到解决,使得各种无底洞居然还能勉强跑起来。
你要觉得是 npm 过于优秀导致的大家胡乱搞依赖所以一定要分给它锅那我也无话可说。但是你说有没有新的方案在开发中就太扯了,难道要把功能全砍掉重新开发一个基于 git 地址的残废包管理器用强行增加用新包的难度来促使包的平均质量增加吗?

草,别这么叫,太尴尬了…

依赖地狱、小文件多、占用空间大、慢 不能说是 npm 的问题,是 JS 生态滥用三方包导致软件复杂度严重升高的结果,毕竟软件成品的复杂度肯定是大于需求的复杂度的。
甚至再说大一点,任何滥用三方包的应用程序或者说生态的成品都会遇到上述四个问题。每一层组件都滥用三方包之后,再用这些组件层层叠加组成的项目肯定是各种无底洞的,开发再聪明也无能为力。

看了下 ruby 的,我的 700 多 M,不过是共享的,当然也可以设置单独的 set 。

有一部分原因应该和 Node 依照文件系统逐级查找,且一个包有很多种入口可能性,需要按照 Fallback 顺序检测直到完成加载的模块 Resolution 机制有关。这种模型包括 CommonJS 设计之初是基于文件系统的访问速度很快可以忽略不记的假设成立之上的。连它本身都这么设计,npm 也没有道理不一切从简,然后就出现了比黑洞更深,令 Windows 瑟瑟发抖的恐怖存在。谁能想到之后会如此复杂,npm 也不得不做出调整。包括 yarn PnP 设计的一大理由就是没有理由惯着 Node 这么粗放动态的模块 Resolution 机制。

如果你说的是充当前端构建工具的 Node,那个占硬盘、小文件多、慢也占不到用户头上,如果乐意的话构建前安装,每次构建完了就删,和 CI 的思路就一样了;前端需要解决的问题复杂度已经很多人说过了,这个实在是没办法。另外谁叫所有人都在写 SPA,或许是图方便大量程序员间的协调?不少人说前端卷,好像在想尽办法提升后来人的入门台阶。这个确实有,比如各种 KPI 开源项目,不过这顶帽子怎么也安不到 npm 和 node_modules 上。

如果你说的是当后端使的 Node,除了有很多框架原生支持 TypeScript 之外,似乎很少有听说过后端需要编译的。后端领域因为环境可控,不太可能会引入前端的那些 Polyfill/Shim, Transpiling, Purge 库和相关的 Bundle 工具链等等,node_modules 不会很夸张。所以 Node 作为所谓 Server Side JS,其实并没有后端生态( x

要说未来发展,听各位描述了一下 pnpm,似乎约等于 Node 版的 Bundler 啊。我还挺期待 yarn PnP 以后会是什么样子,毕竟 npm 抄过 yarn 的依赖扁平化,没道理不再抄一次。

不过私以为影响 Node (主要是前端)生态的最大问题是,再过几年可能所有人都去用 esbuild 这种压根不打包的工具( Elixir Phoenix 1.6 就已经决定把 Node 和 webpack 踢了,自己管理 esbuild 。这样用一个单一的二进制,所有进程都由 Erlang BEAM Port 管理还恰恰更加符合 Elixir Mix 的特色),除了老项目之外还有没有 Node 的事还不一定呢,所以干脆就别改了,现凑活凑活用过这几年算了吧(逃

就目前看来 pnpm 相当程度上夺走了 yarn 的风光。yarn 现在都出到 v3 了,PnP 生态还是没搞起来,各种主流框架工具(点名 typescript )都没能全支持。更不用说一大堆人还停留在 yarn v1 。不过 yarn workspace 还是算比较给力的。

pnpm 算是用相当折中的方式来解决依赖地狱问题。尽管 node_modules 还是层层相套,但是 symlink 节省了很大空间,而且跨项目共享一个 store 。目前唯一问题是个别工具对 symlinked node_modules 兼容不够好(点名 jest )。



这两年 esbuild / vite 爆火,webpack 也算是完成探索前端工程化的历史使命了

依赖要学会精简呢…
nodejs 一般项目也就 60m 左右 vue 项目 100m 左右
如果大的太离谱.是不是项目第三方用太多造成的…
有些东西能自己开发就少用第三方库.万年不升级优化 package.json 那也是项目大坑

.npmignore 就可以不发布. 作者的问题而已.

那也是不够规范。比如某个包超过一定的依赖,它就得锁住,不然开发者一删除,就全挂了

一个函数都要引用一下依赖,各种 README,能不大吗。

node_modules 占用空间其实都还能忍受,关键是它小文件太多啊,这点太要命了,拷贝删除都非常的慢,慢的令人发指

go 挺好用的啊 不是有 go.mod 吗 而且在依赖库文件体积上 go.mod 要比 manven composer 这些小多了

你看他说 go 的包管理不咋样,就知道了 ,完全不懂别的语言,node js 的包管理比其他的差多了

1 楼 go 黑给我看笑了

现在的还行了,前几年的时候 node_modules 还是循环嵌套的,那才叫恶心。。

关于“Nodejs、npm、node_modules为什么会是现在这样”,可以从以下几个方面进行解释:

Nodejs

Node.js是一个基于Chrome V8引擎的JavaScript运行时环境,用于构建快速、可扩展的网络应用程序。自2009年Ryan Dahl首次发布以来,Node.js凭借其高效的性能和丰富的生态系统,逐渐成为JavaScript开发者在服务器端的首选环境。

npm

npm(Node Package Manager)是Node.js的包管理器,由Isaac Z. Schlueter于2010年创立。它允许开发者轻松地安装、更新和管理项目中的JavaScript代码库的包或模块。npm的开放性和易用性使其迅速普及,成为JavaScript生态系统中最流行的包管理工具。

node_modules

node_modules文件夹是npm安装管理的依赖库所在目录。在Node.js项目中,当你使用npm安装包时,这些包会被下载并安装到node_modules文件夹中。由于node_modules的内容在npm install过程中可能会被重写或更新,因此直接修改其中的代码通常不生效,也不推荐这样做。

综上所述,Nodejs、npm以及node_modules的现状是JavaScript生态系统不断演进和完善的结果。它们共同构成了现代JavaScript开发的核心基础设施,为开发者提供了极大的便利。

回到顶部