为什么不应该在生产环境中使用babel-node?

12

babel-node文档中有一个严厉的警告:

不适用于生产环境

不应在生产环境中使用babel-node。它过于沉重,由于缓存存储在内存中,导致内存使用率高。您还将始终经历启动性能惩罚,因为整个应用程序需要即时编译。

让我们来分析一下:

  • 内存使用——什么意思?所有模块在应用程序的整个生命周期中都会在内存中“缓存”。他们在这里是什么意思?

  • 启动时间——这怎么成了性能问题?部署Web应用程序已经需要几秒钟(如果在CI中测试,则需要几分钟)。启动时间增加半秒钟毫无意义。实际上,如果启动时间在任何地方都很重要,那么在开发中比在生产中更重要。如果您频繁重启Web服务器以至于启动时间成为问题,则面临的问题更大。

此外,没有关于在生产环境中使用Babel的require hook (require('babel-register')) 的警告,尽管这可能与babel-node几乎完全相同。例如,您可以执行node -r babel-register server.js并获得与babel-node server.js相同的行为。(我们公司在数百个微服务中都会这么做,没有出现问题。)Babel的警告是虚假信息,还是我遗漏了什么?如果警告有效,则为什么不适用于Babel require hook?

相关: 在生产环境中使用babel-node是否可以 - 但是那个问题只是询问是否建议在生产环境中使用,答案只引用官方建议,即“不建议”。相比之下,我质疑官方建议背后的原因。


虽然在 require hook 本身中没有警告,但是在 require hook 的文档中有一个警告(在 https://babeljs.io/docs/setup/ 中的“选择您的工具”表格中选择“Require hook”)。 - Jessidhia
2个回答

2

babel-node

为了解决此问题,我们添加了生产警告:

如果没有kexec模块,您可能会陷入一个非常丑陋的情况,即子进程死亡,但其死亡或错误从未冒泡。有关更多信息,请参见https://github.com/babel/babel/issues/2137

如果关于babel-node的文档明确说明它不适用于生产环境;如果没有安装kexec,它的行为很糟糕,那就太好了。

(重点是我的)

原始问题#2137的链接已经失效,但是您可以在这里找到它。

因此,这里似乎有两个问题:

  • “大型应用程序的内存使用率非常高”
  • “如果没有安装kexec,则其行为不良”

这些问题导致了生产警告。

babel-register

另外,没有关于在生产环境中使用Babel的require hook(require('babel-register'))的警告

可能没有警告,但也不建议这样做。请参见此问题:

babel-register主要推荐简单的情况。如果您遇到了问题,请更改您的工作流程以便基于文件监视器构建。请注意,我们也从未推荐将babel-register用于生产案例。


1
我对 babel 和 node 的内部了解不够,无法给出完整的答案;其中一些是推测,但 babel-node 所做的缓存不同于 node 所做的缓存。
babel-node 的缓存将成为另一个缓存,在 node 的 require 缓存之上,并且它将在最好的情况下缓存结果源代码(在被提供给 node 之前)。
我相信,node 的缓存在评估模块后,只会缓存从 exports 可达的内容,或者说那些不再可达的内容最终将被垃圾回收。
启动时间的惩罚将取决于您的 .babelrc 内容,但您正在强制 babel 每次执行时翻译整个源代码。即使您实现了持久性缓存,babel-node 仍然需要为应用程序的每个文件执行缓存获取和验证。
在开发中,更适合的工具,如处于观察模式的 webpack,可以在冷启动后,重新翻译仅修改的文件,这比具有完美优化缓存的 babel-node 更快。

"babel-node的缓存是建立在node的require缓存之上的另一个缓存。这个额外的缓存是什么,它的目的是什么?为什么babel-register没有同样的问题?" - callum
原来babel-node和babel-register也在“您的临时目录”中使用磁盘缓存,无论它在哪里:https://babeljs.io/docs/usage/require/ - Jessidhia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接