Techioz Blog

Rails 5.1.7: Sprockets::Rails::Helper::AssetNotFound

概要

Rails 5.1.7 アプリケーションがあり、開発環境ではすべて正常に動作しています。ただし、ステージング環境や、rails s -e ステージングを使用してサーバーを実行している場合は、「Sprockets::Rails::Helper::AssetNotFound」というエラーが表示されます。

たとえば、アセット「fontawesome-free-5.1.1-web/css/all.min.css」はアセット パイプラインに存在しません。

fontawesome-free-5.1.1-web フォルダーは public/styleheets の下にあります。

フォルダーをベンダー/スタイルシートまたはアセット/スタイルシートに移動しようとしましたが、同じエラーが表示されます。

以下は私の環境/staging.rbです

AppName::Application.configure do
  config.cache_classes = true

  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = true
  config.action_view.cache_template_loading = true
  config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

  config.log_level = :debug
  memcached_config = YAML.load_file(Rails.root.join('config/memcached.yml'))
  memcached_hosts = memcached_config['defaults']['servers']
  config.cache_store = :mem_cache_store, *memcached_hosts


  config.action_mailer.delivery_method = :smtp
  config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true
  config.i18n.fallbacks = true

  config.active_support.deprecation = :notify

  config.eager_load = true
  config.assets.js_compressor = Uglifier.new(harmony: true)
  config.assets.compile = false
  config.assets.raise_runtime_errors = true
  config.assets.debug = true
end

ここで何が問題になっているのかについてアドバイスをいただければ大変助かります。ありがとうございます。

解決策

あなたはこれをやっていると仮定します:

<%= stylesheet_link_tag 'fontawesome/all.min.css' %>  
vendor/
└── assets/                  # <= this one is important
    └── stylesheets/
        └── fontawesome/
            └── all.min.css

ベンダー/アセットおよびアプリ/アセットのディレクトリは、アセット パスに自動的に追加されます。 Sprocket がアセットを検索するために使用するパスは次のとおりです。

>> puts Rails.application.config.assets.paths
...
/myapp/app/assets/stylesheets
/myapp/vendor/assets/stylesheets         # <=
/usr/local/bundle/gems/coffee-rails-4.2.2/lib/assets/javascripts
/usr/local/bundle/gems/actioncable-5.2.8.1/lib/assets/compiled
...

config.assets.compile = false になっています。これは、sprockets がアセット パス内を調べてその場でコンパイルを完了することを意味します。現在、public/assets にプリコンパイルされたアセットが期待されています。

# assuming sprockets is still serving files (but not compiling them anymore)
>> Rails.application.config.public_file_server.enabled
=> true
>> Rails.application.config.assets.compile
=> false

>> helper.asset_path("fontawesome/all.min.css")
Traceback (most recent call last):
        1: from (irb):5
Sprockets::Rails::Helper::AssetNotFound (The asset "fontawesome/all.min.css" is not present in the asset pipeline.)

bin/rails のアセットをプリコンパイルする必要があります。

# config/initializers/assets.rb

# but make it precompilable first
Rails.application.config.assets.precompile += ["fontawesome/all.min.css"]
$ bin/rails assets:precompile

I, [2023-09-10T10:04:24.038220 #1]  INFO -- : Writing /myapp/public/assets/fontawesome/all.min-1f62e82d4d0217052a8d48596d631f5c58ee5149386c719419046118e4fa43f3.css
...

今は動作するはずです:

>> helper.asset_path("fontawesome/all.min.css")
=> "/assets/fontawesome/all.min-1f62e82d4d0217052a8d48596d631f5c58ee5149386c719419046118e4fa43f3.css"

# check if it is being served
>> require "open-uri"
>> URI.open(helper.asset_path("fontawesome/all.min.css", host: "http://localhost:3000")).read
=> "i am font\n"

https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://guides.rubyonrails.org/v5.0/configuring.html#configuring-assets

アップデート

ファイルを一括処理するには、2 つのオプションがあります。プリコンパイルのためにアセットを動的に照合するプロシージャを追加します。

# config/initializers/assets.rb

VENDOR_ASSETS = lambda do |logical_path, filename|
  filename.start_with?(::Rails.root.join("vendor/assets/").to_s) &&
    [".css", ".js"].include?(File.extname(logical_path))
end

Rails.application.config.assets.precompile += [VENDOR_ASSETS]

https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/rails/sprockets-rails/blob/v3.4.2/lib/sprockets/railtie.rb#L88

より良いオプションは、manifest.js を使用することです。これは、以降の Rails バージョンのデフォルトです。

# config/initializers/assets.rb

# don't need this in sprockets v4
Rails.application.config.assets.precompile += ["manifest.js"]
// app/assets/config/manifest.js

//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
//
// link everything to be precompiled
//= link_tree ../../../vendor/assets/stylesheets .css
//= link_tree ../../../vendor/assets/javascripts .js
//
// or one file at a time 
//= link fontawesome/all.min.css

https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/rails/sprockets#directives

また、アセットをプリコンパイルするときは、URL を通じて直接アセットをロードする必要があることを意味します。 //= require ディレクティブのみを使用する場合、必要なファイルはプリコンパイルされるファイルにマージされるため、プリコンパイルする必要はありません。取得できるのは、1 つの大きな application.css ファイルだけです。

/* app/assets/stylesheets/application.css */

/*
 *= require_tree .
 *= require_self
 *= require fontawesome/all.min
 */

テストするためにローカルでプリコンパイルしている場合は、完了後に bin/railsassets:clobber を実行することを忘れないでください。開発中にプリコンパイルされたアセットは必要ありません。