@
jason0916 插件管理有两个作用,一个是说明需要装的插件,一个是解决依赖并锁定插件版本。
传统上的 requirements.txt 兼具了这两个作用。但是有一个问题,依赖关系和版本锁定非常复杂,手写的话不仅非常麻烦,而且很容易出错。所以有 pip freeze 功能。但是 pip freeze 功能又有一个问题,就是他把系统上所有安装的包都给 freeze 下来了:有些是你其他 project 的包,有些是你临时装了 debug 用的、或者是一些命令行小工具,你不想放进 repository 的。
Virtualenv 是一个解决方法。至少其他 project 的包不会进来了。但是这样的话,不同 project 需要安装好几次一样的包,浪费空间。另外,临时的 debug 工具这种情况,还是会被 freeze 下来。
以 Ruby 的 Bundler 为代表,把“说明需要装的插件”功能和“解决依赖并锁定插件版本”功能分开了。分为 Gemfile 和 Gemfile.lock. 前者格式非常简单,并且可以方便的指定人为限定的附加信息如:我需要 Rails 这个包,> 4.0 版本。这个文件手动编辑。另一个 lock 文件,是自动生成的,比如精确到 Rails 4.2.1 版本。在第一次 bundle install 时,系统把能够满足依赖关系的精确版本记录在 lock 文件里,其他开发者使用、部署的时候就会用完全一模一样的版本,避免莫名其妙的问题。
同时,同一台机器上即使有多个 project ,也不需要把同一个包装好几遍了。 Ruby 的 bundler 在使用时,可以在系统内多个版本的同一个包中,只读取 lock 文件制定的精确版本。甚至可以 Bundle.require 一次性 load 所有包。