Rails 3.1.0中的ActionView::Template::Error(application.css未预编译)

281

我创建了一个基本的Rails应用程序,其中包括一个简单的页面控制器,具有索引功能。当我加载页面时,会出现以下错误:

ActionView::Template::Error (application.css isn't precompiled):
    2: <html>
    3: <head>
    4:   <title>Demo</title>
    5:   <%= stylesheet_link_tag    "application" %>
    6:   <%= javascript_include_tag "application" %>
    7:   <%= csrf_meta_tags %>
    8: </head>
  app/views/layouts/application.html.erb:5:in `_app_views_layouts_application_html_erb__43625033_88530400'

Gemfile

source 'http://rubygems.org'

gem 'rails', '3.1.0'

# Bundle edge Rails instead:
# gem 'rails',     :git => 'git://github.com/rails/rails.git'

gem 'sqlite3'

gem 'execjs'
gem 'therubyracer'

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails', "  ~> 3.1.0"
  gem 'coffee-rails', "~> 3.1.0"
  gem 'uglifier'
end

gem 'jquery-rails'

# Use unicorn as the web server
# gem 'unicorn'

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'

group :test do
  # Pretty printed test output
  gem 'turn', :require => false
end

7
执行 "bundle exec rake assets:precompile" 看起来可以解决问题,但为什么它不直接起作用呢? - Chris Muench
10
即使运行了 "bundle exec rake assets:precompile",我在生产环境中仍然遇到相同的问题。请您帮忙翻译。 - Lucas Renan
14个回答

313

默认情况下,Rails 假定您已经在生产环境中预编译了文件。如果您想在生产环境中使用实时编译(在运行时编译资产),则必须将 config.assets.compile 设置为 true。

# config/environments/production.rb
...
config.assets.compile = true
...

当使用预编译资源但发现有文件缺失时,您可以使用此选项回退到 Sprockets。

如果设置了config.assets.compile 选项为 false 并且有缺少的预编译文件,则会收到一个 "AssetNoPrecompiledError" 错误,其中包含缺失文件的名称。


3
你可能想尝试一下这篇文章所说的内容: http://devcenter.heroku.com/articles/rails31_heroku_cedar(我自己还没有尝试过) - Chris Muench
7
只是为了明确起见,config.assets.compile选项位于config/environments/production.rb中(如果您正在生产环境中工作)。如果您想要在生产环境中进行实时/延迟编译,还需要在application.rb中启用延迟编译。 - avioing
34
激活运行时编译不是解决方案,因为会影响性能。解决方案是修复核心问题,以允许进行资产预编译。 - David Tuite
5
我使用RAILS_ENV=production bundle exec rake assets:precompile 预编译了资源,为什么我会收到这个错误并需要设置这个标志呢? - Tony
2
@Tony,因为你可能需要的不是application.css/js/image文件,并且你没有在application.rb中注册它。添加/编辑application.rbconfig.assets.precompile +=%w(first.css second.js)。现在这些文件也将被编译。如果您仅在sprockets require中使用它们,请不要添加所有文件,而只需在<link>/<script>中包含它们即可。 - elado
显示剩余4条评论

202

如果您在production.rb中设置config.assets.compile为false并预编译静态资源,那么您将获得更好的生产性能。 您可以使用以下 rake 任务进行预编译:

bundle exec rake assets:precompile

如果你使用的是Capistrano,版本2.8.0有一个配方可以在部署时处理这个问题。 有关更多信息,请参见资产管道指南的“生产中”部分: http://guides.rubyonrails.org/asset_pipeline.html


14
我不敢相信找到如何做这件事有多么困难。 - derekerdmann
3
这似乎是更好的选择:将实时编译设置为true“使用更多内存,性能比默认设置差,并且不被推荐。” http://guides.rubyonrails.org/asset_pipeline.html#live-compilation - andrew.rockwell
2
@Underworld Bundler是一种管理Ruby应用程序中gem依赖关系的工具,它被集成到Rails 3中。如果您正在使用bundler,运行bundle exec rake...将确保您加载了适合您的应用程序的正确rake和相关依赖项。如果您没有使用bundler,您只需运行rake... - richardsun
3
如果你要运行上述命令,请确保你已经将环境设置为生产模式,或者在命令前加上 prefix: RAILS_ENV=production。 - JESii
在预编译资产后,不要忘记重新启动服务器(例如nginx)。 - Kood
显示剩余4条评论

31

好的-我遇到了同样的问题。我不想使用"config.assets.compile=true",所以我必须将所有的.css文件添加到config/environments/production.rb的列表中:

config.assets.precompile += %w( carts.css )

接着我需要创建(然后删除)tmp/restart.txt

我一直使用stylesheet_link_tag帮助程序,所以我发现所有额外的CSS文件都需要添加:

find . \( -type f -o -type l \) -exec grep stylesheet_link_tag {} /dev/null \;

如果您使用媒体查询和不同的CSS文件来适应不同的分辨率,这是最佳选择。 - Fa11enAngel
1
我必须把所有的css文件都包含在数组中吗?如果我有40个css文件怎么办? - yozzz

30

对于Capistrano用户的一个快速解决方法是在Capfile中添加这一行:

# Uncomment if you are using Rails' asset pipeline
load 'deploy/assets'

11

对于所有正在阅读此内容但不会出现问题的人application.css,而是他们的自定义CSS类例如admin.cssbase.css等。

解决方案是如上所述使用。

bundle exec rake assets:precompile

在样式表引用中,只需引用 application.css

<%= stylesheet_link_tag    "application", :media => "all" %>

由于资产管道将在application.css中预编译所有样式表,这也发生在开发中,因此在使用资产管道时使用任何其他引用都是错误的。


8

我在我的开发环境中遇到了完全相同的错误。最终,我只需要添加以下内容就能够修复它:

config.assets.manifest = Rails.root.join("public/assets")

我将以下内容添加到我的config/environments/development.rb文件中,问题得以解决。最终我在开发环境下与资源相关的配置如下:

config.assets.compress = false  
config.assets.precompile += %w[bootstrap-alerts.js] #Lots of other space separated files
config.assets.compile = false
config.assets.digest = true
config.assets.manifest = Rails.root.join("public/assets")
config.assets.debug = true

这是唯一对我有效的解决方案。也许是我的 Rails 版本(3.1.3)有问题?不管怎样,我可以确认我的资源已经成功预编译到 public/assets 目录下,并且它们的文件名与 manifest.yml 中列出的 SHA 值相同。由于某种原因,Rails 不再在正确的位置查找资源,即使之前我的设置一直正常运行。这个更改修复了这个问题。 - antinome
感谢您提供的解决方案。我正在尝试在开发模式下测试一些东西,但是我很惊讶它说“application.css没有预编译”,即使我已经预编译了资产,并且public/assets/application.css已经存在于目录中。令人惊讶的是,他们在生产中自动为您设置config.assets.manifest,但在开发中却没有这样做。 - Tyler Rick

5
我也遇到了这个问题,试图在没有预编译的情况下在生产环境中运行,但仍会抛出未预编译错误。 我不得不更改被注释的 application.rb 中的哪一行:
  # If you precompile assets before deploying to production, use this line
  # Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line
  Bundler.require(:default, :assets, Rails.env)

2
只想澄清一下,对于以后读到这篇文章的人,你需要修改的代码位于 config/application.rb 文件中。 - GMA

4

以下是快速修复方法:

如果您正在使用Capistrano,请在deploy.rb中添加以下内容:

after 'deploy:update_code' do
  run "cd #{release_path}; RAILS_ENV=production rake assets:precompile"
end

cap deploy


3

今天我遇到了这个错误信息,想要发布解决方案以解决我的问题。 结果发现我的问题是我的某个css文件缺少了一个闭合大括号,这导致该文件无法被编译。 如果您的自动化流程包括预编译资产等操作,则可能更难注意到这一点。


1

在所有其他尝试失败之后...

我的解决方案是更改布局文件从

= stylesheet_link_tag "reset-min", 'application'

= stylesheet_link_tag 'application'

它起作用了!(您可以将重置文件放在清单中。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接