繁体   English   中英

何时在 NodeJS 应用程序中加载 .env 变量?

[英]When to load .env variables in NodeJS app?

我正在使用 TypeScript 编写一个简单的 NodeJS Express REST API。 我有一些使用dotenv加载的环境变量。

我在代码中的两个不同阶段访问我的.env变量: index.ts ,这是我的起始文件,以及MyControllerClass.ts文件。 要访问这些变量,代码是process.env.MY_ENV_VAR 要为应用程序加载它们,代码是dotenv.config()

由于我的index.ts文件似乎是我的程序的根目录(我在其中配置了我的应用程序),因此我使用dotenv.config()为程序的其余部分加载我的.env文件。 但是,在我的MyControllerClass.ts文件中,在构造函数中,如果我执行console.log(process.env.MY_ENV_VAR) ,我会得到“ undefined ”。 我可以通过在我的构造函数中添加一个dotenv.config()来解决这个问题(它有效),但在这里拥有它对我来说是无稽之谈。

如何以可读的方式(例如在适当的 .ts 文件中)在我的程序中一劳永逸地使用dotenv.config() ) ? 更一般地说:什么是 NodeJS Express 加载周期?

这是我的代码的文件结构示例

src
├── index.ts
├── Authentication
│   └── authentication.router.ts
│   └── authentication.controller.ts

这是 index.js 的代码

/**
 * Required External Modules
 */
 import * as dotenv from "dotenv";
 import express from "express";
 import cors from "cors";
 import helmet from "helmet";
 import { authenticationRouter } from "./authentication/authentication.router"

 dotenv.config();

 /**
 * App Variables
 */
 if(!process.env.PORT) {
    process.exit(1);
}
const PORT: number = parseInt(process.env.PORT as string, 10);
const app = express();

/**
 *  App Configuration
 */
 app.use(helmet());
 app.use(cors());
 app.use(express.json());
 app.use(authenticationRouter);

 app.use("api/authenticate/", authenticationRouter);
/**
 * Server Activation
 */
 app.listen(PORT, () => {
    console.log(`Listening on port ${PORT}`);
  });

这是authentication.router.ts的代码

import express, { Request, Response } from "express";
import { AuthenticatorController } from "./authentication.controller";
export const authenticationRouter = express.Router();
const authenticatorController = AuthenticatorController.getInstance();

authenticationRouter.post("/api/authenticate", async (req: Request, res: Response) => {   
    try {
        if (await authenticatorController.authenticate(req.body.login, req.body.password)) {
            res.send({"status": "ok"})
        } else
            res.send({"status": "Error"})
    } catch (e) {
        console.debug(e)
        res.send({"status": "500"});
    }
    
});

这是authentication.controller.ts的代码

import { ClientSecretCredential } from "@azure/identity";
import { SecretClient } from "@azure/keyvault-secrets";
import { Authenticator } from "./api/Authenticator";
import * as dotenv from "dotenv";
dotenv.config();

export class AuthenticatorController implements Authenticator {
    
    private static singleInstance: AuthenticatorController | null = null;
    private azureSecretCredential= new ClientSecretCredential(
        process.env.AZURE_TENANT_ID as string,
        process.env.AZURE_CLIENT_ID as string,
        process.env.AZURE_CLIENT_SECRET as string);
    private azureSecretClient = new SecretClient(
        process.env.KEY_VAULT_URL as string,
        this.azureSecretCredential);

    private constructor () {}

    public static getInstance(): AuthenticatorController {
        if (this.singleInstance === null) {
            this.singleInstance = new AuthenticatorController();
        }
        return this.singleInstance;
    }

    public async authenticate(login: string, password: string): Promise<Boolean> {
        let isAuthenticated = false;

        try {
            const secret = await this.azureSecretClient.getSecret(login)
            if (secret.name === login) {
                if (secret.value === password) {
                    isAuthenticated = true;
                }
            }
        }   catch (e) {
            console.debug(e);
        }
            return isAuthenticated;
    }
}

你只调用dotenv.config()一次:

尽早在您的应用程序中,要求并配置 dotenv。

require('dotenv').config()

因此 index.ts 似乎是正确的,然后process.env应该保存您解析的值。 也许您可以使用这样的方法来确保正确解析数据:

const result = dotenv.config();

if (result.error) {
  throw result.error;
}

console.log(result.parsed);

编辑:

您可以尝试以下操作。 我稍微更改了您的导出,因为您的控制器中不需要单例。

authentication.router.ts:

// Imports (no dotenv; no dotenv.config())
// [...]

// Import controller
import { authenticatorController } from "./authentication.controller";

export const authenticationRouter = express.Router();

// Adding routes
// [...]

authentication.controller.ts:

// Imports (no dotenv; no dotenv.config())
// [...]

class AuthenticatorController implements Authenticator {
  // [...]
}

export const authenticatorController = new AuthenticatorController();

索引.ts:

// Imports (dotenv)
// [...]

const { error, parsed } = dotenv.config();

if (error) {
  throw error;
}

console.log(parsed);

// [...]

 app.use("api/authenticate/", authenticationRouter);

// [...]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM