如何从资产的宝石资产中覆盖单个文件:预编译? [英] How to override single files from gem assets for assets:precompile?

查看:163
本文介绍了如何从资产的宝石资产中覆盖单个文件:预编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况



我使用带有自己的JavaScript和样式表资源的gem。这个gem使用标准的application.js和application.css清单来要求它的所有资源: /javascripts/gem_name/application.js
require_tree。

[gem] /app/assets/javascripts/gem_name/backoffice/menu.js
...一些JavaScript代码...

[gem] / app / assets / javascripts / gem_name / backoffice / forms.js
...一些JavaScript代码...

在开发模式然后,我可以通过将它们放置在 [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 中的代码。



Demo



查看使用此测试应用程序的行为: 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复制到我的应用程序/资产仅用于覆盖单个文件。



是否有其他方法?



注意:我知道我可以创建一个定制JavaScript文件 menu_patched.js 来覆盖定义在原始文件并放置它,以便在调用原始对象和方法(猴子修补JavaScript样式)之前应用其定义。但是我在这里寻找一个更干净的解决方案。

在你发布在 on GitHub ,你的application.js有:

  // = require any_gem 

这不会引入目录,它会带入 any_gem.js ,这是Gem的清单文件,可以引入Gem的所有JS文件。如果你不想要这些文件的所有文件,那么你需要改变它,以明确地列出你想要的文件:

  // =需要../../../vendor/assets/javascripts/any_gem/do_not_override.js 

然后你可以在你自己的所有JS文件中重新加载,包括你的覆盖:

  // = require_tree。 

顺便说一句,创建演示应用的工作非常棒!你是孩子们的榜样。


Situation

I use a gem that brings its own JavaScript and stylesheet assets. This gem uses a standard application.js and application.css manifest to require all its assets:

[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 …

In development mode I can then override single asset files by placing them in [my_app]/app/assets folder, e.g.:

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

The load paths configured in Rails then ensure that files in [my_app]/app/assets override files in [gem]/app/assets.

But when I precompile the assets using rake assets:precompile, the overriding file menu.js doesn't replace the original file from the gem. The compiled application.js contains the code from the original menu.js.

Demo

See the behavior in action with this test app: https://github.com/widescape/AssetCompileTest

Considerations

So far, I found out that require_tree looks up files only in the directory of the current file and does not look across multiple load paths (e.g. app/assets or vendor/assets). So if the current file is [gem]/app/assets/javascripts/gem_name/application.js, Sprockets#require_tree will only look in [gem]/app/assets/javascripts/gem_name/ for more files and will not use the other load paths like [my_app]/app/assets/….

I am reluctant to copy all asset files from the gem into my app/assets only to override one single file. And forking the gem to customize a single file doesn't have a great appeal, too.

Is there any other way?

Note: I am aware that I could create a custom JavaScript file menu_patched.js that overrides the objects and methods defined in the original file and place it so that its definitions will be applied before the original objects and methods are called (monkey patching JavaScript style). But I am looking for a cleaner solution here.

解决方案

In the demo code you posted at on GitHub, your application.js has:

//= require any_gem

That does not bring in a directory, it brings in any_gem.js, which is the Gem's manifest file that brings in all of the Gem's JS files. If you do not want all of the files, then you need to change that to bring in only the files you want by listing them explicitly:

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

Then you can add back in all of your own JS files, including your overrides, with:

//= require_tree .

BTW, great job on creating the demo app! You're a role model for the kids.

这篇关于如何从资产的宝石资产中覆盖单个文件:预编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆