我使用带有自己的JavaScript和样式表资源的gem。这个gem使用标准的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/…
我不愿意将gem中的所有资产文件复制到我的app / assets中,以覆盖单个文件。并且分支宝石来定制单个文件也没有很大的吸引力。
还有其他办法吗?
注意:我知道我可以创建一个自定义JavaScript文件menu_patched.js
来覆盖原始文件中定义的对象和方法,并放置它以便在之前应用其定义调用原始对象和方法(猴子修补JavaScript样式)。但我在这里寻找更清洁的解决方案。
答案 0 :(得分:9)
在on GitHub发布的演示代码中,您的application.js有:
//= require any_gem
它没有引入目录,它引入了any_gem.js
,这是Gem的清单文件,它带来了所有的Gem JS文件。如果您不想所有文件,那么您需要更改它以通过明确列出它们来引入您想要的文件:
//= require ../../../vendor/assets/javascripts/any_gem/do_not_override.js
然后,您可以使用以下命令添加回所有自己的JS文件,包括覆盖:
//= require_tree .
顺便说一下,创建演示应用程序非常棒!你是孩子们的榜样。
答案 1 :(得分:2)
在application.rb
或production.rb
中,您可以添加或附加更多资源路径。
config.assets.prepend_path 'vendor/assets/jquery'
config.assets.append_path 'vendor/assets/something'
参考文献: