Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 节点中的require是否使用eval在另一个文件中运行代码_Javascript_Node.js - Fatal编程技术网

Javascript 节点中的require是否使用eval在另一个文件中运行代码

Javascript 节点中的require是否使用eval在另一个文件中运行代码,javascript,node.js,Javascript,Node.js,我只是想理解node中的模块。我了解了一些事情,比如node围绕放置在每个文件中的代码创建模块包装函数 假设有两个文件,a.js和b.js 在a.js中,当我第一次需要b.js时,b.js中的模块包装器函数将如何执行 node是否会执行以下操作:将b.js文件的全部内容作为字符串获取,然后使用eval从a.js执行,然后将此函数调用的结果保存在缓存中。当您确实需要时,node.js具有loader.js文件,该文件负责加载模块。通过loader.js文件执行以下步骤 首先,它检查缓存模块中是否存

我只是想理解node中的模块。我了解了一些事情,比如node围绕放置在每个文件中的代码创建模块包装函数

假设有两个文件,a.js和b.js

在a.js中,当我第一次需要b.js时,b.js中的模块包装器函数将如何执行


node是否会执行以下操作:将b.js文件的全部内容作为字符串获取,然后使用
eval
从a.js执行,然后将此函数调用的结果保存在缓存中。

当您确实需要时,node.js具有loader.js文件,该文件负责加载模块。通过loader.js文件执行以下步骤

  • 首先,它检查缓存模块中是否存在模块。检查由模块完成。\u缓存
  • 如果缓存中不存在,则创建一个新的模块实例
  • 保存到缓存中
  • 使用给定的文件名调用module.load()。 这将在读取文件内容后调用module.compile()
  • 如果解析文件时出错(因为任何编译器进行编译时都有词法分析和解析步骤),则从缓存中删除模块
  • 然后返回module.export对象
  • 正如我们所知,node是开源的,我直接给出node.js的loader.js的github路径

    这是Node.js团队编写的模块加载函数的代码

    // Check the cache for the requested file.
    // 1. If a module already exists in the cache: return its exports object.
    // 2. If the module is native: call `NativeModule.require()` with the
    //    filename and return the result.
    // 3. Otherwise, create a new module for the file and save it to the cache.
    //    Then have it load  the file contents before returning its exports
    //    object.
    Module._load = function(request, parent, isMain) {
      if (parent) {
        debug('Module._load REQUEST %s parent: %s', request, parent.id);
      }
    
      var filename = Module._resolveFilename(request, parent, isMain);
    
      var cachedModule = Module._cache[filename];
      if (cachedModule) {
        updateChildren(parent, cachedModule, true);
        return cachedModule.exports;
      }
    
      if (NativeModule.nonInternalExists(filename)) {
        debug('load native module %s', request);
        return NativeModule.require(filename);
      }
    
      // Don't call updateChildren(), Module constructor already does.
      var module = new Module(filename, parent);
    
      if (isMain) {
        process.mainModule = module;
        module.id = '.';
      }
    
      Module._cache[filename] = module;
    
      tryModuleLoad(module, filename);
    
      return module.exports;
    };
    
    还可以查看本文以了解该过程是如何工作的

    差不多

    Node.js脚本文件内容和包含:

    然后模块函数与vm一起运行。runInThisContext:

      var wrapper = Module.wrap(content);
    
      var compiledWrapper = vm.runInThisContext(wrapper, {
        filename: filename,
        lineOffset: 0,
        displayErrors: true
      });
    
    vm
    模块提供并评估代码,类似于间接
    eval

    runInThisContext()编译代码,在当前全局的上下文中运行并返回结果。运行的代码无权访问本地范围,但可以访问当前全局对象

    由于vm.runInThisContext()无权访问本地作用域,因此localVar保持不变。相反,eval()确实可以访问本地范围,因此值localVar发生了更改。通过这种方式,vm.runInThisContext()非常类似于间接eval()调用,例如(0,eval)('code')


    太棒了,我也给出了同样的答案,但是你解释得很好,这很简单,很短,并且获得了很多关于loader.js的模式知识。谢谢你reply@SourabhSomani不久前刚刚浏览了这部分节点源代码。很高兴它对你也有帮助。是的,它很有帮助。我在回答中也给出了节点源代码的链接。我还研究了源代码。关于源代码的最佳解释。。。。终极的。谢谢@Estus在require.js中也一样吗??
      var wrapper = Module.wrap(content);
    
      var compiledWrapper = vm.runInThisContext(wrapper, {
        filename: filename,
        lineOffset: 0,
        displayErrors: true
      });