调用require不会返回相同的对象

问题描述:

我知道模块加载是如何加载假设在node.js中工作,但我没有观察到正确的行为(并且它看起来实际上看起来有点不一致调用require不会返回相同的对象

使用8.2.1的NodeJS上this answer的评论),我有以下结构:

app 
| 
+ server.js 
+ log 
| | 
| + index.js 
+ db 
    | 
    + index.js 

在server.js,我打电话require('./log'),并在/log/index.js,我require('winston')和配置它是这样的:

let logger = new (winston.Logger)({ 
    transports: [ 
    new (winston.transports.Console)({ 
     name: 'console', 
     level: logLevel, 
     handleExceptions: true, 
     json: false, 
     colorize: process.env.NODE_ENV === 'dev', 
     timestamp: true 
    }) 
    ] 
}); 

根据this answer,我应该可以从任何其他模块只require('winston'),我会得到相同的配置实例。我实际看到的是,当我require('winston')db/index.js中时,默认的winston实例在内存中,根本没有配置。我也通过了require.cache;没有其他模块被添加到缓存中,所以据我所知,如果缓存工作正常,则应该返回相同的配置实例。我已验证log/index.js中的代码在db/index.js中的模块正在加载之前正在调用。

任何想法?我应该在所有依赖模块中使用require我的./log模块吗?

+1

不应该需要配置的记录器吗? – Icepickle

任何想法?我应该只需要我的所有依赖模块中的./log模块?

是的,你应该。就像你说的,当你需要一个父模块已经需要的模块时,你正在访问同一个对象。但实际上,在winston中,你正在导入一个构造函数(实际上,为了配置它,你需要定义一个名为logger的变量,并且创建一个新的winson记录器)。

您应该只从原木/ index.js出口记录器(和使用const反而让)

const logger = new (winston.Logger)({ ... }) 
module.exports = logger 

在另一个模块中,你可以做

const logger = require('./log/index.js') // './log' is the same 

记录器将永远是相同的对象:)

是的,你应该是require./log文件,因为你正在创建一个Winston的新实例。你的日志文件应该在你创建它的温斯顿记录器实例的东西,如出口:

let logger = new (winston.Logger)({ 
    transports: [ 
    new (winston.transports.Console)({ 
     name: 'console', 
     level: logLevel, 
     handleExceptions: true, 
     json: false, 
     colorize: process.env.NODE_ENV === 'dev', 
     timestamp: true 
    }) 
    ] 
}); 
module.exports = logger 

然后在你的其他代码,您可以:

const logger = require('./log') 

,并得到相同的实例。

+0

节点8x中的模块缓存有所改变吗? – BrDaHa

+0

没有模块仍然被缓存。当你创建一个'new'实例时,你并没有改变默认实例,你正在创建一个新实例。所以你需要导出。如果您只是导入Winston,您将获得默认值,而不是您创建和配置的默认值。 –