Rails Rails 3.1 Assets Pipeline 应该怎么配置?

suupic · 2011年11月27日 · 最后由 iwinux 回复于 2012年05月02日 · 13918 次阅读

js/css 文件加载不上,求解

环境:

  • rails 3.1.3
  • unicorn 4.1.1
  • nginx 1.0.6

现象:

  1. 用 rails s 启动开发模式,一切正常。请求地址为http://dev:3000/assets/application.js?body=1
  2. 用 rails s -e production 启动,assets pipeline 异常。请求地址为http://dev:3000/javascripts/application.js404 错误
  3. 用 unicorn -c config/unicorn.rb 启动,异常。请求地址为http://dev/assets/application.js?body=1, 404 错误
  4. 用 unicorn -c config/unicorn.rb -E production 启动,异常。请求地址为:http://dev/javascripts/application.js, 404 错误。且仅加载 application.js/css,上面 3 种情况则会加载很多其他的 js/css

404 时, nginx 的日志为:

open() "xxxxx/public/assets/application.js" failed (2: No such file or directory

rails 的日志为:

ActionController::RoutingError (No route matches [GET] "/javascripts/application.js"):

unicorn 的日志为:

cache: [GET /javascripts/application.js] miss

production 配置 (局部,其他选项默认)为:

config.serve_static_assets = false
config.assets.compress = true
config.assets.compile = false
config.assets.digest = true
config.assets.debug = true

http://guides.rubyonrails.org/asset_pipeline.html 参考下这篇,部署到 production 前要 precompile 一下,还有注意下 js,css helper 的使用

昨晚已经跟着 asset_pipeline.html 里的指导做了 刚才又整理一下思路 1、在 development 下,assets pipeline 会尝试加载所有 controller 命名的 js 和 css。WEBrick 下的请求全部返回 200;unicorn 下的所有 controller 命名的全部 404,application/jquery 返回 200。 访问地址均 assets+ 文件名,例如/assets/application.js?body=1 2、在 production 下,assets pipeline 不会加载 controller 命名的 js 和 css。请求地址为 “文件类型”+ 文件名,例如/javascripts/application.js 和/stylesheets/application.css。注意,不是 assets 目录。

所以我想,解决这个问题的关键在于为什么 production 下会把路径转换为 “文件类型 + 文件名” 的形式,而不是 “assets+ 文件名” 的形式。product 下手动输入 “assets+ 文件名” 是可以访问的

搭车再多问一句,为什么 development 会加载 controller 的 js 而 production 不会

#3 楼 @suupic dev 环境不压缩 js 所以你看到都在 head 里。prod 环境全部压缩到 applications.js 这个文件里了。

我的问题跟这个很像 http://stackoverflow.com/questions/7890845/rails-3-1-cant-enable-asset-pipeline-in-the-app

昨晚我也尝试了将 config.assets.enabled 设成 false,后来又改回 true。不确实是否跟这个有关系

现在的感觉就是 production 里没有启用 assets pipeline

#7 楼 @suupic 最好是有代码能让我们下到自己电脑上跑一跑。。

yeah,解决了!

原因是我用了 mongoid,按照 mongoid 的要求,在 application.rb 中做了修改,注释 rails/all #require 'rails/all' require "action_controller/railtie" require "action_mailer/railtie" require "active_resource/railtie" require "rails/test_unit/railtie"

这个修改导致处理 assets pipeine 的 sprockets 没有被加载 因此解决方法是在后面追加一句 require 'sprockets/railtie'

#9 楼 @suupic great! 很巧昨天 ruby-china 代码里也刚加了这个。

#10 楼 @ashchan 没看太明白,加了 #9 楼 这行以后,是不是就不用手动配置这个了?

config.assets.precompile += %w(home.css foo.js)

#12 楼 里那个正则是针对 Compass 写的,在包含所有 css/js/图片 文件的前提下,排除 Compass 的 partials(文件名是下划线开头的,比如 _shared.css.sass)

#11 楼 @huacnlee 个人觉得如果 application.{js|scss}里组织好的话,是不用额外去配置的(因为 production 下都会被压到 application 中去,而这个是自动被 precompile 的)。

上面加入 sprockets,是因为如果用 mongoid 改了 railtie 的加载的话,sprockets 就漏掉了。这样在 production 下会出现 digest 不正常等问题。

#14 楼 @ashchan 我一般的设计方式是一个 application.css 和 controller_name.css ,这样 CSS 可以细化,JS 也是类似的做法

#15 楼 @huacnlee 嗯,我也这么做。另外,第三方的 js(包括 jquery)和 css 及 image,我一般放在 vendor/assets 下,app/assets 下只放自己写的内容并且 require_tree 全包含进来。

比方说 ruby-china 已经用了 jquery-rails,那样就没必要再单独存放一份 jquery 了。这方面什么时候可以重新组织一下。

#9 楼 @suupic +1 一语中的

不喜欢 config.assets.precompile += %w( active_admin.js active_admin.css ) 这样的配置方式

#18 楼 @ruisin 是啊,这样很蛋疼,总会在发布的时候才发现少了个 CSS 或 JS ...

匿名 #20 · 2011年11月29日

这个我收藏了。。。

@ruisin @huacnlee 所以可以试试我这种写法~

#12 楼 @iwinux 这个方法靠谱!

#12 楼 @iwinux 你的方法很好,今天搜索到这个帖子,重写了一下,应该更简洁吧:

config.assets.precompile += [ Proc.new {|path| File.basename(path) =~ /^[^_].*\.\w+$/} ]

#23 楼 @daqing 我是觉得 assets:precompile 这么慢,puts 点东西出来比较友好,哈哈~

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册