Fundamentos do Node.js

0/23 aulas0%
pratica

Carregando Variáveis de Ambiente com '--env-file' (Node.js CLI)

Aprenda sobre carregando variáveis de ambiente com '--env-file' (node.js cli)

40 min
Aula 5 de 6

Gerenciamento de Dependências e Variáveis de Ambiente: Carregando Variáveis de Ambiente com '--env-file' (Node.js CLI)

Olá, pessoal! 👋 Sejam bem-vindos a mais uma aula do nosso curso de Fundamentos do Node.js. Hoje, vamos mergulhar em um tópico super importante para o desenvolvimento de aplicações robustas e seguras: o gerenciamento de variáveis de ambiente.

Especificamente, exploraremos um recurso nativo e muito útil do Node.js CLI: a flag --env-file. 🚀

1. Introdução: O Problema das Configurações e a Solução das Variáveis de Ambiente

Ao desenvolver aplicações, frequentemente precisamos de configurações que variam entre diferentes ambientes (desenvolvimento, teste, produção). Pense em chaves de API, credenciais de banco de dados, portas de serviço, etc. Hardcodar esses valores diretamente no código é uma péssima prática por diversos motivos:

  • Segurança: Credenciais expostas no código-fonte, especialmente se o código for versionado em repositórios públicos. 🔒
  • Flexibilidade: Alterar uma configuração significa modificar o código e, potencialmente, reimplantar a aplicação. 🔄
  • Manutenção: Dificuldade em gerenciar diferentes configurações para diferentes ambientes. 🤯

A solução padrão para isso são as variáveis de ambiente. Elas permitem que você configure sua aplicação de fora para dentro, injetando valores de configuração no ambiente de execução do processo Node.js.

Tradicionalmente, para carregar variáveis de ambiente de um arquivo .env (um formato popular para armazenar essas variáveis), usávamos pacotes como dotenv. No entanto, o Node.js introduziu a flag --env-file em sua CLI, permitindo carregar esses arquivos de forma nativa, sem a necessidade de uma dependência externa para casos básicos! ✨

Nesta aula prática, vamos aprender como utilizar essa flag, suas vantagens e como integrá-la em nossos projetos.

2. Explicação Detalhada: A Flag --env-file

A flag --env-file do Node.js CLI permite que você especifique um ou mais arquivos que contêm variáveis de ambiente no formato KEY=VALUE. O Node.js irá ler esses arquivos e popular o objeto process.env antes que seu script principal seja executado.

Como funciona?

  1. Criação do Arquivo .env: Você cria um arquivo (geralmente nomeado .env) na raiz do seu projeto com as variáveis de ambiente.

    # .env
    PORT=3000
    DATABASE_URL=mongodb://localhost:27017/myapp_dev
    API_KEY=sua_chave_secreta_aqui
  2. Execução com a Flag: Você executa seu script Node.js passando a flag --env-file e o caminho para o arquivo.

    node --env-file=.env seu_script.js
  3. Acesso no Código: Dentro do seu seu_script.js, você pode acessar as variáveis através de process.env.

    // seu_script.js
    console.log(`Porta do servidor: ${process.env.PORT}`);
    console.log(`URL do banco de dados: ${process.env.DATABASE_URL}`);
    console.log(`Chave da API: ${process.env.API_KEY}`);

Precedência das Variáveis de Ambiente

É crucial entender a ordem de precedência quando você tem múltiplas fontes de variáveis de ambiente:

  1. Variáveis de ambiente passadas diretamente na linha de comando: Ex: PORT=4000 node seu_script.js.
  2. Variáveis de ambiente carregadas via --env-file: A ordem importa aqui. Se você especificar múltiplos --env-file, as variáveis do arquivo mais à direita sobrescreverão as do arquivo mais à esquerda se houver chaves duplicadas.
  3. Variáveis de ambiente já existentes no sistema operacional: Ex: PATH, HOME, etc.

Exemplo de Múltiplos Arquivos:

Você pode ter arquivos para diferentes ambientes:

  • .env.development
  • .env.production
  • .env.local (para configurações locais que não devem ser versionadas)
# Para desenvolvimento, carregando configurações gerais e depois as locais
node --env-file=.env.development --env-file=.env.local seu_script.js
 
# Para produção
node --env-file=.env.production seu_script.js

Neste caso, se PORT estiver definido tanto em .env.development quanto em .env.local, o valor de .env.local prevalecerá.

Vantagens do --env-file

  • Nativo: Não requer instalação de dependências de terceiros, reduzindo o tamanho do node_modules e a superfície de ataque.
  • Performance: As variáveis são carregadas antes da execução do script, sem overhead de require ou inicialização de pacotes.
  • Simplicidade: Para casos de uso básicos de carregamento de .env, é extremamente direto.

Quando usar dotenv vs. --env-file?

Embora --env-file seja ótimo, o pacote dotenv ainda tem seu lugar:

Característica--env-file (Node.js CLI)dotenv (Pacote NPM)
DependênciaNenhuma (nativo do Node.js)Sim (pacote dotenv)
CarregamentoAntes da execução do script (via CLI)Durante a execução do script (via require('dotenv').config())
FlexibilidadeMenor: Caminhos fixos, ordem de precedência via CLIMaior: Pode carregar arquivos dinamicamente, de diferentes locais, baseado em lógica de app
Uso ComumConfigurações simples e estáticas por ambienteConfigurações mais complexas, diferentes arquivos para diferentes NODE_ENV dentro do app, validação de variáveis

Para a maioria dos casos de uso onde você só precisa carregar um ou dois arquivos .env na inicialização, --env-file é a escolha mais elegante e eficiente.

⚠️ Segurança: .env e .gitignore

Nunca, jamais, em hipótese alguma, comite seus arquivos .env com dados sensíveis para o controle de versão (Git)!

Sempre adicione .env (e variações como .env.local, .env.development, etc.) ao seu arquivo .gitignore:

# .gitignore
.env
.env.local
.env.*.local

Em vez disso, você deve fornecer um arquivo .env.example (ou .env.sample) com valores fictícios ou vazios para que outros desenvolvedores saibam quais variáveis são necessárias.

# .env.example
PORT=3000
DATABASE_URL=
API_KEY=

3. Código de Exemplo Oficial (Adaptado da documentação)

A documentação oficial do Node.js sobre --env-file é bem direta. Vamos criar um exemplo prático que simula um pequeno servidor e utiliza variáveis de ambiente.

Estrutura do Projeto

my-app/
├── .env.development
├── .env.production
├── .env.local
└── server.js

📄 Arquivo: .env.development

# .env.development
NODE_ENV=development
PORT=3001
GREETING_MESSAGE="Olá do Ambiente de Desenvolvimento!"
DB_HOST=localhost
DB_PORT=27017

📄 Arquivo: .env.production

# .env.production
NODE_ENV=production
PORT=80
GREETING_MESSAGE="Bem-vindo ao Ambiente de Produção!"
DB_HOST=prod.database.com
DB_PORT=5432

📄 Arquivo: .env.local

Este arquivo simula configurações locais que podem sobrescrever as de desenvolvimento, mas não devem ser versionadas.

# .env.local
PORT=4000 # Sobrescreve a porta de desenvolvimento
DB_HOST=127.0.0.1 # Sobrescreve o host do DB de desenvolvimento

📄 Arquivo: server.js

// server.js
const http = require('http');
 
// Acessando variáveis de ambiente
const NODE_ENV = process.env.NODE_ENV || 'development'; // Default para 'development'
const PORT = process.env.PORT || 3000; // Default para 3000
const GREETING_MESSAGE = process.env.GREETING_MESSAGE || 'Olá, mundo!';
const DB_HOST = process.env.DB_HOST || 'localhost';
const DB_PORT = process.env.DB_PORT || '27017';
 
const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end(`${GREETING_MESSAGE}\n`);
  console.log(`Requisição recebida. Mensagem: "${GREETING_MESSAGE}"`);
});
 
server.listen(PORT, () => {
  console.log(`🚀 Servidor rodando em http://localhost:${PORT}/`);
  console.log(`Ambiente: ${NODE_ENV}`);
  console.log(`Configuração do Banco de Dados: ${DB_HOST}:${DB_PORT}`);
  console.log('--------------------------------------------------');
});
 
// Exemplo de como acessar uma variável que não existe, para mostrar undefined
console.log(`Variável SECURE_TOKEN: ${process.env.SECURE_TOKEN}`);

Como Rodar os Exemplos

Abra seu terminal na pasta my-app/ e execute:

  1. Ambiente de Desenvolvimento (padrão):

    node --env-file=.env.development server.js

    Saída esperada: Porta 3001, Mensagem de Desenvolvimento, DB localhost:27017.

  2. Ambiente de Desenvolvimento com Sobrescrita Local:

    node --env-file=.env.development --env-file=.env.local server.js

    Saída esperada: Porta 4000 (de .env.local), Mensagem de Desenvolvimento, DB 127.0.0.1:27017 (de .env.local).

  3. Ambiente de Produção:

    node --env-file=.env.production server.js

    Saída esperada: Porta 80, Mensagem de Produção, DB prod.database.com:5432.

  4. Sem --env-file (usando defaults do código):

    node server.js

    Saída esperada: Porta 3000, Mensagem "Olá, mundo!", DB localhost:27017.

Experimente acessar http://localhost:<PORTA_DO_SERVIDOR>/ no seu navegador após iniciar o servidor para ver a mensagem.

4. Exercícios/Desafios Práticos

Agora é sua vez de colocar a mão na massa! Crie um novo projeto e siga os desafios abaixo.

🎯 Desafio 1: Configuração Básica de uma Aplicação Express

Neste desafio, você criará uma pequena API com Express e usará --env-file para configurar a porta e uma mensagem de boas-vindas.

Tarefas:

  • Crie um novo diretório de projeto (my-express-app).
  • Inicialize um novo projeto Node.js (npm init -y).
  • Instale o Express (npm install express).
  • Crie um arquivo .env na raiz do projeto com as seguintes variáveis:
    # .env
    APP_PORT=5000
    WELCOME_MESSAGE="Bem-vindo à minha API Express!"
  • Crie um arquivo app.js com o seguinte conteúdo:
    // app.js
    const express = require('express');
    const app = express();
     
    const PORT = process.env.APP_PORT || 3000;
    const MESSAGE = process.env.WELCOME_MESSAGE || 'API rodando!';
     
    app.get('/', (req, res) => {
      res.send(MESSAGE);
    });
     
    app.listen(PORT, () => {
      console.log(`🚀 Servidor Express rodando na porta ${PORT}`);
      console.log(`Mensagem de boas-vindas: "${MESSAGE}"`);
    });
  • Execute a aplicação usando a flag --env-file:
    node --env-file=.env app.js
  • Acesse http://localhost:5000/ no seu navegador e verifique a mensagem.

🎯 Desafio 2: Múltiplos Ambientes e Variáveis Essenciais

Vamos expandir o projeto Express para suportar múltiplos ambientes e garantir que variáveis críticas estejam sempre presentes.

Tarefas:

  • No seu projeto my-express-app, adicione um arquivo .env.test com as seguintes variáveis:
    # .env.test
    APP_PORT=5001
    WELCOME_MESSAGE="API em ambiente de Teste!"
    TEST_DB_CONNECTION_STRING="mongodb://testdb:27017/test_app"
  • Adicione um arquivo .env.production com:
    # .env.production
    APP_PORT=80
    WELCOME_MESSAGE="API em Produção!"
    PROD_DB_CONNECTION_STRING="mongodb://prod-cluster.com/prod_app"
  • Modifique app.js para:
    • Exibir qual ambiente (NODE_ENV) está sendo usado (adicione NODE_ENV=development ou NODE_ENV=production aos seus .env files).
    • Exibir a string de conexão do banco de dados apropriada para o ambiente.
    • Importante: Implemente uma checagem para garantir que APP_PORT e WELCOME_MESSAGE estejam sempre definidos. Se não estiverem, o aplicativo deve logar um erro e sair (process.exit(1)).
  • Crie um .gitignore e adicione .env, .env.development, .env.test, .env.production a ele.
  • Crie um .env.example com as variáveis esperadas (sem valores sensíveis).
  • Execute a aplicação para o ambiente de teste:
    node --env-file=.env.test app.js
  • Execute a aplicação para o ambiente de produção:
    node --env-file=.env.production app.js
  • Tente rodar sem nenhuma flag --env-file (e sem variáveis no sistema) para ver a checagem de variáveis essenciais em ação.

🎯 Desafio 3 (Opcional): Comparando com dotenv

Se você tiver tempo e quiser aprofundar, compare o comportamento com o pacote dotenv.

Tarefas:

  • No seu projeto my-express-app, instale dotenv: npm install dotenv.
  • Crie um novo arquivo .env.local (se ainda não tiver) com:
    # .env.local
    APP_PORT=6000
    OVERRIDE_MESSAGE="Esta mensagem vem do .env.local via dotenv!"
  • Modifique app.js para que ele também use dotenv no início do arquivo:
    // app.js (trecho inicial)
    require('dotenv').config({ path: '.env.local' }); // Carrega .env.local via dotenv
     
    const express = require('express');
    const app = express();
     
    // ... o restante do seu código ...
  • Adicione uma nova rota /override que exiba process.env.OVERRIDE_MESSAGE.
  • Execute a aplicação combinando --env-file e dotenv:
    node --env-file=.env.production app.js
    Observe: Qual APP_PORT e WELCOME_MESSAGE são utilizados? E qual OVERRIDE_MESSAGE?
    • --env-file carrega antes do script.
    • dotenv carrega durante o script.
    • Variáveis carregadas via --env-file terão precedência sobre as que dotenv tenta carregar se elas já existirem em process.env. No entanto, dotenv ainda pode adicionar variáveis que não foram carregadas pelo --env-file.

Este desafio ajuda a entender a ordem de carregamento e a precedência entre as diferentes abordagens.

5. Resumo e Próximos Passos

Nesta aula, exploramos a poderosa flag --env-file do Node.js CLI, uma ferramenta nativa para carregar variáveis de ambiente de arquivos .env.

O que aprendemos:

  • A importância das variáveis de ambiente para a configuração flexível e segura de aplicações.
  • Como usar node --env-file=<caminho/para/arquivo.env> seu_script.js.
  • A precedência das variáveis quando múltiplas fontes são usadas.
  • A diferença entre --env-file e o pacote dotenv.
  • A crucial importância de adicionar arquivos .env ao .gitignore e usar .env.example.

O uso de variáveis de ambiente é uma prática fundamental em qualquer aplicação moderna. Dominar essa técnica garante que suas aplicações sejam mais seguras, configuráveis e fáceis de implantar em diferentes ambientes.

Próximos Passos:

  • Validação de Configuração: Em aplicações maiores, você pode querer usar bibliotecas como joi ou zod para validar se todas as variáveis de ambiente necessárias estão presentes e no formato correto.
  • Gerenciamento de Segredos: Para segredos em produção, considere usar serviços de gerenciamento de segredos como AWS Secrets Manager, Google Secret Manager ou HashiCorp Vault, que injetam as variáveis no ambiente de forma ainda mais segura.
  • Configuração Dinâmica: Para cenários mais complexos onde a configuração pode mudar em tempo de execução ou ser carregada de diferentes fontes (APIs, bancos de dados), você pode construir um módulo de configuração mais avançado.

Continuem praticando e explorando! Até a próxima aula! 👋💻

© 2025 Escola All Dev. Todos os direitos reservados.

Carregando Variáveis de Ambiente com '--env-file' (Node.js CLI) - Fundamentos do Node.js | escola.all.dev.br