← 中文资源

简体中文版本

Ruby LoadError 无法加载文件 — Bundler 与 Gem 解析

通过 bundle check、bundle exec 与加载路径排查 Ruby LoadError,修复缺失 gem、平台锁文件与原生扩展编译问题。

阅读英文原文

现象

报 LoadError: cannot load such file -- nokogiri,或 Bundler::GemNotFound;直接 ruby app.rb 能跑,用 bundle exec 反而失败;部署到不同 CPU 架构或 Ruby 版本时失败。

诊断

先区分“没安装”和“用错执行方式”:

bundle check
bundle exec ruby app.rb
bundle exec ruby -e "require 'nokogiri'; puts Nokogiri::VERSION"
bundle platform
gem env home

bundle check 列出缺失的 gem;已满足但仍报错,说明加载路径或执行入口不对。bundle exec 会把 $LOAD_PATH 限制为 Gemfile 中的版本,如果这样能跑而普通 ruby 不行,说明应用一直在依赖全局安装的 gem。gem env home 可暴露 rbenv、rvm 或系统 Ruby 之间的错位。bundle platform 与 bundle config list 用于检查平台锁和排除的 group。

修复

使用部署环境的 Ruby 执行 bundle install,始终通过 bundle exec 或 binstub 启动应用,缺失的 gem 写入 Gemfile 而不是全局安装:

bundle config set --local path vendor/bundle
bundle install
bundle lock --add-platform x86_64-linux
bundle exec ruby app.rb

原生扩展需要编译工具与头文件,应放在构建阶段而不是运行时镜像;用 .ruby-version 固定 Ruby 版本,避免 ABI 不一致。不要为了绕过平台问题删除 Gemfile.lock,那会丢失版本锁定。

验证

bundle check 应通过,bundle exec ruby -e "require 'nokogiri'" 能输出版本;通过 bundle exec 启动应用并运行测试,最后在部署镜像中重复一遍。若镜像内仍失败,先对比本地与服务端的 ruby -v 和 bundle platform,再考虑修改 Gemfile。