Cайт веб-разработчика, программиста Ruby on Rails ESV Corp. Екатеринбург, Москва, Санкт-Петербург, Новосибирск, Первоуральск

Ошибка преобразования пути к ресурсам css в gem sprockets-rails

Проблема состоит в том, что в gem sprockets-rails 3.5.2 с ошибкой подставляются (изменяются) пути до различных ресурсов (например, изображений) в файлах css сторонних библиотек. Допустим, где-то в коде css указан путь к изображению url('image.png'), после обработки будет заменен на url('/image.png'). Не знаю, чем думали авторы, когда писали это, но суть в том, что они заменяют относительный путь до изображения абсолютным, но правильно было бы либо вообще не менять, либо заменить на url('./image.png') - разница всего лишь в одной точке в начале пути, но как меняет смысл!

Эту ошибку я обнаружил уже давно, даже сообщал это авторам gem sprockets-rails, но ко мне не захотели прислушиваться. Впервые заметил ошибку, когда в редакторе CKEditor исчезли все иконки как раз после очередного обновления gem-ов. В итоге я просто сам исправил ошибку в gem-е и при каждой новой установке (новая версия Ruby, например) я просто немного поправляю один файл в gem - и всё работает прекрасно у меня. В версии 3.5.2 до сих пор эта "особенность" присутствует.

Исправление ошибки в gem

В gem sprockets-rails в файле lib/sprockets/rails/asset_url_processor.rb необходимо внести небольшие изменения:

def self.call(input)
  context = input[:environment].context_class.new(input)
  data    = input[:data].gsub(REGEX) do |_match|
    path = Regexp.last_match[:path]
    # original: "url(#{context.asset_path(path)})"

    # === my patch instead of the original above
    orig_path = path
    path = context.asset_path(path)
    path = (path == "/#{orig_path}") ? ".#{path}" : path
    "url(#{path})"

  end

  context.metadata.merge(data: data)
end

В последствии в gem добавили дополнительную опцию конфигурации, но свой патч я всё же не отменил, потому как неизвестно - какие ещё пути могут обрабатываться, но опция полезная:

config.assets.resolve_assets_in_css_urls

When this option is enabled, sprockets-rails will register a CSS postprocessor to resolve assets referenced in url() function calls and replace them with the digested paths. Defaults to true.