Как да замените единични файлове от активи на скъпоценни камъни за активи: предкомпилиране?

Ситуация

Използвам скъпоценен камък, който носи собствен 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 не замества оригиналния файл от gem. Компилираният 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 файлове, които се съдържат в gem. Той ще включва само файловете, които са относителни към включващия файл. Това е как работи require_tree, за съжаление. Sprocket не търси пътищата за зареждане за всеки файл в списъка с файлове require_tree. - person Robert; 02.06.2013
comment
Страхувам се, че отговорът, който търся, вероятно не е (променен) ред код, а по-скоро различен модел на кодиране... - person Robert; 02.06.2013
comment
Да, скъпоценните камъни трябва да предоставят свои собствени начини да стоят настрани и да ви позволяват да отмените поведението; Sprockets не ви дава добър механизъм за отмяна. Все пак би било по-поддържано и по-добре за вас да изисквате JS файловете на Gem един по един (отказвайки се от удобството на предоставения any_gem.js от Gem), за да изключите файла, който не искате. напр. //= 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