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

时间:2019-02-21 08:35:23

标签: javascript typescript

当我遇到这种情况时,我正在使用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作为environmentLogger变量的结果。 我在这里做错什么吗? 对我来说唯一可行的方法是将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中的SecretSecret中的Logger。如果是这种情况,我什至尝试从Logger删除Secret导入并使用console.log()。但是,仍然无法按照我希望的方式工作。

1 个答案:

答案 0 :(得分:1)

是的,这里有一个循环依赖项:

  • logger.ts中,导出的成员是Logger的实例:export default new Logger()
  • 在类Logger的构造函数中,实例化类Secretnew 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导入记录器,因为记录器需要首先完全执行此文件的内容。

如果您确实需要交叉引用,那么在您的类之间不相互使用构造函数时,它将起作用。

在任何情况下,如果记录器在执行其工作之前需要秘密,则不能要求它在提供该秘密之前就起作用。