为何Bundler反复选择需Ruby 2.0+的gem?Ruby1.9.3老项目问题
这问题我维护老Ruby项目时踩过好几次坑,Bundler在处理Ruby 1.9.3这种超旧版本时,确实容易出现版本选择的偏差,给你几个亲测有效的解决办法:
1. 锁定Bundler到兼容Ruby 1.9.3的版本
新的Bundler(2.x及以上)早就放弃支持Ruby 1.9.3了,如果你现在用的是高版本Bundler,它根本不会理你Gemfile里的Ruby版本声明,直接拉最新的gem版本。所以得先把Bundler换成兼容的旧版本:
# 先卸载所有已安装的Bundler版本 gem uninstall bundler --all # 安装支持Ruby 1.9.3的最后一个Bundler版本(1.17.3) gem install bundler -v 1.17.3
之后执行安装命令时,要指定用这个版本的Bundler:
bundle _1.17.3_ install
2. 给冲突的gem手动指定兼容版本
有些gem的新版本要求Ruby 2.0+,但旧版本是支持1.9.3的。你需要在Gemfile里明确给这些冲突的gem加上版本限制。比如我之前碰到过devise的问题,它的3.5.11版本是最后支持Ruby 1.9.3的:
# 示例:锁定devise到支持1.9.3的最高版本 gem 'devise', '<= 3.5.11'
怎么找兼容版本?可以用gem info [gem名]查看版本历史,或者去该gem的GitHub仓库看tags页的版本说明,找标注支持Ruby 1.9.3的最后一个版本。
3. 用--full-index参数强制Bundler查完整索引
有时候Bundler的本地缓存索引可能漏掉了旧版本的gem信息,导致它找不到兼容1.9.3的版本。执行安装时加上这个参数:
bundle _1.17.3_ install --full-index
这个参数会让Bundler从RubyGems的完整索引里找包,而不是用本地的精简缓存,更容易定位到旧版本的兼容gem。
4. 手动排查依赖链并调整Gemfile.lock(谨慎操作)
如果上面的方法都不行,先删掉现有的Gemfile.lock,然后在Gemfile里逐个锁定冲突gem的版本,再重新执行bundle install。如果还是报错,仔细看Bundler的错误输出——它会明确告诉你哪个gem依赖了要求Ruby 2.0+的版本,你需要顺着依赖链往上找,锁定那个依赖的兼容版本。
比如错误提示xxx gem requires ruby version >= 2.0.0,那你要么找xxx gem的旧版本,要么找依赖xxx的父gem的旧版本。
5. 确认JRuby的Ruby版本模拟是否正确
因为你用的是JRuby,得确保它是在模拟Ruby 1.9.3的模式下运行。执行下面的命令检查:
jruby -v
输出里应该包含ruby 1.9.3p551的信息,如果不是,就设置环境变量强制JRuby用1.9模式:
export JRUBY_OPTS="--1.9"
把这个配置加到服务器的环境变量里(比如~/.bashrc或者部署脚本),确保Bundler能正确识别当前的Ruby版本环境。
内容的提问来源于stack exchange,提问作者iconoclast

