node最恶劣的设计,就是node_modules了
发布于 10 年前 作者 kingapple 105494 次浏览 最后一次编辑是 8 年前 来自 分享

一个项目,某个模块的副本可能超过10个,太浪费空间了:(

71 回复

这个设计是有必要的, 不同的模块依赖的版本可能不相同。

@hackerjs java为何不这么干?应该向java学习的:(

@hackerjs node同时存在多个副本,也会导致混乱?

是个问题。

你因为模块多 服务器内存不够用了?

1楼正解。 另外node的模块一般都不大,多个副本也占不不了多少空间,相对于减少依赖的复杂度来说,这点浪费应该是值得的。

“一个项目,某个模块的副本可能超过10个”

你这明显不会写package么

@tulayang 啥意思? node_modules嵌套可能超过10层啊。。。。这不是浪费空间么?一个版本有一个副本不就够了么?

@kingapple

嵌套? 是你自己不会写而已。

编程语言if else也能嵌套,但是会写的就不会多少嵌套。

node_modules 在规范上应该只有1层才对

你在模块里又放入node_modules文件夹,本身就是错误的。全局只应该有1个node_modules文件夹,所有的外部模块通过package管理。

你的系统应该类似这样放置:

-node_modules- a,b,c,...   // 任何第3方模块
-lib  //  你自己的代码
-src //  你自己的c代码
-... // 其他文件夹

@tulayang node_modules/xxx/nodules_modules这种目录结构太常见了啊。。。

还有,如果你只是发布单个模块,文件里不应该带node_modules,而应该通过package.json指明你的依赖。 这样别人的node_modules文件里会自动加入依赖。

@kingapple

谁说这是常见的,这是严重的错误的。

这个反而是Node.js的优势……

加载模块还有缓存机制,所以性能上也不会因为模块多导致慢

Node.js 一个很不错的设计…在你眼里成了恶劣…目测应该是洁癖党…再说了…冗余点空间…比到时候各种版本冲突好不能太多了…

@tulayang ⊙﹏⊙b汗,A/B B/C C/A A依赖B,B依赖C C依赖A 目录结构会是A/node_modules/B/node_modules/C/node_modules/A 。。。

@tulayang 显然通过.json指明依赖啊

@kingapple 跟你说了,这是错误的。 只要你的项目全局有一个node_modules,其他模块都会自动到这个文件夹中去挂载依赖。

而且这种方式,跟C语言的加载是很相似的。

@youxiachai 同一个版本是否可能在内存中加载多份?

@tulayang 看一下这个

hexo\node_modules\gulp-jshint\node_modules\gulp-util\node_modules\chalk\node_modules\strip-ansi\node_modules

亮瞎狗眼了:(

@kingapple

小朋友总能写出神奇的代码,这有什么稀奇的。

错的不是语言,或者API,错的是使用者根本就不知道他使用的东西的机制。

上边的这个项目,明显是没有团队代码的概念。

@tulayang 应该肿么写?

@kingapple

hexo -node_modules- ------------------------------gulp-jshint ------------------------------gulp-util ------------------------------chalk ------------------------------strip-ansi ------------------------------…

@whatsmynick 百科缺钱了。。。

这样我看没啥问题。

@tulayang 汗,这得知道依赖关系才行啊。。。

@kingapple

任何在node_modules都会被全局引用到,依赖是很简单的

@tulayang 为何npm不自动把依赖下载到本地node_modules下,而是另外建立一个目录xxx/node_modules

@kingapple 那是因为你在下载的模块的文件夹中,直接install。

每次不用重复加载,有缓存吧

@tulayang 啥意思?不都是直接install的么?

@Hi-Rube 我说的是加载到内存啊,亲:)

@kingapple

install之前要在项目package.json指明依赖,安装路径要在项目主文件夹install。

@tulayang 当然是在主目录install啊, 然后了那个很长的奇葩路径啊。。。

@kingapple 那你一个项目有多少模块啊。。。没有到内存受不了的程度吧

@yorkie if (cachedModule) { return cachedModule.exports; }

if (NativeModule.exists(filename)) { // REPL is a special case, because it needs the real require. if (filename == ‘repl’) { var replModule = new Module(‘repl’); replModule._compile(NativeModule.getSource(‘repl’), ‘repl.js’); NativeModule._cache.repl = replModule; return replModule.exports; }

debug('load native module ' + request);
return NativeModule.require(filename);

}

棒棒

@kingapple if (cachedModule) { return cachedModule.exports; }

if (NativeModule.exists(filename)) { // REPL is a special case, because it needs the real require. if (filename == ‘repl’) { var replModule = new Module(‘repl’); replModule._compile(NativeModule.getSource(‘repl’), ‘repl.js’); NativeModule._cache.repl = replModule; return replModule.exports; }

debug('load native module ' + request);
return NativeModule.require(filename);

}

@Hi-Rube 以路径来命名模块? 赶脚如果路径不同,模块有两个副本,也会当成两个模块,而不会有缓存功能。。

这个绝对是node.js的优势,这样做非常好,各个项目依赖的包版本号可能不相同,很好的独立各个项目,不像Python为了这个功能还需要搞一个 VirtualEnv 来管理各个项目的依赖包版本,node.js原生支持还不满足?

@Hi-Rube 我不是韩国人

@kingapple 额是这样的,路径不同的两个一样的模块是不一样的

@yorkie 夸你棒。。。为什么会有这种先入为主的想法。。。为什么会首先想到韩国人,我都没说棒子

之前bower拉取bootstrap好像,想删除不让我删除,提示我超出文件长度啥的,嵌套好深,一层又一层…我win7系统…

@fancyboynet 用bower的好处是不需要把框架代码放在项目中? 这样版本库可以小一点?

@kingapple 没试过,不过应该可行,只要控制配置文件,自己install就可以了

感觉这个是node的优势,把依赖设计成树状而不是图状,能够很好的解决同一个模块的不同版本的依赖问题,这个浪费是非常值得的。

楼主,你确认你会用node_module? 一旦顶层有了这个module,下面就不再去下载了哦!

只能说 npm 和 node不是一起做的,npm的install -g 装到AppData\Roming\npm下面

node的require有全局路径 C:\user\Administrator.node_modules\ 但是npm 硬是自己搞一个

不爽npm可以自己搞一个出来吗,再搭个registry,就行了

@tulayang @tulayang 其实楼主所说的情况很常见,并不奇怪。比如模块A依赖模块B,而模块B又依赖模块C,模块C又依赖模块D。然后在npm install的时候就会出现那样的文件目录,因为每个npm模块都应该有个package.json。 而安装的时候默认就是安装在其所在目录下。

但是楼主所担心的问题,nodejs在设计时候也已经考虑到了。

模块的加载机制,模块首次使用的时候,会缓存此模块编译好的文件。当require的时候首先是从缓存中获取,而缓存的模块其实是编译好的,这也大大减少了加载和编译的时间。其次才会去加载核心模块,自定义模块和文件路径模块。具体的加载机制你可以在google下

好消息…lz 的愿望在未来的npm 3.0 将会实现…

http://tw.iojs.org/2015/02/24/npm-weekly-6/

ps: 看来npm现在有钱,有时间,有人开发复杂功能了…

看到标题就知道LZ肯定会被教育。。。进来一看,果然~~

@tulayang

Try npm install npm

然后看看

ls node_modules/npm/node_modules/request/node_modules

楼主需要的是dedupe命令 npm help dedupe

@youxiachai 滚了一屏幕还是看到这个最振奋人心~~~~这问题是客观上普遍存在的,不过不是node的问题,算是npm的问题

不同嵌套深度的相同版本的模块会只被缓存一次?好像即使是两个相同版本的模块,还是会被当做完全独立的模块

这不是node的问题,你要是不嫌麻烦,把嵌套的node_modules里边的模块全部拷贝到根目录的node_modules里node运行也是没问题的。 楼主说的问题确实存在,windows用户应该经常碰到拷贝或者删除node_modules目录时系统报路径太长的错误,但那是npm的问题。

看了这么多其实我想问… 楼主是处女座的吧?

曾经因为目录路径太深,无法通过普通方式删除项目文件夹。

这么做的好处显而易见,a 依赖 b,c 依赖另一个版本的 b,两个版本的 b 差了一个大版本,不兼容。python 就很蛋疼,所有大环境只能用一套版本的包管理都很蛋疼。我是一个被 npm 宠坏的孩子,就是因为 node_modules。

npm dedupe 跑了半分多钟, 电脑都烫了

楼主可能不知道有个东西叫NODE_PATH环境变量。 此外,很多在全局安装过的包,在node_modules里是通过软链接的方式链接进去的。

这个时候跑过来挖坟是几个意思

npm3是模块就扁平化处理了,结果带来的麻烦是就是很难找对应的模块,依赖太多,一下子翻不过来.orz

挖你祖坟 哈哈

回到顶部