package.json 的困境
package.json 不能够保证每次安装的依赖的唯一性。 举例来说:
A 模块:1
2
3
4
5
6
7{
"name": "A",
"version": "0.1.0",
"dependencies": {
"B": "<0.1.0"
}
}
依赖版本号小于 0.1.0 的 B 模块。1
2
3
4
5
6
7{
"name": "B",
"version": "0.0.1",
"dependencies": {
"C": "<0.1.0"
}
}
我们在开发的时候 B 模块时 0.0.1。下一次执行 npm install 的 B 模块发布了 0.0.2 版本。此时安装到的版本时 B 的 0.02 版。出现了不一致情况。
npm 推荐 sermer 的规则来管理自己的版本发布:1
2
3- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards-compatible manner, and
- PATCH version when you make backwards-compatible bug fixes.
sermer 的目的是让代码升级到最新的 bug fix。但是,通常一个项目依赖成百上千个模块,你并不能确定哪一个模块会出问题。
一定要选择靠谱的开源模块 并不能解决你的忧虑。
相信别人,还是相信自己?从可控性角度来说,当然是相信自己。我们需要的是一个 single of truth 的依赖树。
yarn.lock
npm 的 对待此问题的行动迟缓 (君不见 nodejs、io-js), facebook 开发出了 yarn 来解决npm 的 lock 和 cache 等问题。
版本锁定 与 install 等操作同步,保证了 node_modules 的一致性。实现了我们想要的 single of truth 的依赖树。
package-lock.json
有竞争就有改进的动力。 npm 5 发布,默认支持 package-lock.json。
1 | package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates. |
一个简单的例子:
1 | { |
package-lock 描述了所有相关依赖的具体版本,并且会随着 npm install 变化而变化。弥补了 package.json 的不足。
npm-shrinkwrap.json
npm-shrinkwrap.json 和 package-lock.json 内容是相同的。不同之处在于:
- npm-shrinkwrap.json 优先级较高。install 时会优先采用。
- 可发布到 registry。使用场景仅在:模块通常以 daemon 形式后台运行,或者依赖在dev中。其他请用package-lock.json。
结论
要使得避免“我这里是好的”这种情况。npm 5 是不错的选择。低版本推荐用 yarn 替代。