You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Rails 5预编译资产时的rb_sysopen错误?

Rails 5.2.2 生产环境资产预编译 Errno::ENOENT 错误排查

环境与操作

运行环境

  • Rails 5.2.2
  • Ruby 2.6.6
  • Bundler 2.4.4
  • Windows 10

操作步骤

  1. 清理资产目录:bundle exec rake assets:clobber --trace
  2. 生产环境预编译:bundle exec rake assets:precompile RAILS_ENV=production --trace

问题现象

多数静态资源(js/css/jpg/png)编译正常,但处理glyphicons-halflings-regular字体文件时触发Errno::ENOENT错误,此前也曾在png文件编译时失败,怀疑与Bundler版本更新有关。

错误日志

Errno::ENOENT: No such file or directory @ rb_sysopen - C:/Users/..../...../public/assets/flatty/bootstrap/glyphicons-halflings-regular-5ff7c239555476e939e86d457bb78424b945b733b2c23791d9807c2357259d43.eot.103323240.10692.178366
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/sprockets-3.7.2/lib/sprockets/path_utils.rb:278:in `initialize'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/sprockets-3.7.2/lib/sprockets/path_utils.rb:278:in `open'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/sprockets-3.7.2/lib/sprockets/path_utils.rb:278:in `atomic_write'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/sprockets-3.7.2/lib/sprockets/asset.rb:165:in `write_to'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/sprockets-3.7.2/lib/sprockets/manifest.rb:210:in `block (2 levels) in compile'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb:24:in `block in execute'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `block in synchronize'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `synchronize'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:41:in `synchronize'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb:19:in `execute'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/ivar.rb:169:in `safe_execute'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/future.rb:55:in `block in execute'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:363:in `run_task'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:352:in `block (3 levels) in create_worker'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:335:in `loop'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:335:in `block (2 levels) in create_worker'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `catch'
C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/concurrent-ruby-1.1.8/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `block in create_worker'
Tasks: TOP => assets:precompile

疑问

已知项目依赖gem版本较旧,但此前预编译正常,更新Bundler后出错,是否与Bundler版本有关?


问题分析与解决

版本兼容性结论

是,问题大概率源于Bundler 2.4.4与旧版Rails/Sprockets的兼容性冲突。

Bundler 2.x系列在依赖解析逻辑、gem安装路径处理上和旧版Bundler有显著差异,而你的项目使用的Sprockets 3.7.2是适配旧版Bundler的版本,两者配合时会出现路径解析异常——错误日志中的.eot.103323240.10692.178366是Sprockets原子写入时创建的临时文件后缀,无法找到路径说明Bundler传递给Sprockets的文件路径出现了错误。

解决方案

1. 回退Bundler到之前的可用版本

找到之前能正常预编译的Bundler版本,执行以下命令:

gem install bundler -v <旧版本号>
# 用旧版本执行预编译
bundle _<旧版本号>_ exec rake assets:precompile RAILS_ENV=production --trace

2. 修复Sprockets路径与权限问题

  • 手动创建public/assets/flatty/bootstrap目录,确保当前Windows用户拥有该目录的读写权限
  • 在config/environments/production.rb中添加或确认以下配置:
    config.assets.compile = true
    config.assets.digest = true
    config.assets.paths << Rails.root.join('app', 'assets', 'fonts')
    
    之后重新执行清理和预编译命令。

3. 手动复制字体文件

如果上述方法无效,可直接找到项目中的glyphicons-halflings-regular.eot/woff/woff2/ttf/svg字体文件(通常在vendor/assets/fonts或app/assets/fonts目录),手动复制到public/assets/flatty/bootstrap目录,再执行预编译。


内容的提问来源于stack exchange,提问作者DeeBee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:20:27