Rails引擎:共享资产依赖项

tri*_*anm 6 ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1 sprockets asset-pipeline

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

// my_engine.js

//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jstree_pre1.0_fix_1/jquery.jstree.js
//= require_tree .
Run Code Online (Sandbox Code Playgroud)

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

<%= javascript_include_tag 'application' %>
<%= javascript_include_tag 'my_engine/my_engine' if user_logged_in? %>
Run Code Online (Sandbox Code Playgroud)

但是,如果主应用程序的清单已经包含其中一个依赖项(很可能是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>
Run Code Online (Sandbox Code Playgroud)

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

tri*_*anm 4

最后,我选择不使供应商库成为硬依赖项,并且我已在文档中写入必须手动要求它们。这为下游开发人员带来了更多的工作量,但我认为它提供了最大的灵活性。

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

//= require_tree .
Run Code Online (Sandbox Code Playgroud)

和一个示例主应用程序:

application.js:

//= require jquery
//= require jquery_ujs
//= require_tree .
Run Code Online (Sandbox Code Playgroud)

my_engine_requirements.js:

//= require jquery-ui
//= require jstree_pre1.0_fix_1/jquery.jstree.js
//= require my_engine/my_engine
Run Code Online (Sandbox Code Playgroud)

application.html.erb:

<%= javascript_include_tag 'application' %>
<%= javascript_include_tag 'my_engine_requirements' if user_logged_in? %>
Run Code Online (Sandbox Code Playgroud)

从技术上讲,这个解决方案并没有回答我最初的问题,但这是我在对情况进行更多合理化之后所做的。