【问题标题】:Conditionally disable asset precompile in Capistrano在 Capistrano 有条件地禁用资产预编译
【发布时间】:2023-12-12 13:22:02
【问题描述】:

我已经看到了在 Rails 中执行惰性资产预编译的各种复杂且通常无效的解决方案。作为后端开发人员,我并不特别想在每次程序部署时重新编译我从未接触过的资产,但因为资产是通过load 'deploy/assets' 加载到Capfile 中的,而不是通过在deploy.rb 中定义任务来加载的,所以我可以'想办法有条件地禁用它。

我所追求的行为是使用cap deploy 进行常规预编译部署,并使用cap deploy:no_assets 跳过资产部署。

【问题讨论】:

    标签: ruby-on-rails capistrano


    【解决方案1】:

    turbo-sporocket-rails 和自动跳过脚本都有一些缺陷(我稍后会提到)。所以我使用了下面的hack,所以我可以传递一个参数来随意跳过资产预编译:

    callback = callbacks[:after].find{|c| c.source == "deploy:assets:precompile" }
    callbacks[:after].delete(callback)
    after 'deploy:update_code', 'deploy:assets:precompile' unless fetch(:skip_assets, false)
    

    此脚本将更改内置的资产预编译钩子,因此它将根据 skip_assets 参数进行钩子。我可以致电cap deploy -S skip_assets=true 跳过整个资产预编译。


    对我来说,turbo-sporocket-rails 在没有任何变化的情况下仍然需要几分钟来进行检查。当我需要尽快将修复推送到服务器时,这可能至关重要。因此我需要我的强制跳过方法。

    【讨论】:

    • 这是一个很好的解决方案。在带有 Capistrano 2 的 Rails 4 应用程序上,它仍然可以工作。只是要小心你没有任何其他作业链接到'deploy:assets:precompile',否则它们也会被跳过。
    【解决方案2】:

    rails4 使用新版本的 sprocket 解决了这个问题,只预编译已更改的资产。同时,对于您的 rails3 应用程序,我推荐 turbo-sprockets-rails3 gem。

    这个 gem 最初是由 Nathan Broadbent 为 sprockets-rails 提供的 set of patches,由于问题已在 rails4 中解决,因此未合并到 master。来自自述文件:

    • 加快 Rails 3 rake 资产的速度:仅通过根据源文件的哈希重新编译更改的资产进行预编译

    • 仅编译一次即可生成指纹和非指纹资产

    还有:

    turbo-sprockets-rails3 应该可以与最新版本的 Capistrano 一起使用。

    我可以确认它适用于使用 Capistrano 部署的 rails-3.2.x 应用程序。

    作为 GitHubbers 的附注,原始的 pull request 是一个很好的例子,说明如何将代码提交到开源项目,即使它没有被合并。

    【讨论】:

    • 我自己刚切换到这个,可以证明它很棒!
    • 我确实有 Rails 4.0,我没有更改任何资产,但它只是从头开始重新编译所有内容。有什么想法吗?
    【解决方案3】:

    这个要点看起来很有前途https://gist.github.com/3072362

    它会检查您从上次部署到现在的 git 日志,以查看 %w(app/assets lib/assets vendor/assets Gemfile.lock config/routes.rb) 中是否有任何更改,如果有,则仅进行预编译。

    【讨论】:

    • 我之前已经安装了这个 gist 和类似的,但它似乎没有任何效果。如果我将 load 'deploy/assets' 留在我的 capfile 中,它不会在不需要时停止预编译。如果我取出load 'deploy/assets',即使需要它也不会预编译。即使在代码更新后添加了触发器来触发它。
    • 我认为您的 config/deploy.rb 文件中可能不需要此要点。它覆盖了 deploy:assets:precompile 任务。您应该在 Capfile 中保留 load 'deploy/assets'
    • 这仍然比 turbo-sporocket-rails 快,因为它跳过了整个检查,这对我来说需要几分钟。