2

It seems that Sprockets has a cached environment built in that loads a list of all possible assets at the start of a request, and then requiring any assets outside that list raises an error.

I've written a custom directive to create a new CSS file - I need to wrap the contents of an existing file in a new selector - something like so:

class DirectiveProcessor < Sprockets::DirectiveProcessor
  def process_wrap_directive(path)
    src = Rails.root.join("app", "assets", "stylesheets", path)
    dst = Rails.root.join("app", "assets", "stylesheets", "wrapped", path)
    File.write(dst, ".new-selector {" + File.read(src) + "}")
    process_require_directive("wrapped/" + path)
  end
end 

However, requiring the new wrapped asset fails because it isn't in the list of files Sprockets knows about. When refreshing the page, the first asset will succeed because it now existed at the start of the request and is thus in the cached list, but the second one will fail, and so on.

Is there any way to get around this? Disabling the cache didn't fix the issue.

I'm guessing it relates to this code https://github.com/rails/sprockets-rails/pull/197/files - but short of reopening a bunch of classes, is there a way to avoid the cached environment?

sevenseacat
  • 24,699
  • 6
  • 63
  • 88

1 Answers1

0

The problem may be a need to flush the file so the new selector is actually written. With reference to https://ruby-doc.org/core-2.6.3/IO.html (the IO object being File's parent), it appears that either File.close or File.flush may solve the problem.

David Yockey
  • 595
  • 3
  • 11
  • Unfortunately this isn't the case - the file is written successfully, but Sprockets maintains a list of files and the new file isn't on the list. – sevenseacat Jun 24 '19 at 02:12