首页 > 解决方案 > 如何修改 NodeJS 内置的全局对象?

问题描述

我想添加一个重要的功能,我可以在工作中使用,而无需每次都使用 require()。所以,我认为修改内置对象可以做到这一点,但我无法找到这些对象的位置来进行修改。

NodeJS 中的那些对象是二进制的吗?这是否意味着我必须分叉整个 NodeJS 存储库才能实现这一点?

请,我不想使用与要求相同的原型编辑等。我需要有原生的感觉。

标签: node.jsglobal

解决方案


首先,我同意之前的评论,这听起来有点像 XY 问题,如果您描述您真正想要解决的问题,我们可以更好地帮助您。可在任何地方工作或与任何未来版本的 node.js 一起工作的便携式 node.js 程序不依赖于某种自定义配置环境来运行。他们使用 node.js 的内置功能,并且他们需要/导入他们想要添加到环境中的外部事物。


NodeJS 中的那些对象是二进制的吗?

是的,它们在可执行文件中。

这是否意味着我必须分叉整个 NodeJS 存储库才能实现这一点?

是的。

请,我不想使用与要求相同的原型编辑等。我需要有原生的感觉。

“乡土情怀”?听起来您还没有真正购买 node.js 模块架构。它与许多其他环境不同。随着时间的推移很容易习惯。IMO,最好采用平台的流程和架构,而不是制作一些自定义版本的 node.js,只是为了节省启动代码中的一行输入。

而且,添加许多可以在任何地方使用的全局变量的整个概念几乎表明您还没有完全理解嵌入到 node.js 中的模块设计的设计、架构、代码重用和可测试性优势。如果您有,您就不会尝试编写大量无法以您现在没有预料到的其他方式重用的代码。


也就是说,在 Github 上搜索 node.js 源代码时,我发现了这个源文件node.js ,它是在 node.js 全局对象中添加了很多东西的地方,例如setTimeout()clearTimeout()、等等。因此,该源文件似乎是 node.js 设置全局对象的位置。如果你想在那里添加你自己的东西,那是一个可以完成的地方。setImmediate()clearImmediate()

要提供该代码的示例(您可以查看上面的链接以获取完整代码):

if (!config.noBrowserGlobals) {
  // Override global console from the one provided by the VM
  // to the one implemented by Node.js
  // https://console.spec.whatwg.org/#console-namespace
  exposeNamespace(global, 'console', createGlobalConsole(global.console));

  const { URL, URLSearchParams } = require('internal/url');
  // https://url.spec.whatwg.org/#url
  exposeInterface(global, 'URL', URL);
  // https://url.spec.whatwg.org/#urlsearchparams
  exposeInterface(global, 'URLSearchParams', URLSearchParams);

  const {
    TextEncoder, TextDecoder
  } = require('internal/encoding');
  // https://encoding.spec.whatwg.org/#textencoder
  exposeInterface(global, 'TextEncoder', TextEncoder);
  // https://encoding.spec.whatwg.org/#textdecoder
  exposeInterface(global, 'TextDecoder', TextDecoder);

  // https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
  const timers = require('timers');
  defineOperation(global, 'clearInterval', timers.clearInterval);
  defineOperation(global, 'clearTimeout', timers.clearTimeout);
  defineOperation(global, 'setInterval', timers.setInterval);
  defineOperation(global, 'setTimeout', timers.setTimeout);

  defineOperation(global, 'queueMicrotask', queueMicrotask);

  // Non-standard extensions:
  defineOperation(global, 'clearImmediate', timers.clearImmediate);
  defineOperation(global, 'setImmediate', timers.setImmediate);
}

此代码内置于 node.js 可执行文件中,因此我知道直接修改它的唯一方法(无需对可执行文件本身进行 hackish 修补)就是修改文件,然后为您的平台将 node.js 重建为自定义版本。


在更实际的一点上,您还可以使用-r module 命令行参数告诉 node.jsrequire(module)在启动主脚本之前运行。因此,您可以采用不同的方式从始终将-r fullPathToYourModule参数传递给 node.js 的 shell 文件启动 node.js,因此它将始终运行您的启动模块,将内容添加到全局对象中。

同样,您这样做只是为了在启动文件中保存一行输入。真的值得这样做吗?


推荐阅读