[英]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.