导入的打字稿类的实例化似乎不起作用



我在遇到这种情况时,使用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作为Loggerenvironment变量的结果。我在这里做错了吗?似乎对我有用的唯一方法是,当我将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导入记录器,因为记录器需要首先执行此文件的内容。

如果您确实需要交叉引用,则如果您的班级不使用其构造函数互相使用,则它将有效。

无论如何,如果记录仪需要秘密来完成其工作,则您不能要求它在给予该秘密之前。

相关内容

最新更新