【发布时间】:2013-05-02 08:58:11
【问题描述】:
情况
我使用带有自己的 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在当前文件的目录中只查找文件,不查找多个加载路径(例如app/资产或供应商/资产)。因此,如果当前文件是 [gem]/app/assets/javascripts/gem_name/application.js,Sprockets#require_tree 只会在 [gem]/app/assets/javascripts/gem_name/ 中查找更多文件,并且不会使用其他加载路径,例如 [my_app]/app/assets/…。
我不愿意将所有资产文件从 gem 复制到我的应用程序/资产中,只是为了覆盖一个文件。并且 fork gem 来自定义单个文件也没有太大的吸引力。
还有其他方法吗?
注意:我知道我可以创建一个自定义 JavaScript 文件 menu_patched.js,它会覆盖原始文件中定义的对象和方法并将其放置,以便在原始文件之前应用其定义对象和方法被调用(猴子修补 JavaScript 风格)。但我在这里寻找更清洁的解决方案。
【问题讨论】:
标签: ruby-on-rails gem assets sprockets