Mac OS BigSur用rbenv升级Ruby2.7.2后运行Rails RSpec报LoadError无法加载etc
问题根因
cannot load such file -- etc 不是Rails本身的代码问题:etc是Ruby内置的C扩展标准库,ActiveSupport在初始化阶段就会调用这个库读取系统用户信息,所以栈追踪才会把报错位置定位到application.rb里require "rails"这一行。
这个报错的本质是当前项目的加载路径配置指向了和当前rbenv管理的Ruby 2.7.2不匹配的旧版本目录,和项目业务逻辑无关——这也刚好解释了为什么相同版本搭建的全新Rails项目可以正常运行rspec、rake命令,因为全新项目不会残留旧Ruby版本的路径映射。
注意:不要为了解决这个问题去安装名为etc的第三方gem,这个库是Ruby原生内置的,装第三方同名包反而会造成新的加载冲突。
分步解决操作
- 清除项目内所有旧版本残留的Bundle路径配置
进入项目根目录执行:rm -rf .bundle/删除项目本地的gem路径映射,这个文件是之前用旧版本Ruby运行项目时生成的,会强制把标准库、gem的加载路径指向旧版本的安装目录rbenv local 2.7.2确认项目的Ruby版本锚定正确,避免Shell上下文错用了系统自带的旧Ruby版本
- 重建Ruby原生扩展的加载索引,清除旧缓存
- 执行
gem pristine --all 2.7.2强制重建当前Ruby 2.7.2版本下所有原生扩展的链接,修复内置扩展的加载路径索引 - 如果项目用了本地vendor缓存,执行
rm -rf vendor/cache/删除旧版本下编译好的gem文件 - 重新执行
bundle install全量安装项目依赖,不要复用旧版本下载的gem缓存
- 执行
- 验证基础加载能力
先在项目根目录执行基础测试命令:ruby -e 'require "etc"; puts Etc.getlogin'- 如果命令能正常输出当前系统用户名,说明Ruby的内置扩展加载没有问题,回到项目跑rspec就可以正常启动
- 如果这条命令都报同样的错,说明是之前用ruby-build编译Ruby 2.7.2时的环境不匹配,需要重新编译安装对应版本:在Big Sur环境下携带正确的依赖参数重新安装即可:
RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1) --enable-shared" rbenv install 2.7.2
- 最终兜底排查
如果以上步骤都走完还是报错,检查项目的初始化文件、config/application.rb里有没有硬编码添加旧版本Ruby路径到$LOAD_PATH的逻辑,这类历史配置是全新项目里不会存在的,也是旧项目特有的问题来源。
内容的提问来源于stack exchange,提问作者Jesper Grann Laursen
相关产品推荐
相关产品推荐

