我正在使用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.`);
};
我怀疑是由于循环依赖性
fetchRange
->logger
->parseArgs
->fetchRange
是的,这是正确的。 parseArgs
正在导入fetchRange
,而C0正在导入logger
,并且该模块确实访问argv.verbosity
之前执行初始化yargs.command(…)
的argv
调用。
至少在首先导入parseArgs
时发生。当首先导入fetchRange
时,它确实可以工作(但是fetchRange
将在parseArgs
中未初始化,但这并不重要,因为它不会立即使用)。
因此,您可以保留循环依赖关系,并严格控制将哪个模块用作循环的入口点。或者,您可以使用依赖关系反转,将argv
导入删除到logger
中,然后在解析命令行参数之后在已经存在的记录器实例上配置详细级别。
是的,我在记录方面也遇到了同样的问题。正如亚当建议的那样,您还可以通过导出一个返回记录器并在其中一个模块中调用该函数的函数来懒惰地评估其中一个模块的记录器,如下所示:
// 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
或不使用日志记录。