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:
同样,资产预编译是通过以下命令完成的:
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 报告我的机器上的 rubyracer 大小为 17MB,并且它不使用自动加载。我们没有使用任何 CoffeeScript 视图模板。
该评论的作者提出了一种解决方法,但后来在线程中讨论了该策略的缺陷,这让我感到紧张。
tl;dr:
我们如何从生产运行时删除开发依赖项?或者,我缺少什么来解释为什么这种能力是可取的/默认的?