13

有没有办法预编译 node.js 脚本并分发二进制文件而不是源文件?

4

1 回答 1

18

节点已经这样做了

“这个”是指创建机器可执行的二进制代码。不过,它使用JIT 模式来做到这一点。在我介绍了其他人在谷歌上搜索可能正在搜索的内容之后,更多信息......

操作系统本机二进制可执行文件... 如果使用二进制文件而不是源代码,您的意思是本机操作系统可执行文件,是的。 NW.JSElectron都做得很出色。

在你的 node.js 脚本中使用二进制文件...... 如果使用二进制文件而不是源代码,你的意思是能够将你的脚本的一部分编译成二进制文件,所以它很难或不可能使用,或者你想要机器原生速度的东西,是的。它们被称为C/C++ 插件。您可以分发二进制文件(对于您的特定操作系统)并像使用任何其他 var n = require("blah"); 一样调用它。

Node 使用二进制文件“Just In Time”

开箱即用,Node 会自行预编译您的脚本并创建缓存的 V8 机器代码(认为“可执行” - 它使用运行 Node 的 CPU 原生的真实机器代码),然后执行它处理的每个事件。

这是一个谷歌参考,解释了 V8 引擎实际上编译为真正的机器代码,而不是虚拟机。

谷歌 V8 JavaScript 引擎设计

此编译发生在您的应用程序首次加载时。

只要您调用“require('module')”指令,它就会将这些代码位缓存为“模块”。

它不会等待您的整个应用程序被处理,而是在遇到每个“需求”时预编译每个模块。

require 中的所有内容都被编译并引入内存,包括它的变量和活动状态。同样,与许多流行的博客文章相反,这是作为单独的机器代码进程执行的。没有虚拟机,也没有任何解释。JavaScript 源代码本质上被编译成内存中的可执行文件。

这就是为什么每个模块都可以引用相同的 require 而不会产生大量开销的原因;它只是引用内存中预编译和现有的对象,而不是“重新需要”整个模块。

您可以随时强制它重新编译任何模块。鲜为人知的是,您实际上可以非常轻松地控制重新编译这些对象,使您能够“热重新加载”应用程序的各个部分而无需重新加载整个事物。

一个很好的用例是创建自修改代码,例如,从文件夹加载策略的策略模式,一旦添加了新文件夹,您自己的代码就可以将文件夹重新编译成 in-线策略模式,创建一个“strategyRouter.js”文件,然后使路由器的节点缓存无效,这会强制节点仅重新编译该模块,然后在未来的客户端请求中使用该模块。

最终结果:只要将新文件或文件夹放入应用程序,Node 就可以热重载路由或策略。无需重新启动您的应用程序,无需分离无状态和有状态操作:只需将响应编写为常规 Node 模块,并在它们更改时重新编译它们。

注意:在人们告诉我自修改代码与 一样糟糕或更eval糟糕,调试很糟糕并且无法维护之前,请注意 Node 本身就是这样做的,许多流行的 Node 框架也是如此。我不是在解释原始研究,而是通过设计来解释 Google V8 引擎(以及 Node)的能力,正如这个问题要求我们做的那样。请不要向 R FM 的人开枪,否则人们会停止 R'ing 并保持沉默。

“Unix 的设计不是为了阻止它的用户做愚蠢的事情,因为这也会阻止他们做聪明的事情。” – 道格·格温

Angular 2、Meteor、新的开源 Node-based Light table IDE和一堆其他框架都朝着这个方向发展,以便进一步将开发人员从代码中移除,让他们更接近应用程序。

如何重新编译(热重载)所需的 Node 模块?

这实际上真的很简单......这是一个热重载的 npm,对于替代方案只是谷歌“节点需要热重载”

https://www.npmjs.com/package/hot-reload

如果我想以一种惊人的新方式构建自己的框架并热重载怎么办?

就像 Node 中的许多事情一样,这也非常容易。Node 就像用于服务器的 jQuery!;D

stackoverflow - 使节点的要求缓存无效

于 2016-01-08T17:54:09.793 回答