使用 Bundler 和 Rails 4 将开发精华从生产中移除

2023-12-29

Problem

我们部署的应用程序具有开发依赖项。我们有很多开发依赖。这会增加生产中的工件大小和内存消耗,因为所有这些依赖项都是require'd。大多数实例都部署在云中,因此更大的实例更多的内存=更多的钱。我们希望减少大小/内存,并在已部署的工件和开发环境之间进行更清晰的分离。一个特别重点是需要therubyrhino在生产环境中,即使我们的资产是预编译的。

Context

这个问题 https://stackoverflow.com/q/16406204/4970406有一些得到高度评价的评论提出了同样的问题(请参阅this one https://stackoverflow.com/questions/16406204/why-did-rails4-drop-support-for-assets-group-in-the-gemfile#comment27655021_17221248 and this one https://stackoverflow.com/questions/16406204/why-did-rails4-drop-support-for-assets-group-in-the-gemfile#comment24284525_16420771),但我实际上没有看到任何答案。

Looking at the Rails upgrade guide http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-3-2-to-rails-4-0-gemfile, the following is suggested: enter image description here

同样,资产预编译是通过以下命令完成的:
RAILS_ENV=production rake assets:precompile

正如链接问题中所讨论的,这意味着all生产时需要宝石。从根本上来说,这对我来说没有意义,而且我觉得我错过了一些明显的东西。资产预编译的重点是我们避免在生产中执行它,因此这个命令(据我所知)应该类似于:
RAILS_ENV=development RAILS_ENV_TARGET=production rake assets:precompile
或者做点生意。

我读过关于旧 Rails 票证的讨论here https://github.com/rails/rails/commit/49c4af43ec5819d8f5c1a91f9b84296c927ce6e7#commitcomment-4449619,这似乎没有回答这个问题——我们如何从生产环境中获取开发依赖项?一位用户特别总结了同样的问题here https://github.com/rails/rails/commit/49c4af43ec5819d8f5c1a91f9b84296c927ce6e7#commitcomment-4449619

令我印象深刻的是,生产中像 therubyracer 这样的东西默认的内存膨胀很差,特别是如果预编译是核心的建议并且是目前广泛采用的最佳实践的话。许多人可能永远不会停下来考虑,即使他们在资产组删除后来到 Rails,或者从未考虑过它服务于此目的,这种情况也会发生——至少在生成的 Gemfile 中添加一条暗示性评论可能是个好主意。

现在,对于开发人员来说,解决这个问题对于他们知道在生产网络或工作进程中不需要的 gem 来说是一件很困难的事情,因为加载组已从预编译任务中删除了。我现在基本上将其作为样板包含在新应用程序中: namespace :assets do # Override sprockets-rails task to put back assets group require, so as to # avoid memory bloat in web processes :-/ task :environment do Bundler.require(:assets) Rake::Task['environment'].invoke end end
加上恢复Bundler.require(*Rails.groups(assets: %w[development test])) to config/application.rb。真是一团糟。

仅供参考,du 报告我的机器上的 ruby​​racer 大小为 17MB,并且它不使用自动加载。我们没有使用任何 CoffeeScript 视图模板。

该评论的作者提出了一种解决方法,但后来在线程中讨论了该策略的缺陷,这让我感到紧张。

tl;dr:

我们如何从生产运行时删除开发依赖项?或者,我缺少什么来解释为什么这种能力是可取的/默认的?


我们如何从生产运行时删除开发依赖项?

这条评论 https://github.com/rails/rails/commit/49c4af43ec5819d8f5c1a91f9b84296c927ce6e7#commitcomment-4449619在您引用的线程中有启用旧的说明:assets群体行为:

Change Bundler.require(*Rails.groups) to Bundler.require(*Rails.groups(assets: %w[development test])) in config/application.rb,并将其添加到您的 rake 任务中:

namespace :assets do
  # Override sprockets-rails task to put back assets group require, so as to
  # avoid memory bloat in web processes :-/
  task :environment do
    Bundler.require(:assets)
    Rake::Task['environment'].invoke
  end
end

或者,我缺少什么来解释为什么这种能力是可取的/默认的?

因此,严格来说,这些不是开发依赖项。您实际上不应该这样考虑它们,因为资产预编译应该发生在生产环境中,即使只是在部署期间。您绝对不应该在开发人员计算机上进行预编译。

最重要的是,自资产管道的早期版本以来,特定资产宝石和生产宝石之间的界限变得更加模糊。例如,许多 gem 现在都希望有 javascript 解释器可用。此外,许多 Rails 应用程序现在都使用.coffee视图中的模板(而不是.js.erb),并且由于这些无法预编译,coffeescript 必须在生产中可用。

基本上,随着 Rails 贡献者开始从:assets小组中,他们意识到它实际上不再需要存在,并且如果它消失就会简化事情。它最初只是存在,以避免意外的按需编译,但资源管道在 Rails 4 中进行了更新,默认情况下仅提供静态资源。

最后,这可能不是记忆最优化的决定(因为你requireing 一堆你从未使用过的宝石)但它是最普遍兼容的。

编辑:另请参阅这个问题 https://stackoverflow.com/questions/16406204/why-did-rails4-drop-support-for-assets-group-in-the-gemfile有关此问题的更多讨论/答案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Bundler 和 Rails 4 将开发精华从生产中移除 的相关文章

随机推荐