javascript CommonJS需要机制

b09cbbtk  于 2023-05-27  发布在  Java
关注(0)|答案(1)|浏览(165)

根据我的课本,require函数的定义是这样的

require.cache = Object.create(null);

function require(name) {
    if (!(name in require.cache)) {
        let code = readFile(name);
        let module = {exports: {}};
        require.cache[name] = module;
        let wrapper = Function("require, exports, module", code);
        wrapper(require, module.exports, module);
    }
    return require.cache[name].exports;
}

注意事项:

  • readFile(name)是一个任意函数,取决于我使用的是node.js还是特定的浏览器。
  • 我们将该高速缓存设置为空对象
  • 这是我的教科书引用的代码。

为了避免多次加载同一个模块,require保留了一个已经加载的模块的存储(缓存)。调用时,它首先检查请求的模块是否已加载,如果未加载,则加载它。这包括阅读模块的代码,将其 Package 在函数中,并调用它。
我不明白的是:在这种情况下递归是如何工作的。我只是对 Package 器功能感到困惑。

tjvv9vkg

tjvv9vkg1#

假设你有这些极其简单的模块1:

// In square.js
const square = function (n) {
  return n * n;
}

module .exports = square

// In squareAll.js
const square = require ('./square')

const squareAll = function (ns) {
  return ns .map (n => square (n))
}

module .exports = squareAll

使用这个主模块:

const squareAll = require ('./squareAll')

console .log (squareAll ([1, 2, 3, 4, 5]))

在外面的require ('./squareAll')上,当我们到达线时

let wrapper = Function("require, exports, module", code);

我们create a new Function看起来像这样:

const wrapper = function (require, exports, module) {
  const square = require ('./square')

  const squareAll = function (ns) {
    return ns .map (n => square (n))
  }

  module .exports = squareAll
}

我们调用这个构造函数,传递require函数、module对象及其exports属性。然后,当调用它的第一行时,它将递归调用require

const square = require ('./square')

并且它将再次使用Function构造函数,调用 that 函数,并将返回square函数,将其赋值给square变量。在外部调用中,我们将使用square函数来定义squareAll,并将其赋值给module.exports,然后返回:

return require.cache[name].exports;

我们的index.js函数现在有一个对squareAll的引用,而squareAll又有一个对square的引用。由于缓存,下次我们require其中之一时,我们将返回已经加载的版本。
这是一个相当优雅的过程。
1是的,这些可以用箭头功能写得更简单。我想,但我想让尽可能多的人理解这一点。

相关问题