如何在需要不同路径时重用Node.js模块

sgtfey8w  于 2023-03-22  发布在  Node.js
关注(0)|答案(4)|浏览(97)

我有一个名为 counter 的自定义模块,它被多个其他模块使用。这些其他模块位于不同的目录中,这导致需要具有不同路径的 counter 模块。
下面是简化的设置。

- dir1
-- counter.js
-- module1.js
- dir2
-- module2.js

counter.js

var count = 0;

counter.increment = function(){
  count++;
  console.log(count);
};

module1.js

var counter = require('./counter');
counter.increment(); // Prints 1

module2.js

var counter = require('../dir1/counter')
counter.increment(); // Prints 1, but should print 2

如果使用了相同的include路径,那么 counter 只会被创建一次,并且module1和module2都将使用相同的 counter 模块。但是由于所需的路径不同,因此会创建两个单独的 counter 模块。
有人知道如何防止这种情况吗?我希望只有一个 * 计数器 * 模块。

inkz8wg9

inkz8wg91#

由于您需要每个应用程序的单例,而require()无法知 prop 有两个单独路径的模块实际上是同一个模块,因此我所知道的唯一方法是(而不是删除到模块的单独路径)是让您的模块将一个单例注册为全局,然后在创建另一个单例之前对该单例进行自己的初始化检查。然后,每次加载它时,它只会返回一个指向该单例的导出。

// counter.js
 // if no singleton yet, create the one singleton
 if (!global._counter) {
    global._counter = new Counter();
 }
 // export the singleton
 module.exports = global._counter;

第一次加载require()(无论路径如何)时,它将创建一个单例并将其存储在global._counter变量中。第二次加载时(即使使用不同的路径),它将找到前一个单例并导出相同的单例。因此,只有一个计数器。
这使得所有使用它的代码都将其视为一个真实的的模块,避免在任何地方使用global引用。通常情况下,应该避免使用全局变量,但这是当你想要一个对某个东西的单例引用,而不能使用模块级变量来保存它时(这正是你的情况),全局变量是一件好事。
然后,您可以像使用普通模块一样使用它:

var counter = require('./counter');
counter.increment(); // Prints 1

// in another file
var counter = require('../dir1/counter');
counter.increment(); // Prints 2
ac1kyiln

ac1kyiln2#

一个好的解决方案是只将count变量设为全局变量,而不是将整个模块设为全局变量。
在主文件中-

global.count=0;

在counter.js中

counter.increment = function(){
     count++;
     console.log(count);
};

这样你就不需要更改module1.js和module2.js,甚至对于其他模块,你可以像以前一样使用它。

ghhkc1vu

ghhkc1vu3#

我在我的项目中使用了NODE_PATH环境变量。它的值是,项目的根。然后需要本地模块就变成了需要npm模块。
对于相同的设置,我更改了require语句:
下面是简化的设置。

- dir1
-- counter.js
-- module1.js
- dir2
-- module2.js

counter.js

var count = 0;

exports.increment = function(){
  count++;
  console.log(count);
};

module1.js

var counter = require('dir1/counter');
counter.increment(); // Prints 1

module2.js

var counter = require('dir1/counter')
counter.increment(); // Prints 2

我用NODE_ENV环境变量运行程序。

NODE_ENV=. node
> require('dir1/module1');
1
{}
> require('dir2/module2');
2
{}
>

.表示当前文件夹。

7d7tgy0s

7d7tgy0s4#

这是因为当你导入一个文件时,它会在那里创建一个新的示例,所以在你的每个模块中,它都会以0开始。
解决方案是在主文件中导入全局计数器,并在所有地方使用相同的计数器
在主文件中

global.counter = require('./counter');

在模块文件中

global.counter.increment();

计数器文件可以从任何文件,模块中加载,这并不重要。只需声明一次,并确保在使用增量方法之前加载它。

相关问题