我在谷歌上搜索这个问题时遇到了很多麻烦,因为bundler
不断出现。但是,我的问题在于我使用mkmf
和 ruby c API 捆绑的 c 库。我已经将我的 c 代码编译成一个文件(例如my_library.bundle
(,我已经在助手中需要它,require_relative "my_library"
没有问题。
当我部署到 heroku 并收到错误时出现问题:
2019-08-14T19:09:15.452530+00:00 app[web.1]: /app/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require': cannot load such file -- /app/app/helpers/my_library (LoadError)
我可以在我的 heroku 应用程序上运行ls
和cat
,以验证文件是否存在以及内容是否匹配。当我使用RAILS_ENV=production
在本地运行应用程序时,我也没有遇到任何问题。此外,运行heroku local web
在我的机器上运行良好。
这与我的配置有关吗autoload_paths
?我的主要问题是我似乎无法在本地调试它。
编辑:我注意到这个问题也出现在码头工人化的实例中。似乎容器化的某些东西似乎是问题所在。我什至尝试按照本指南创建一个 gem 来包含捆绑包,该指南在本地工作,但再次遇到查找文件时遇到的相同问题,但这次路径是相对于 gem,而不是我的项目。我仍然对导致此问题的原因感到困惑。
根据您发布的错误,Docker似乎没有指向正确的路径cannot load such file -- /app/app/helpers/my_library
。如果正确,则应在 Dockerfile 中显式指定工作目录。
WORKDIR /path/to/project
之后,只需重建映像即可。
现在,如果这不起作用,您可以在项目中检查autoload_paths
或自定义引导快照以避免自动加载路径出错。
您可以做的是将整个my_library
作为本地 gem并将您的 Gemfile 指向它。 大致上,大纲如下:
- 将
my_library
的整个代码放在应用中的目录中,例如fixtures
(与 Gemfile 处于同一级别(。app/ ... fixtures/ my_library/ ext/ ... lib/ ... my_library.gemspec Rakefile Gemfile
- 将您的宝石文件指向
my_library
宝石:gem 'my_library', path: 'fixtures/my_library'
- 然后只需通过运行来更新您的
Gemfile.lock
bundle update
正如@jay-dorsey所提到的,该捆绑包确实需要在部署应用程序的服务器上编译才能使用。我遵循的创建宝石的两个指南都有一些错误信息。
- gem 应仅包含源文件,不包含已编译的源文件
- rakefile 应该引用
ext.lib_dir = "lib/my_library"
而不是ext
目录 - gemspec 应该在其他依赖项之前添加
rake-compiler
开发依赖项 - 版本文件不应尝试加载扩展,因为它在 gemspec 中使用,这是在 gem 有机会被 rake/bundler 编译之前调用 的
- 无法在 Linux 计算机上读取
.bundle
文件