其实也不用每次都安装node_modules,直接使用软连接即可:
windows 使用mklink /j node_modules %APPDATA%\Roaming\npm\node_modules
linux使用ls -s node_modules %APPDATA%\Roaming\npm\node_modules

nodejs中package.json中的依赖必须每个项目都有自己的node_modules文件夹,而无法在多个项目之间共用一套node_modules(像Java中的Maven那样)。

依赖管理是每个现代语言的标配。依赖管理和打包工具是两个概念,npm是依赖管理,webpack是打包工具。
在Java中,maven既能实现依赖管理又能实现打包。

何为依赖管理?
依赖管理说白了就是构建一个有向无环图。项目A依赖项目B,项目B依赖项目C,那么当你的项目依赖A的时候,依赖管理工具会自动让你的项目依赖B和C。
要想构建有向无环图,最关键的是要将项目转化为有向无环图中的结点。所以对于项目往往有description,作者信息,版本信息等额外信息。
依赖管理最难解决的问题就是版本问题。库A依赖库B,库C也依赖库B,但是库A跟库C所依赖的库B不是同一版本,如果库B的这两个版本兼容还好,如果不兼容就坑大发了,这是无解的问题。

下面说说Java,Python,Node三种语言中的依赖管理。

  • Java中的Maven仓库在开发者电脑上是全局的,所有项目的依赖都集中存放在本地仓库中。每个项目都有pom.xml指明依赖本地仓库中的哪些库。
  • Python中的pip跟maven很像,在开发者电脑上也是集中存放包,但是它不存在版本问题。也就是说,在你的电脑上每个python库都只有一个版本。既然如此,当你依赖某个库的时候,就无需指明版本号,直接引用包的名称就可以了。
  • Node中的依赖如果你不写package.json,那么依赖的就是全局的库;如果写了package.json,就会把所有依赖下载到node_modules文件夹。

Node这种node_modules文件夹的方式有利有弊。
最明显的坏处是:

  • 每次都需要安装依赖,费流量,网速慢时很费时间
  • 浪费磁盘空间,每个node_modules中包含的工具很多,动辄20M

最明显的好处是:

  • 使用package.json安装好之后,node_modules文件夹中没有版本信息,从而package.json可以删掉了。
    移动/复制/打包项目比较简单,对于开发、部署都有好处
  • 对于设计npm的人来说,这是最省事的包依赖方法。这就好比maven安装依赖之后自动将jar包安装到项目的lib里面。
  • 随意改代码。安装在node_modules里面的东西,你可以随便改,无需担心对其它项目的影响。在Java中使用maven管理项目时,如果想要定制某个库,就需要更改这个库的源代码,这时就需要把这个库的源代码复制到项目中,跟node_modules是一个道理。npm的设计者大概认为:前端都是经常修改库的源代码的。

我认为不同语言对于依赖的定位不同。Java中的库是严谨的库,Python中的库是玩具一样、随手写就的库,Node里的库是代码片段一样的库。Node里面的库既然定位就是代码片段,那么当然要将代码片段跟你的项目放在一起了,这样才方便你修改这些代码片段。可是随着时间推移,node中的库越来越大、越来越严谨,这种对待代码片段的方式就有些不好了。

总结:这是一种设计,这种设计有利有弊。

以下是知乎上的回答片段:

全局依赖的唯一好处就是省了硬盘空间。这种省毫无意义。首先如果你要为几十几百兆的硬盘空间斤斤计较,那么也许你已经穷得不适合做开发。其次如果需要支持全局多版本也省不了多少。至于有人说的,每次npm install时间太长,我认为这也不是个事。npm install又不是天天搞,而且只是第一次全新checkout的时候比较慢,以后都是增量更新。实在嫌慢(比如因为防火墙的原因),可以把node_modules一起提交到git里去。
其实我觉得完全可以做成全局的,依赖模块都装到公共目录,每个项目在 npm install 时用符号连接把每个模块对应的版本目录连过来,或者干脆就在 require() 时去全局的模块目录里去找,这样也不麻烦。实际上我团队就包了这样一个命令,安装时是全局安装,项目 init 时符号连接过来,很省时间和空间。但 npm 没有这么做,我觉得一是在一开始没考虑到,后面也就不好改了。实际上就连 node_modules 模块多层嵌套导致路径过长的问题,也是一开始设计时没考虑周全,到了 npm3 才改。

Java在20年前就解决这个问题了,然后后面抄的语言没有一个完全抄对的

参考资料

https://www.zhihu.com/question/41409670

转载于:https://www.cnblogs.com/weiyinfu/p/8471407.html

为什么 npm 要为每个项目单独安装一遍 node_modules?相关推荐

  1. cmd命令 - vue项目:单独安装vue-router

    cmd命令 - vue项目:单独安装vue-router 今天做测试的时候,发现之前的vue项目忘记安装vue-router 为了让项目能重新跑起来,只能另外安装一下vue-router 这里,总结一 ...

  2. 初识 npm script : 用 npm init 快速创建项目

    初识 npm script 首先介绍创建 package.json 文件的科学方法,目标是掌握 npm init 命令.然后,通过在终端中运行自动生成的 test 命令,详细讲解 npm 脚本基本执行 ...

  3. webpack 的基本使用—— 创建列表隔行变色项目||在项目中安装和配置 webpack

    创建列表隔行变色项目 ① 新建项目空白目录,并运行 npm init –y 命令,初始化包管理配置文件 package.json ② 新建 src 源代码目录 ③ 新建 src -> index ...

  4. vant部署_详解VUE项目中安装和使用vant组件

    Vant 是有赞前端团队基于有赞统一的规范实现的 Vue 组件库,提供了一整套 UI 基础组件和业务组件. 特性 50+ 个经过有赞线上业务检验的组件 单元测试覆盖率超过 90% 完善的中英文文档和示 ...

  5. npm、cnpm、yarn的安装与常用命令

    1.安装 npm curl -L https://www.npmjs.com/install.sh | sh a.临时使用(例如安装express) npm --registry https://re ...

  6. npm工具运行Vue项目

    检查npm管理包:npm -v npm集成在node中的 安装Vue:npm install vue 安装vue-cli:npm install -g vue-cli 初始化项目:vue init w ...

  7. 手把手建项目 PrimeNG安装使用

    手把手建项目 PrimeNG安装使用 之前写过一片关于PrimeNG的安装使用,当时也是接触不久,最近重新使用的时候发现还是有一些东西没有说清楚. 当时用的是Angular2现在已经是Angular4 ...

  8. VUE项目中安装和使用vant组件

    Vant 是有赞前端团队基于有赞统一的规范实现的 Vue 组件库,提供了一整套 UI 基础组件和业务组件. 特性 50+ 个经过有赞线上业务检验的组件 单元测试覆盖率超过 90% 完善的中英文文档和示 ...

  9. npm run serve起项目报错node-sass not find

    npm run serve起项目报错node-sass not find node-sass是开发中比较常见的依赖包,也是最常见见到的报错之一. 由于node-sass与别的依赖包不一样.而node- ...

最新文章

  1. 【 Vivado 】Performing System-Level Design Entry(总览)
  2. Presto实现原理和美团的使用实践
  3. Scrapy框架的学习(11.scrapy框架中的下载中间件的使用(DownloaderMiddlewares))
  4. EasyRTSPClient:基于live555封装的支持重连的RTSP客户端RTSPClient
  5. 初学者在python下使用Ta-lib库时遇到的一些问题及解决办法
  6. 《Python编程从入门到实践》记录之将Python函数存储在模块中(import、import*)
  7. html一个div调用的一个php页面,打开一个HTML文件,一个div/iframe中内PHP
  8. Apache Struts 和 Spring 开源漏洞状况的对比
  9. 如何用递归处理一个数组中的数据成为一个树结构_Spark处理的一些业务场景(持续更新ing)...
  10. SWF播放器object DEMO
  11. Onvif协议:IPC客户端开发之图像抓拍
  12. 自由软件运动与GNU项目
  13. ArcCatalog中通过ArcSDE向Oracle数据库中导入数据
  14. Arnold阿诺德电影级渲染器完全教学
  15. UINO优锘:深度|扒一扒图化资源申请之三生三世那点事儿
  16. 如何修复vagrant up失败错VBoxManage: error: The machine is already locked for a session (or being unlocked)
  17. Go微服务架构实战 中篇:6. 微服务治理策略
  18. 69的人因为穷不谈恋爱,这届年轻人脱单太难了
  19. CornerNet,CenterNet关键代码解读: kp,_decode,left pooling
  20. SSH协议原理和实践

热门文章

  1. 数据库设计需要注意什么
  2. 由System.getProperty(user.dir)引发的联想
  3. robotium(及百度cafe)运行testcase之后程序挂起没有响应的原因调查及解决
  4. SecureCRT无法使用root账户远程连接ubuntu
  5. 垂涎欲滴!30个美味的食品类移动应用程序【下篇】
  6. 怎样才能做好技术团队管理
  7. visual studio 2008 intellisense does not work
  8. 【Java从0到架构师】git 入门和基本应用
  9. 【matplotlib笔记】3D图像绘制
  10. 【南邮操作系统实验】页面置换算法(FIFO、LRU、OPT) C++ 版