当我遇到这种情况时,我正在使用Typescript编码NodeJS服务器端。我创建了一个类Secret
为我提供了环境变量集。就是这个。
import Logger from './logger';
import dotenv from 'dotenv';
import * as fs from 'fs';
class Secret {
private ENVIRONMENT: string;
public constructor() {
this.setEnvironmentVaribales();
}
private setEnvironmentVaribales(): void {
if (fs.existsSync('.env')) {
Logger.logError('Using .env file to supply config environment variables');
dotenv.config({ path: '.env' });
} else {
Logger.debug('Using .env.mm file to supply config environment variables');
dotenv.config({ path: '.env.mm' });
}
this.ENVIRONMENT = process.env['NODE_ENV'];
}
public get environment(): string {
return this.ENVIRONMENT;
}
}
export default Secret;
然后我将Secret
导入到'Logger
,在此我初始化记录器。这是logger.ts
import * as Winston from 'winston';
import Secret from './secret';
class Logger {
private logger: Winston.Logger;
private secret: string;
public constructor() {
this.secret = new Secret().environment;
console.log(this.secret);
this.initializeLogger();
}
/**
* Initializes the winston logger
*/
private initializeLogger(): void {
this.logger = Winston.createLogger({
transports: [
new (Winston.transports.Console)({
level: Secret.ENVIRONMENT === 'production' ? 'error' : 'debug'
}),
new (Winston.transports.File)({
filename: 'debug.log',
level: 'debug'
})
]
});
if (Secret.ENVIRONMENT !== 'production') {
this.logger.debug('Logging initialized at debug level');
}
}
}
export default new Logger();
问题是我无法在我的this.string
中获得预期的值。实际上,Secret
的新实例似乎没有生成。我得到undefined
作为environment
中Logger
变量的结果。
我在这里做错什么吗?
对我来说唯一可行的方法是将Secret
更改为以这种方式导出。
import Logger from './logger';
import {dotenv} from 'dotenv/config';
import * as fs from 'fs';
if (fs.existsSync('.env')) {
Logger.logError('Using .env file to supply config environment variables');
dotenv.config({ path: '.env' });
} else {
Logger.debug('Using .env.mm file to supply config environment variables');
dotenv.config({ path: '.env.mm' });
}
export const ENVIRONMENT = process.env['NODE_ENV'];
还是阻止它的循环依赖关系。 Logger
中的Secret
和Secret
中的Logger
。如果是这种情况,我什至尝试从Logger
删除Secret
导入并使用console.log()
。但是,仍然无法按照我希望的方式工作。
答案 0 :(得分:1)
是的,这里有一个循环依赖项:
logger.ts
中,导出的成员是Logger
的实例:export default new Logger()
Logger
的构造函数中,实例化类Secret
:new Secret().environment
Secret
的构造函数中,调用成员setEnvironmentVaribales()
,该成员同步使用Logger
的导出实例。您当前的解决方案也无效:
if (fs.existsSync('.env')) {
Logger.logError('Using .env file to supply config environment variables');
dotenv.config({ path: '.env' });
} else {
Logger.debug('Using .env.mm file to supply config environment variables');
dotenv.config({ path: '.env.mm' });
}
export const ENVIRONMENT = process.env['NODE_ENV'];
在这里,Logger
不能包含ENVIRONMENT
的内容,然后再导出。
最好的解决方案是不要从secret.ts
导入记录器,因为记录器需要首先完全执行此文件的内容。
如果您确实需要交叉引用,那么在您的类之间不相互使用构造函数时,它将起作用。
在任何情况下,如果记录器在执行其工作之前需要秘密,则不能要求它在提供该秘密之前就起作用。