新手问题 不同 controller 加载不同 assets 最佳方法

lilijreey · August 17, 2016 · Last by FrankFang replied at August 20, 2016 · 3327 hits

Rails 的预编译清单文件只有一个就是 application.js.要是把所有的资源都在这里面加载会导致很多页面加载无用 js,css,文件的情况。但是清单文件只认 application.js 每个控制权的 coffee 文件并不支持清单文件的加载语法. 需要手动修改 Rails.application.config.assets.precompile .有没有什么好方法,可以让不同的 controller 只加载自己需要的 js,css 文件。

可以通过给页面加 controller 标识,然后让 js 去查找这个标识决定加载不加载。

layouts/application.html.erb

<body data-controller-name="<%= controller_name  %>">
...
</body>

xxx.js

$(function(){
  if($('body[data-controller-name="xxx"]').length > 0) {
    return ;
  }

  // your logic here
})

#1 楼 @bastengao 这个可以加载的资源,不会被 rails 自动编译。比较麻烦。

#1 楼 @bastengao #3 楼 @jojoma 看了一下 Rails5 的文档,有给出 Controller Specific Assert 的做法 对于把文件加载到 pipeline 使用下面这个会好一些。不需要每个都手动添加。

Rails.application.config.assets.precompile += 
  Dir.entries('app/assets/javascripts/').select{ |name| name =~ /.*\.coffee$/}  +
  Dir.entries('app/assets/stylesheets/').select{ |name| name =~ /.*\.scss$/}

#2 楼 @lilijreey 可能我没有说清楚,所有的 js 还是会全都编译到一个 application.js, 但是对应的代码只在特定的 controller 下面执行。

#5 楼 @bastengao 恩,我知道。但是我不想把所有代码编译到一个文件中,因为这样会引入大量无用代码。

目前使用的这个方法还是有问题的,比如有的资源文件是空的,还是会请求一次。

目前自己写了一个 view heapler

 module ApplicationHelper
  HAS_CONTROLLERS=[].freeze
  def controllerAsset
    if HAS_CONTROLLERS.include?(params[:controller])
      params[:controller]
    else
      ""
    end
  end
end

来判断是否需要加载 asset

#7 楼 @lilijreey https://github.com/jasl/a_rails_start_up_omakase/blob/master/app/helpers/application_helper.rb#L94-L98 类似这样的写法就可以了,几年前写的,应该还可以用 需要有定制 assets 的页面在 view 里调一下这 helper

对应代码只在特定 action 执行也很容易,可以在 html 标签上加 class 属性,里面添加好 action 和 controller 信息,然后嘛... jquery 呀

  1. 删除 Turbolinks
  2. 清空 application.js 里面的内容
  3. 不要在布局 javascript_include_tag 'application'
  4. 配置文件里面 config.assets.precompile += '*.js' 把每个文件都独立编译。(如果你不担心静态文件缓存,不需要 hash tag,不需要预处理,那么直接放 public 目录里面就行了)
  5. 在每个页面单独 javascript_include_tag 需要的 js 文件。(如果放在 public 目录,就直接写 script 标签)

成功回到 Rails 2 时代。

12 Floor has deleted

一次加载有一次加载的好。 加载了又不会执行,浪费点流量而已。

You need to Sign in before reply, if you don't have an account, please Sign up first.