即使资产没有变化,也会发生 Rails 资产预编译

Posted

技术标签:

【中文标题】即使资产没有变化,也会发生 Rails 资产预编译【英文标题】:Rails asset precompilation happening even if there is no change in assets 【发布时间】:2016-10-09 13:44:29 【问题描述】:

我正在 AWS Opsworks 上运行 rails 堆栈。在 before_symlink.rb 部署钩子中,我有以下代码。

rails_env = new_resource.environment["RAILS_ENV"]
shared_path = "#new_resource.deploy_to/shared"

# create shared directory for assets, if it doesn't exist
directory "#shared_path/assets" do
  mode 0770
  action :create
  recursive true
  not_if do
    Dir.exists?("#shared_path/assets")
  end
end

# symlink current deploy's asset folder to shared assets each deploy
link "#release_path/public/assets" do
  to "#shared_path/assets"
end

# precompile assets into public/assets (which is symlinked to shared assets folder)
execute "rake assets:precompile" do
  cwd release_path
  command "bundle exec rake assets:precompile --trace"
  environment 'RAILS_ENV' => rails_env
end

问题是即使没有更改,资产也会一直预编译,尽管它们位于符号链接的共享文件夹中。我在 Rails 4.1.2 上运行,我猜 Rails 足够智能,可以在 Rails 4 之后只编译更改的资产?为什么会这样?

更新

现在已经解决了。

我错过了将 /tmp/cache 符号链接到 /shared/tmp/cache。这是 sprockets 存储缓存文件的地方。

更新代码。

# Precompile assets. Assets are compiled into shared/assets and shared between deploys.
rails_env = new_resource.environment["RAILS_ENV"]
shared_path = "#new_resource.deploy_to/shared"

# create shared directory for assets, if it doesn't exist
directory "#shared_path/assets" do
  mode 0770
  action :create
  recursive true
  not_if do
    Dir.exists?("#shared_path/assets")
  end
end

#create shared directory to store sprockets cache
directory "#shared_path/tmp/cache" do
  mode 0770
  action :create
  recursive true
  not_if do
    Dir.exists?("#shared_path/tmp/cache")
  end
end

# symlink current deploy's asset folder to shared assets each deploy
link "#release_path/public/assets" do
  to "#shared_path/assets"
end

# symlink current deploy's sprockets cache  folder to shared cache folder on each deploy
link "#release_path/tmp/cache" do
  to "#shared_path/tmp/cache"
end

# precompile assets into public/assets (which is symlinked to shared assets folder)
execute "rake assets:precompile" do
  cwd release_path
  command "bundle exec rake assets:precompile --trace"
  environment 'RAILS_ENV' => rails_env
end

【问题讨论】:

【参考方案1】:

OpsWorks 会在每次部署时重建您的整个 Rails 应用程序,并保留大量备份副本。它应该在如下路径中创建它:

/srv/www/yourappname/current

您可以通过 ssh 进入您的服务器来确认这一点。如果你去路径

ls -la /srv/www/yourappname/releases

您应该会看到一些带有日期时间戳名称的文件夹。 如果您查看内容,它们将包含您的整个 Rails 应用程序。 如果在部署过程中出现问题,这可以很容易地回滚。

由于每个文件夹基本上都是您的应用程序的新安装,因此需要进行资产预编译,否则当前版本将没有任何资产。这种类型的部署不只是让同一个目录做一个 git pull origin master

更新:看起来这是带有 Sprockets 的 issue,已在此 pull request 中解决,因此请确保您的 gem sprockets 版本包含此 commit。看起来它已包含在 v4.0.0beta1v4.0.0beta2 中,所以尝试一下,如果没有,请尝试降级到 >=2.12.4 as per this comment

【讨论】:

我明白了。但是对于任何“发布”文件夹,我的公共/资产符号链接到共享/资产。所以应该没关系吧?我的意思是对于任何版本,基本上资产都驻留在一个地方。 这可能是真的,但我相信默认的 Opsworks 部署脚本会默认运行预编译。有关更多详细信息,请参阅这些链接。 docs.aws.amazon.com/elasticbeanstalk/latest/dg/…forums.aws.amazon.com/message.jspa?messageID=436400github.com/aws/opsworks-cookbooks/… 你是救生员。我已经在使用 Sprockets 2.12.4,但我错过了将 /tmp/cache 符号链接到 /shared/cache。这是 sprockets 存储缓存文件的地方。我从 PR 描述中得到它。非常感谢 :) 现在部署时间不到 1 分钟。 也许添加您自己的答案和/或更新已解决的问题,并发布您更改/添加的实际代码以解决您的问题。可能对其他人有帮助。

以上是关于即使资产没有变化,也会发生 Rails 资产预编译的主要内容,如果未能解决你的问题,请参考以下文章

Rails:预编译资产缺少节点模块

Rails 3.1 资产管道 - 为啥我的图像没有为生产进行预编译?

Rails 4 - 在生产服务器上预编译资产后没有 manifest.json

如何加快 Rails 3+ 中的资产预编译?

rails and metronic - 资产预编译:SassC 错误,空间不足

预编译 Rails AngularJS 资产