使用NPM安装的时候会常常出现包冲突(好比多个主模块的子模块版本不一致等),致使在开发过程当中会遇到各类或大或小的问题。全部在这会介绍如下内容:html
NPM 各类安装方式node
npm install packageName[@next | @versionNumber]
git
npm install packageName --f | -- force
github
npm update packageName
npm
NPM 查询服务json
npm view packageName [version]
查询对映模块的信息输入 npm install 命令并敲下回车后,会经历以下几个阶段(以 npm 5.5.1 为例):缓存
1. 执行工程自身 preinstall函数
当前 npm 工程若是定义了 preinstall 钩子此时会被执行。post
2. 肯定首层依赖模块code
首先须要作的是肯定工程中的首层依赖,也就是 dependencies
和 devDependencies
属性中直接指定的模块(假设此时没有添加 npm install 参数)。
工程自己是整棵依赖树的根节点,每一个首层依赖模块都是根节点下面的一棵子树,npm 会开启多进程从每一个首层依赖模块开始逐步寻找更深层级的节点。
若是查询node_modules目录之中已经存在指定模块,那么再也不从新安装
3. 获取模块
获取模块是一个递归的过程,分为如下几步:
4. 模块扁平化(dedupe)
一步获取到的是一棵完整的依赖树,其中可能包含大量重复模块。好比 A 模块依赖于 loadsh,B 模块一样依赖于 lodash。在 npm3 之前会严格按照依赖树的结构进行安装,所以会形成模块冗余。
从 npm3 版本
开始默认加入了一个 dedupe 的过程。它会遍历全部节点,逐个将模块放在根节点下面,也就是 node-modules 的第一层。当发现有重复模块时,则将其丢弃。
这里须要对重复模块进行一个定义,它指的是模块名相同且 semver 兼容。每一个 semver 都对应一段版本容许范围,若是两个模块的版本容许范围存在交集,那么就能够获得一个兼容版本,而没必要版本号彻底一致,这可使更多冗余模块在 dedupe 过程当中被去掉。
好比
举个例子,假设一个依赖树本来是这样:
node_modules -- foo ---- lodash@version1
-- bar ---- lodash@version2
假设 version1 和 version2 是兼容版本,则通过 dedupe 会成为下面的形式:
node_modules -- foo
-- bar
-- lodash(保留的版本为兼容版本)
假设 version1 和 version2 为非兼容版本,则后面的版本保留在依赖树中:
node_modules -- foo -- lodash@version1
-- bar ---- lodash@version2
5. 安装模块
这一步将会更新工程中的 node_modules,并执行模块中的生命周期函数(按照 preinstall、install、postinstall 的顺序)。
6. 执行工程自身生命周期
当前 npm 工程若是定义了钩子此时会被执行(按照 install、postinstall、prepublish、prepare 的顺序)。
最后一步是生成或更新版本描述文件,npm install 过程完成。
文章分享同步于: github.com/zhongmeizhi…
参考