测试环境 npm-v 6.8.0
要了解npm解决包冲突的问题,就要先了解一下他是如何找包的
node中require查找依赖的方式
│ app.js
│
└───node_modules
一般我们们的app.js中的requier查找依赖的时候,会去目录下的node_modules去寻找
但是,实际他会以一种依次向上的方式进行寻找,这里以common模块依赖jquery为例
// common.js
let $ = require('jquery')
- 向外层目录寻找(当前目录没找到指定的js)
│ app.js
│
├───common
│ │ common.js
│ │
│ └───node_modules
│ └───bootstrap
└───node_modules
└───jquery
1. 首先 common.js会在本级的node_modules中寻找是否存在jquery
2. 之后,他会向上一层目录去寻找,是否有node_modules,并去寻找
- 向外层目录寻找(当前目录不存在node_modules)
│ app.js
│
├───common
│ common.js
│
└───node_modules
└───jquery
1. 首先,common.js的本级目录不存在node_modules,直接跳向上一级目录
2. 在上级目录中,找到了指定的js
- 向多层目录下寻找(直到找到根目录为止)
│ app.js
│
├───mgr
│ └───public
│ ├───common
│ │ │ common.js
│ │ │
│ │ └───node_modules
│ │ └───bootstrap
│ └───node_modules
│ └───express
└───node_modules
└───jquery
1. 首先,common.js在本级的node_modules中寻找,未找到,跳转到上一级目录
2. 查找到了public目录, 查看此目录的node_modules中寻找,未找到,跳转上一级目录
3. 来到了mgr目录, 未找到node_modules目录,继续向上寻找
4. 来到了项目根目录下,在本级的node_modules中,寻找到了
可以看出,他在寻找的时候,会依次向上寻找,直到根目录下
- node不会去兄弟目录中查找
│ app.js
│
├───common
│ │ common.js
│ │
│ └───node_modules
│ └───bootstrap
├───host
│ └───node_modules
│ └───jquery
└───node_modules
└───express
1. common.js去本级node_modules目录下寻找,没有找到,返回上一级
2. 来到了项目根目录,去本级目录下的node_modules目录下寻找,没有找到,寻找结束,未找到。
3. **注意,他不会钻到他的兄弟目录host中去寻找**,他只能向上寻找,不能向下。
npm解决包冲突的问题
- 有两个相同的项目依赖了同一个文件
├───a
│ └───c_v1.0.0
└───b
└───c_v2.0.0
+ a 依赖了1.0.0的c文件
+ b 依赖了2.0.0的c文件
- 版本不同的时候,他会分别在各自的包下建立node_modules文件
│ app.js
│
└───node_modules
├───a
│ └───node_modules
│ └───c(v1.0.0)
├───b
│ └───node_modules
│ └───c(v2.0.0)
├───bootstrap
├───c
└───jquery
+ a依赖了的c包(1.0.0) (实际上没有版本号,就叫c)
+ b依赖了的c包2.0.0 (实际上没有版本号,就叫c)
+ 由于他查找包的机制,就会找到适合自己版本的
- 仅仅单个版本不同
│ app.js
│
└───node_modules
├───a
│ └───node_modules
│ └───c(v1.0.0)
├───b
├───d
├───bootstrap
├───c
└───jquery
+ a依赖了c包(1.0.0)
+ b也依赖的c包
+ d也依赖的c包
+ 由于包查找机制,先从内层查找,依次向外翻,a会使用它特定版本的c,其他使用外部的c就好