如何修复Rails 5预编译资产时的rb_sysopen错误?
Rails 5.2.2 生产环境资产预编译 Errno::ENOENT 错误排查
环境与操作
运行环境
- Rails 5.2.2
- Ruby 2.6.6
- Bundler 2.4.4
- Windows 10
操作步骤
- 清理资产目录:
bundle exec rake assets:clobber --trace - 生产环境预编译:
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
相关产品推荐
相关产品推荐

