Как переопределить отдельные файлы из активов драгоценных камней для активов: предварительная компиляция?

Ситуация

Я использую гем, который имеет свой собственный JavaScript и ресурсы таблицы стилей. Этот драгоценный камень использует стандартный манифест application.js и application.css, чтобы потребовать все свои активы:

[gem]/app/assets/javascripts/gem_name/application.js
  require_tree .

[gem]/app/assets/javascripts/gem_name/backoffice/menu.js
  … some JavaScript code …

[gem]/app/assets/javascripts/gem_name/backoffice/forms.js
  … some JavaScript code …

В режиме разработки я могу переопределить отдельные файлы активов, поместив их в папку [my_app]/app/assets, например:

[my_app]/app/assets/javascripts/gem_name/backoffice/menu.js

Пути загрузки, настроенные в Rails, гарантируют, что файлы в [my_app]/app/assets переопределяют файлы в [gem]/app/assets.

Но когда я прекомпилирую ресурсы с помощью rake assets:precompile, переопределяющий файл menu.js не заменяет исходный файл из драгоценного камня. Скомпилированный application.js содержит код исходного menu.js.

Демо

Посмотрите, как работает это тестовое приложение: https://github.com/widescape/AssetCompileTest.

Соображения

На данный момент я обнаружил, что require_tree ищет файлы только в каталоге текущего файла и не просматривает несколько путей загрузки (например, приложение/активы или поставщик/активы). ). Таким образом, если текущий файл [gem]/app/assets/javascripts/gem_name/application.js, Sprockets#require_tree будет искать дополнительные файлы только в [gem]/app/assets/javascripts/gem_name/ и не использовать другие пути загрузки, такие как [my_app]/app/assets/….

Я не хочу копировать все файлы активов из драгоценного камня в свое приложение/активы только для переопределения одного файла. И разветвление драгоценного камня для настройки одного файла тоже не очень привлекательно.

Есть ли другой способ?

Примечание. Я знаю, что могу создать собственный файл JavaScript menu_patched.js, который переопределяет объекты и методы, определенные в исходном файле, и поместить его таким образом, чтобы его определения применялись до вызова исходных объектов и методов. (обезьяна исправляет стиль JavaScript). Но я ищу более чистое решение здесь.


person Robert    schedule 08.05.2013    source источник


Ответы (2)


В демонстрационном коде, который вы разместили на на GitHub, ваш application.js содержит:

//= require any_gem

Это не вводит каталог, а вводит any_gem.js, который является файлом манифеста Gem, который вводит все JS-файлы Gem. Если вам не нужны все файлы, вам нужно изменить это, чтобы отображались только те файлы, которые вы хотите, явно перечислив их:

//= require ../../../vendor/assets/javascripts/any_gem/do_not_override.js

Затем вы можете добавить обратно все свои собственные файлы JS, включая свои переопределения, с помощью:

//= require_tree .

Кстати, отличная работа по созданию демо-приложения! Вы образец для подражания для детей.

person Old Pro    schedule 01.06.2013
comment
Вы правы, что require_tree ./any_gem перенесет содержимое каталога [my_app]/app/assets/any_gem/*. Однако тогда require_tree не будет включать все остальные файлы JavaScript, содержащиеся в геме. Он будет включать только те файлы, которые относятся к включаемому файлу. К сожалению, это как работает require_tree. Sprocket не ищет пути загрузки для каждого файла в списке файлов require_tree. - person Robert; 02.06.2013
comment
Боюсь, ответ, который я ищу, вероятно, не (измененная) строка кода, а скорее другой шаблон кодирования... - person Robert; 02.06.2013
comment
Да, драгоценные камни должны предоставлять свои собственные способы оставаться в стороне и позволять вам переопределять поведение; Sprockets не дает вам хорошего механизма для переопределения. Тем не менее, для вас было бы удобнее и лучше требовать JS-файлы Gem один за другим (отказывая от удобства, предоставляемого Gem any_gem.js), чтобы исключить файл, который вам не нужен. Например. //= require ../../../vendor/assets/javascripts/any_gem/other - person Old Pro; 02.06.2013
comment
ОК, следуя вашему подходу, я создал ветку solution-with-individual- включения, которые также включают проверку того, что решение работает в среде разработки и производственной среде. Подробности см. в изменениях. - person Robert; 03.06.2013
comment
Хотели бы вы изменить свой ответ, чтобы отразить это решение? Тогда я буду рад принять ваш ответ и вознаградить вас наградой. :) - person Robert; 03.06.2013
comment
Еще раз, хорошая работа с кодом GitHub. Я обновил ответ. - person Old Pro; 03.06.2013

В application.rb или production.rb вы можете добавить путь к дополнительным ресурсам.

config.assets.prepend_path 'vendor/assets/jquery'
config.assets.append_path 'vendor/assets/something'

Использованная литература:

person catcyborg    schedule 28.05.2013
comment
Проблема не в том, что активы драгоценных камней не могут быть загружены. Проблема в том, что приложение/активы не переопределяют драгоценный камень/активы в скомпилированных статических активах. См. пример приложения github.com/widescape/AssetCompileTest, чтобы увидеть поведение в действии. - person Robert; 29.05.2013