4

问题

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

语境

这个问题有一些非常高评价的评论,它们都在问同样的事情(见这个这个),但我实际上没有看到任何答案。

查看Rails 升级指南,建议如下: 在此处输入图像描述

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

如链接问题中所述,这意味着生产中需要所有宝石。从根本上说,这对我来说没有意义,我觉得我错过了一些明显的东西。资产预编译的全部意义在于我们避免在生产中进行,所以这个命令(据我所知)应该是这样的:
RAILS_ENV=development RAILS_ENV_TARGET=production rake assets:precompile
或者一些业务。

我在这里阅读了关于旧 Rails 票证的讨论,似乎没有回答这个问题——我们如何从生产环境中获取开发依赖项?一位用户在这里特别总结了同样的问题

仍然让我感到震惊的是,生产中的 ruby​​racer 之类的默认内存膨胀很差,特别是如果预编译是核心的建议并且在这一点上被广泛接受的最佳实践。许多人可能永远不会停止考虑,即使他们在资产组被删除后来到 Rails 或从未考虑过它是否服务于该目的 - 至少在生成的 Gemfile 中的建议性评论可能是一个好主意。

现在,对于开发人员来说,由于从预编译任务中删除了加载组,因此对于他们知道在生产 Web 或工作进程中不需要的 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]))config/application.rb. 真是一团糟。

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

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

tl;博士:

我们如何从生产运行时移除开发依赖?或者,我错过了什么,为什么这种能力是可取的/默认的?

4

1 回答 1

4

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

您引用的线程中的此评论具有启用旧:assets组行为的说明:

更改Bundler.require(*Rails.groups)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 和生产 gem 之间的界限变得更加模糊。例如,现在许多 gem 都希望有一个可用的 javascript 解释器。此外,许多 Rails 应用程序现在.coffee在视图中使用模板(而不是.js.erb),并且由于这些模板无法预编译,coffeescript 必须在生产中可用。

基本上,随着 Rails 贡献者开始从组中删除越来越多的 gem :assets,他们意识到它不再需要存在,并且如果它消失了会简化事情。它最初只是为了避免意外的按需编译而存在,但是在 Rails 4 中更新了资产管道,以期望默认情况下只提供静态资产。

最后,它可能不是最优化内存的决定(因为你正在require使用一堆你从未使用过的宝石)但它是最普遍兼容的。

编辑:另请参阅此问题以获取有关此问题的更多讨论/答案。

于 2016-09-28T22:41:40.410 回答