Rails引擎:共享资产依赖项

时间:2012-03-05 22:34:13

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1 asset-pipeline sprockets

我正在编写一个可安装的Rails 3.1引擎,它可以为主应用程序添加功能(即它不是孤立的)。引擎的JS取决于jQueryjQueryUIDataTablesJSTree(以及其他库),因此引擎的清单看起来像:

// my_engine.js

//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jstree_pre1.0_fix_1/jquery.jstree.js
//= require_tree .

我可以有条件地使用以下方法将此文件加载到主应用的布局中:

<%= javascript_include_tag 'application' %>
<%= javascript_include_tag 'my_engine/my_engine' if user_logged_in? %>

但是,如果主应用程序的清单已经包含其中一个依赖项(很可能是jQuery和jQuery_UJS),那么这些依赖项将被加载两次。我会看到类似的东西:

<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
...
<script src="/assets/application.js?body=1" type="text/javascript"></script>

<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery-ui.js?body=1" type="text/javascript"></script>
<script src="/assets/jstree_pre1.0_fix_1/jquery.jstree.js?body=1" type="text/javascript"></script>
...
<script src="/assets/cms/application.js?body=1" type="text/javascript"></script>

Sprocketrequire指令只需要一个资产在同一个包中,但在这里我使用两个包。为了使其他开发人员能够实现我的引擎,我希望他们能够包含一行来检测是否已经包含共享依赖项。使用Sprockets有没有很好的方法呢?

1 个答案:

答案 0 :(得分:4)

最后,我选择不使供应商库存在硬依赖关系,并且我已经在文档中写入了必须手动需要的文档。这为下游开发人员创造了更多的工作,但我认为它提供了最大的灵活性。

因此,引擎的清单文件my_engine.js现在只是:

//= require_tree .

和一个示例主应用程序:

application.js

//= require jquery
//= require jquery_ujs
//= require_tree .

my_engine_requirements.js

//= require jquery-ui
//= require jstree_pre1.0_fix_1/jquery.jstree.js
//= require my_engine/my_engine

application.html.erb

<%= javascript_include_tag 'application' %>
<%= javascript_include_tag 'my_engine_requirements' if user_logged_in? %>

这个解决方案在技术上并没有回答我原来的问题,但这是我在对情况进行合理化之后的所作所为。