Rails assets 在 Heroku 上编译 application.js 文件

Rails assets compile application.js file on Heroku

我有几个供应商 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 个文件?

编辑: 我真的不知道我应该如何将供应商 js 文件包含到 rails 应用程序中。由于大多数 js 文件在 dom 加载后工作,我希望它们在 body 标记的末尾加载。

我删除了应用程序并再次推送到 heroku。我什么都没改变。现在 js 文件可以工作了,但奇怪的是它似乎没有加载。

我不需要 application.js 文件中的任何供应商文件。

编辑 2

非常感谢您的回答,并试图再了解一件事。

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

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

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

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

对所有 js 文件执行此操作,然后确保是否有任何 js 文件无法正常工作以通过调用此处所述的 page:change 事件来说明 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,因此您实质上是将此脚本加载到每个页面,例如您的application.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 %>

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

编辑 3:

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

资产的理想方式

在您的 application.js 文件中删除 require_tree 并且仅 //=require 您希望在应用程序范围内使用的文件,无论它是供应商 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'。然后我也在这一行下使用 yield to 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文件!