Node.js中Winston重复声明问题:如何使用winston.info日志?
问题说明
未在index.js中声明winston,但在index.js引入的其他文件(如startup/logging.js)内声明了该变量。尝试声明并使用winston时,触发"winston already declared"语法错误;不声明直接使用时,错误仍存在。报错详情:
C:\Users\Thanushik Saravanan\node-training\first-app\startup\logging.js:2
const winston = require('winston');
^
SyntaxError: Identifier 'winston' has already been declared
at wrapSafe (node:internal/modules/cjs/loader:1378:20)
at Module._compile (node:internal/modules/cjs/loader:1428:41)
at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
at Module.load (node:internal/modules/cjs/loader:1288:32)
at Module._load (node:internal/modules/cjs/loader:1104:12)
at Module.require (node:internal/modules/cjs/loader:1311:19)
at require (node:internal/modules/helpers:179:18)
at Object. (C:\Users\Thanushik Saravanan\node-training\first-app\index.js:6:1)
at Module._compile (node:internal/modules/cjs/loader:1469:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
Node.js v20.18.0
解决步骤
1. 排查重复声明来源
报错核心是依赖链中某模块已用const/let声明过winston,后续代码重复声明了同名变量:
- 检查
index.js的所有引入文件,确认是否有多个文件执行const winston = require('winston');,且其中某文件将winston挂载到了global全局对象。 - 检查
logging.js内部是否存在多次声明winston的代码,或该文件是否被重复引入。
2. 用单例模式统一管理Winston实例
这是最规范的解决方案,避免重复声明和实例化:
- 在
startup/logging.js中声明并配置Winston,然后导出实例:
// startup/logging.js const winston = require('winston'); // 配置日志(示例:控制台输出JSON格式日志) const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [new winston.transports.Console()] }); module.exports = logger;
- 在
index.js或其他需要日志的文件中,直接引入导出的实例,无需再次require('winston'):
// index.js const logger = require('./startup/logging'); // 调用日志方法 logger.info('业务日志内容');
3. 修复全局变量污染问题
若某文件误将winston挂载到global(如global.winston = require('winston')),后续声明同名变量会触发报错:
- 删除全局挂载代码,改用上述单例导出方式。
- 若必须保留全局变量,直接通过
global.winston.info()调用,不要重新声明变量。
4. 消除模块循环依赖
如果index.js和logging.js存在循环引入(A引入B,B又引入A),也会导致变量声明异常:
- 拆分公共代码,调整模块结构,彻底消除循环依赖。
内容的提问来源于stack exchange,提问作者Thanusik Saravanan

