在Node中,"node module wrapper function"是什么意思?

10
我想了解“模块包装函数”是什么意思,以及它对我的代码有什么作用。
(function (exports, require, module, __filename, __dirname) {  
       
    
 });

你在哪里找到包含 processglobal 的这个包装器?在 node.js 文档 中的包装器并不包括它们。其他参数是特定于模块的变量,因此 node.js 通过将您的模块代码插入到此函数中,在处理代码之前为每个模块定义它们,然后通过此函数调用您的代码并传递这些特定于模块的参数。 - jfriend00
相关的 Node.js 源代码,展示了包装器:https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L124 - jfriend00
4个回答

13

原始回答

根据Node.js文档

在模块的代码执行之前,Node.js会用一个函数包装器将其封装起来,该包装器如下所示:

(function(exports, require, module, __filename, __dirname) { 
    // Module code actually lives in here 
}); 

Node.js通过这种方式实现了一些功能:

  • 它使得顶级变量(使用var、const或let定义)仅限于模块而不是全局对象。
  • 它有助于提供一些看起来是全局变量但实际上只属于该模块的变量,例如:
    • 模块和exports对象,实现者可以使用它们从模块中导出值。
    • 包含模块的绝对文件名和目录路径的方便变量__filename和__dirname。

本质上,这个包装器用于配置您的模块,并且使得能够使用变量exportsrequiremodule__filename__dirname

OP还提到了processglobal变量。

  • process对象提供有关当前Node.js进程的信息和控制。
    • 它会发出事件,例如exit和uncaughtException来管理Node进程。
    • 它还包括函数,如process.abort()以结束当前进程。
    • 要查看所有信息,请参阅Node上的process文档
  • global提供了一个访问和设置全局变量的系统。
    • 例如,如果您在一个模块中执行global.something = true,在另一个模块中您可以访问something并且它将为true(无需导出它)。
    • 请阅读Node上的global文档以获取更多信息。

您也可以编辑这个包装器:

let Module = require('module');

Module.wrap = (function (exports, require, module, __filename, __dirname) {
    // What you want the new wrapper to be.
    return Module.wrapper[0] + exports + 'console.log("This is the wrapper.");' + Module.wrapper[1];
});

OP在包装器中也显示了globalprocess。您能解释一下这是从哪里来的吗? - jfriend00
@jfriend00 好的,我已经添加了一个关于那个的部分。 - Marco
抱歉,这是一个错误。在Node.js中,它最初并不包括在内。但是,我想问一下,是否可以更改此模块包装函数的内容? - yasiru
@jfriend00 对我来说它似乎是可编辑的。当然,为了使代码正常运行,您必须遵循相当严格的格式。我在repl.it上制作了一个简单的演示,展示了可以进行的轻微更改。链接 - Marco
@Marco,您的演示不可用。 - Melab
显示剩余3条评论

2

我觉得我有点晚发这篇文章,但我想在这里分享我的意见。

所以你写的表达式是IIFE(立即调用函数表达式)。

基本上,你在(Node)文件中的代码被包装在这个特定的函数中。当有人需要这个文件时,IIFE会自动运行并提供对象,如module.exports,exports,__dirname,__filename。

这些对象不是全局的,而是局部于你的模块(文件)。这些对象由这个IIFE函数提供。使用这个对象可以导出你的模块。

链接到文档已经在上面的答案中提供了,那应该会有帮助。


1

If you write some code, e.g.:

const fs = require("fs");
module.exports = fs.readFileSync(__dirname + "test.txt");
process.exit();

然后,您将使用许多全局变量,这些变量未通过js规范定义,它们仅在node中可用。为了使它们对代码可用,执行的代码被包含在您引用的函数中,从而允许您访问它们。他们也可以编写一些C++代码来解决这个问题,但那将会更加复杂。


0

“模块包装函数”是一个封装了Node.js模块内代码的函数。当Node.js加载和执行一个模块时,它会自动添加这个函数。模块包装函数的目的是为模块的代码提供本地作用域,并公开某些变量和工具以进行模块管理。

模块包装函数接受几个参数:

exports:它是一个对象,允许你将函数、对象或值从模块导出,以便其他模块可以访问它们。

require:它是一个用于导入其他模块及其导出功能到当前模块的函数。

module:它是一个表示当前模块的对象,提供有关模块的信息,如文件名和导出内容。

__filename:它是一个包含当前模块文件绝对路径的字符串。

__dirname:它是一个包含当前模块文件所在目录的绝对路径字符串。

通过将这些参数提供给模块包装函数,Node.js确保您的模块代码在其自己的隔离作用域中执行。这种封装防止了模块的变量和函数与其他模块发生冲突或污染全局作用域。

以下是一个示例,说明模块包装函数的用法:

(function (exports, require, module, __filename, __dirname) {
  // Your module code here

  // Example of exporting a function
  exports.myFunction = () => {
    console.log("Hello from myFunction!");
  };

  // Example of importing another module
  const otherModule = require("./otherModule");
  otherModule.someFunction();
});

在上面的例子中,模块包装函数为模块的代码提供了局部作用域。它通过"exports"对象将myFunction作为模块公共接口的一部分进行导出。它还通过"require"函数使得从另一个模块中导入someFunction成为可能。
总的来说,模块包装函数有助于封装您的模块代码,管理导出和导入,并提供必要的与模块相关的变量和工具。

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