我在遇到这种情况时,使用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();
问题是IAM在我的this.string
中没有获得预期值。实际上,Secret
的新实例似乎并未生成。IAM获取undefined
作为Logger
中environment
变量的结果。我在这里做错了吗?似乎对我有用的唯一方法是,当我将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
中的CC_11和Logger
中的Secret
。如果是这种情况,我什至尝试删除从Secret
导入并使用console.log()
的Logger
。但是,仍然无法按照我想要的方式工作。
是的,这里有一个循环依赖性:
- 在
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
导入记录器,因为记录器需要首先执行此文件的内容。
如果您确实需要交叉引用,则如果您的班级不使用其构造函数互相使用,则它将有效。
无论如何,如果记录仪需要秘密来完成其工作,则您不能要求它在给予该秘密之前。