NodeJS-由于循环依赖而未定义变量?

问题描述 投票:0回答:2

我正在使用yargs。变量argv似乎是未定义的(请参见logger.ts),尽管我确实知道它确实存在,并且可以很好地进行解析(console.log中的parseArgs.ts)。我怀疑是由于循环依赖性fetchRange-> logger-> parseArgs-> fetchRange

我正确吗?如果是这样,是否意味着如果函数使用命令行参数,我将无法在yargs配置中引用它?

// logger.ts
import winston from "winston";
import { argv } from "./parseArgs";

export const logger = winston.createLogger({
  level: argv.verbosity, // this is undefined!
});

// parseArgs.ts
import yargs from "yargs";
import { fetchRange } from "./fetchRange";

export const argv = yargs
    .command(
        /* Some unimportant stuff */
        argv => {
            fetchRange(strToDate(argv.fromDate), strToDate(argv.toDate));
        }
    ).argv;
console.log(argv) // This is NOT undefined!

// fetchRange.ts
import { logger } from "./logger";

export const fetchRange = async (fromDate: Date, toDate: Date) => {
  /* Some unimportant stuff */
    logger.verbose(`Day ${dateToStr(i)} finished.`);

};

javascript node.js
2个回答
1
投票

我怀疑是由于循环依赖性fetchRange-> logger-> parseArgs-> fetchRange

是的,这是正确的。 parseArgs正在导入fetchRange,而C0正在导入logger,并且该模块确实访问argv.verbosity 之前执行初始化yargs.command(…)argv调用。

至少在首先导入parseArgs时发生。当首先导入fetchRange时,它确实可以工作(但是fetchRange将在parseArgs中未初始化,但这并不重要,因为它不会立即使用)。

因此,您可以保留循环依赖关系,并严格控制将哪个模块用作循环的入口点。或者,您可以使用依赖关系反转,将argv导入删除到logger中,然后在解析命令行参数之后在已经存在的记录器实例上配置详细级别。


0
投票

是的,我在记录方面也遇到了同样的问题。正如亚当建议的那样,您还可以通过导出一个返回记录器并在其中一个模块中调用该函数的函数来懒惰地评估其中一个模块的记录器,如下所示:

// logger.ts
import winston from "winston";
import { argv } from "./parseArgs";

export const logger = winston.createLogger({
  level: argv.verbosity, // this is undefined!
});

export const loggerA = () => logger
// fetchRange.ts
import { loggerA } from "./logger";

export const fetchRange = async (fromDate: Date, toDate: Date) => {
  /* Some unimportant stuff */
    loggerA().verbose(`Day ${dateToStr(i)} finished.`);
};

或者,您必须像Keith所建议的那样退出某个部门。我很确定那是我解决的方法-我的模块之一使用console.log或不使用日志记录。

© www.soinside.com 2019 - 2024. All rights reserved.