大多数npm库都严重依赖于其他npm库,这会导致嵌套依赖关系,并增加无法匹配相应版本的几率。
虽然可以通过npm config set save-exact true
命令关闭在版本号前面使用^
的默认行为,但这个只会影响顶级依赖关系。由于每个依赖的库都有自己的package.json
文件,而在它们自己的依赖关系前面可能会有^
符号,所以无法通过package.json
文件为嵌套依赖的内容提供保证。
为了解决这个问题,npm提供了shrinkwrap
命令。此命令将生成一个npm-shrinkwrap.json
文件,为所有库和所有嵌套依赖的库记录确切的版本。
然而,即使存在npm-shrinkwrap.json
这个文件,npm也只会锁定库的版本,而不是库的内容。即便npm现在也能阻止用户多次重复发布库的同一版本,但是npm管理员仍然具有强制更新某些库的权力。
这是引用自shrinkwrap
文档的内容:
如果你希望锁定包中的特定字节,比如是为了保证能正确地重新部署或构建,那么你应该在源代码控制中检查依赖关系,或者采取一些其他的机制来校验内容,而不是靠校验版本。
npm 2
会安装每一个包所依赖的所有依赖项。如果我们有这么一个项目,它依赖项目A,项目A依赖项目B,项目B依赖项目C,那么依赖树将如下所示:
node_modules
- package-A
– node_modules
— package-B
----- node_modules
------ package-C
-------- some-really-really-really-long-file-name-in-package-c.js
这个结构可能会很长。这对于基于Unix的操作系统来说只不过是一个小烦恼,但对于Windows来说却是个破坏性的东西,因为有很多程序无法处理超过260个字符的文件路径名。
npm 3
采用了扁平依赖关系树来解决这个问题,所以我们的3个项目结构现在看起来如下所示:
node_modules
-
package-A
-
package-B</