Base de bot de discordConvenções

Env

Carregando variáveis de ambiente nativamente

Arquivo env

Com as versões mais recentes do NodeJs nós podemos usar a flag --env-file para indicar um arquivo de variáveis de ambiente para o nosso projeto

node --env-file .env ./dist/index.js

O Bun lê automaticamente o arquivo .env se existir na raiz do projeto, mas também é possível usar a flag --env-file para indiciar manualmente um arquivo de variáveis de ambiente para o nosso projeto

bun --env-file .env ./src/index.ts

Iniciando o projeto com essa flag no script, o objeto process.env vai conter todas as variáveis definidas no arquivo .env da raiz do projeto.

Você pode ter dois arquivos env no seu projeto e escolher qual usar atráves dos scripts pré-definidos

package.json
{
  // ...
  "scripts":{
    "dev": "tsx --env-file .env ./src/index.ts",
    "dev:dev": "tsx --env-file .env.dev ./src/index.ts",
  }
}

Se você tem um arquivo .env.dev você pode executar o script dev:dev

npm run dev:dev

Isso é o mesmo para todos os outros scripts

npm run start:dev
npm run watch:dev

Assim você pode ter variáveis de ambiente de desenvolvimento e de produção

Validando variáveis de ambiente

Com zod, podemos criar uma schema para o objeto de variáveis de ambiente de validar antes do projeto iniciar, assim garantindo que as informações estão corretas e também fornecendo para o intelisense um auto completar das variavéis que possuímos, veja:

src/env.ts
import { validateEnv } from "#base";
import { z } from "zod";

export const env = validateEnv(z.object({
    BOT_TOKEN: z.string("Discord Bot Token is required").min(1),
    WEBHOOK_LOGS_URL: z.url().optional()
}));

Quando precisar usar as variavéis de ambiente validadas e transformadas, apenas importe env de #env:

import { env } from "#env";

console.log(env.BOT_TOKEN);

Você pode definir o mínimo de caracteres, o formato, se deve ser url, email, restringir valores, converter para outros tipos, veja alguns exemplos abaixo:

src/env.ts
import { validateEnv } from "#base";
import { z } from "zod";

export const env = validateEnv(z.object({
    BOT_TOKEN: z.string("Discord Bot Token is required").min(1),
    DATABASE_URL: z.url("Database URL is required"), 
    WEBHOOK_LOGS_URL: z.url().optional()
});
src/env.ts
import { validateEnv } from "#base";
import { z } from "zod";

export const env = validateEnv(z.object({
    BOT_TOKEN: z.string("Discord Bot Token is required").min(1),
    USER_EMAIL: z.email(), 
    USER_PASSWORD: z.string().min(8), 
    WEBHOOK_LOGS_URL: z.url().optional()
});
src/env.ts
import { validateEnv } from "#base";
import { z } from "zod";

export const env = validateEnv(z.object({
    BOT_TOKEN: z.string("Discord Bot Token is required").min(1),
    HOST: z.url(), 
    PORT: z.coerce.number(), 
    WEBHOOK_LOGS_URL: z.url().optional()
});

Com isso em mente, ao trabalhar com mais ferramentas ou bibliotecas que necessitem de informações sensíveis armazenadas no arquivo .env, basta acrescenter no schema, as validações necessárias.