【问题标题】:Require multiple times需要多次
【发布时间】:2019-02-20 21:48:52
【问题描述】:

文件my_script.js:

(function() {
    console.log("IMPORTED");
})();

调用此文件 (run_me.js) 会导致 IMPORTED 打印两次:

require("./my_script");
require("./my_script");

但是它只打印一次。

如何更改 run_me.js 以便将 IMPORTED 打印到控制台两次。

假设对于这个问题,不能对my_script.js进行更改

【问题讨论】:

  • 为什么要导入两次?你可以my_script打印两次
  • 这个节点是webpack还是其他?
  • @andrewgi 我不想编辑my_script。为这个幽默我
  • @AndyRay Nodejs,检查问题标签

标签: javascript node.js


【解决方案1】:

require() 缓存其结果。因此,第一次需要一个模块时,它的初始化代码就会运行。之后,缓存只是返回 module.exports 的值,而无需再次运行初始化代码。这是 node.js 模块的一个非常理想的特性。

如果您希望代码每次都运行,那么您应该导出一个可以在需要后调用的函数,如下所示:

你的模块:

module.exports = function() {
    console.log("IMPORTED");
}

每次都需要它并运行代码

require("./my_script")();
require("./my_script")();

另外,请注意,没有理由在模块中使用 IIFE。 node.js 模块已经自动包装在一个私有函数中,因此您无需再次执行此操作。


正如您现在在评论中所说(但您的问题没有直接说),如果您根本不想编辑 my_script (这只是解决此问题的错误方法),那么您必须删除node.js 缓存中的模块,然后再次要求它,可以这样完成:

delete require.cache[require.resolve('./my_script')];

我不建议将此作为解决方案。这不是在 node.js 中编码的正确方法。这是一种破解方法。

【讨论】:

  • 不幸的是,我坚持使用不好的方法。感谢您的回答。
  • 为什么这种糟糕的方法如此糟糕?
  • @JoshMcGee - 如果您希望模块是可变的(一遍又一遍地运行自己),那么只需设计一个从函数导出的函数,并根据需要多次调用它。从缓存中删除它只是为了再次运行它是一种黑客行为。这就是现在模块设计的工作方式,并且不能保证较新的 ESM 模块可以以这种方式工作。此外,如果您希望模块具有特定功能,则将该功能构建到模块本身中,而不是尝试破解以使其再次运行其初始化代码。
【解决方案2】:

如果你使用 jest 并且希望每次都运行代码进行测试,你可以使用jest.isolateModules:

jest.isolateModules(() => {
    require("./my_script");
});

jest.isolateModules(() => {
    require("./my_script");
});

【讨论】:

    【解决方案3】:

    我认为不修改myscript.js 文件是不可能的。特别是因为正如您展示的那样,它不会导出任何内容。

    它会在你第一次需要它时执行(这就是为什么你会看到一次“导入”),但是在未来调用 require 时不会发生任何事情,因为返回的“缓存”值(即module.exports)是空的。

    以下是我认为您想要的示例(除了 myscript.js 已被修改)。最大的不同是,在你原来的myscript.js文件中,函数实际上是被执行的,而在下面的例子中,它只是被定义,然后在run_me.js文件中的require调用中实际执行。

    文件myscript.js:

    module.exports = () => console.log("Imported");
    

    文件run_me.js:

    require('myscript.js')(); // note the () at the end which actually calls the function
    require('myscript.js')(); // note the () at the end which actually calls the function
    

    【讨论】:

    【解决方案4】:

    你可以使用这个包,它是一个 npm 模块,每次都会清除缓存并从源代码中加载一个模块。

    https://www.npmjs.com/package/require-uncached

    const requireUncached = require('require-uncached');
    
    require('./foo')();
    //=> 1
    
    require('./foo')();
    //=> 2
    
    requireUncached('./foo')();
    //=> 1
    
    requireUncached('./foo')();
    //=> 1
    

    【讨论】:

      猜你喜欢
      • 2019-09-30
      • 2013-03-30
      • 1970-01-01
      • 2020-07-03
      • 2018-09-04
      • 2011-09-09
      • 2013-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多