Rails资产在Heroku

时间:2016-05-20 00:04:45

标签: ruby-on-rails heroku assets precompile

我有几个供应商js文件,我把它们放在body标签底部的application.html.erb中;

  <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
        <meta charset="utf-8" />
        <title><%= full_title(yield(:title)) %></title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-touch-fullscreen" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="default">
        <meta content="" name="description" />
        <meta content="" name="author" />
        <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
        <meta name="viewport" content="initial-scale = 1.0,maximum-scale = 1.0" />


      <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>    





        <%= csrf_meta_tags %>

      </head>

      <% if (controller.controller_name == "main") %>
        <body class="fixed-header no-header">
   ...

      <%= javascript_include_tag 'pace/pace.min', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'modernizr.custom', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'jquery-ui/jquery-ui.min', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'boostrapv3/js/bootstrap.min', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'jquery/jquery-easy', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'jquery-unveil/jquery.unveil.min', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'jquery-bez/jquery.bez.min', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'jquery-ios-list/jquery.ioslist.min', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'jquery-actual/jquery.actual.min', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'jquery-scrollbar/jquery.scrollbar.min', 'data-turbolinks-track' => true %>    
      <%= javascript_include_tag 'bootstrap-select2/select2.min', 'data-turbolinks-track' => true %>    

...       
      </body>
    </html>

然后我宣布他们为Rails能够编译(config / initializers / assets.rb)

Rails.application.config.assets.precompile += %w( pace/pace.min.js modernizr.custom.js jquery-ui/jquery-ui.min.js boostrapv3/js/bootstrap.min.js jquery/jquery-easy.js jquery-unveil/jquery.unveil.min.js jquery-bez/jquery.bez.min.js jquery-ios-list/jquery.ioslist.min.js jquery-actual/jquery.actual.min.js jquery-scrollbar/jquery.scrollbar.min.js bootstrap-select2/select2.min.js switchery/js/switchery.min.js ...)

然后我注册了heroku并创建了一个应用程序,然后输入;

1. bundle exec rake assets:precompile RAILS_ENV=production
2. git add .
3. git commit -m "smth"
4. git push heroku master 

应用程序运行正常,但问题出在网络标签中。我有application.js文件,但我个别拥有所有供应商js文件。不应该将rails编译为1个文件吗?

enter image description here

修改 我真的无法弄明白我应该如何将供应商js文件包含到rails应用程序中。由于大多数js文件在dom加载后工作,我希望它们在body标签的末尾加载。

我删除了该应用并再次推送到heroku。我一无所获。现在js文件可以正常运行,但奇怪的是它似乎没有加载。

enter image description here

我在application.js文件中没有要求任何供应商文件。

编辑2

我非常感谢你的回答,并试图了解更多的事情。

假设我有一个名为main.rb的模型,所以我有主文件夹和home.html.erb文件。 Rails创建main.coffee(我将其更改为main.js.coffeee)。因此,如果我将所有相关的js代码放入此文件(main.js.coffee),每当调用home.html.erb时,此js代码将在页面加载后自动调用,它是如何工作的?如果是这样,我将组织这样的页面特定的js代码。谢谢

1 个答案:

答案 0 :(得分:1)

您正在从页面以及连接的预编译文件中直接加载它们,因此您看到的是正在加载的连接文件,然后从应用程序中的单独js include标记再次重新加载库.html.erb文件!您需要做的是在app / assets / javascripts / application.js文件中要求它们,以便加载一次。

例如,在你的app / assets / js / application.js文件中应该是:

//= require pace/pace.min
//= require bootstrap-select2/select2.min

对所有js文件执行此操作,然后通过调用page:change event来确保是否有任何js文件无法正常工作以解决turbolinks:

Rails 4: how to use $(document).ready() with turbo-links

编辑:在Head标记中加载js库是非常好的,因为它们通常都包含在$(document).ready调用中,所以不需要强制它们进入像你和php和其他平台一样的页面。处理此问题的Rails方法是按照application.js中的说明要求它们,然后运行bundle exec rake assets:precompile RAILS_ENV=production。然后做另一个git add and commit,然后推送到heroku!

现在,要做你想做的事情并将js保留在特定页面的底部,你必须意识到你的application.html.erb会被调用每个页面请求,所以你基本上将这个脚本加载到每个页面,就像你的应用程序一样。 js资产文件专为。如果您只想在特定页面上调用js,则可以在底部执行以下操作:

在关闭正文标记之前最底部的application.html.erb文件中,您可以输入:

<%= yield :javascript %>

然后,在您想要包含某些脚本或库的所有视图页面上,您可以放在该视图的最底部:

 <%= content_for :javascript do %>
      <script src="jquery-1.12.2.min.js"></script>
      <script type='text/javascript'>
         all your custom js here....
      </script>
<% end %>

这将根据需要在您的application.html.erb底部生成js块:javascript。

编辑3:

你会注意到标准的Rails application.js文件有一个“require_tree”指令。这基本上加载了所有js,因此你在main.js文件夹中的脚本将触发在应用程序的任何其他部分引用它们的任何内容。为了避免这种情况,你可以做我做的事情并删除这些指令并单独调用。这有点先进,但我会引导您完成它,因为很难将它们整合在分散在互联网上的文档中。这是如何加载页面特定资产以及在Rails中处理资产的理想方法。

在您的application.js文件中删除require_tree,并且只删除您想要应用程序范围的文件//无论是供应商js文件夹中的库还是个人脚本。完成后,您需要更改application.html.erb文件,如下所示:

在head标记中,您可以保留“javascript_include_tag应用程序”调用,因为这样可以执行您想要的操作并提取所有应用程序。宽js文件。然后在该文件的底部放置关闭体标记:

<%= javascript_include_tag params[:controller] if ::Rails.application.assets.find_asset("#{params[:controller]}.js") %>

然后,这将仅调用具有匹配控制器名称的js文件,例如示例中的“main.js”。我也在这一行下使用了一个可能在其他视图上的javascript代码:

<%= yield :javascript %>

然后在具有页面特定js的页面上,我将它放在各自视图的最底部,并且根本不将它添加到我的assets / js文件夹中:

<%= content_for :javascript do %>
  <script type='text/javascript'>
    code here
  </script>
<% end %>

现在你差不多完成了。因为您将通过控制器加载文件,所以需要将它们添加到Rails预编译列表中!因此,例如,您的'main.js'文件,即使在生成控制器时自动处理,也必须与所有其他控制器js文件一起添加到此预编译数组中。为此,打开config / initializers / assets.rb文件并取消注释以下行并添加以控制器命名的所有js文件:

Rails.application.config.assets.precompile += %w ( main.js )

现在重新启动服务器,你就完成了!我也为css文件做这个!

注意:如果您有仅在一个页面中使用的js库,则可以在这些与控制器相关的js文件中执行//= require语句。 //= require不仅限于application.js文件!