<h2>Introdução: Por Que Variáveis de Ambiente Importam</h2>
<p>Variáveis de ambiente são pares chave-valor armazenados no sistema operacional que controlam o comportamento da sua aplicação sem precisar modificar o código. Em JavaScript, especialmente em projetos Node.js, elas são essenciais para separar configurações sensíveis (chaves de API, senhas de banco de dados) do código-fonte. Isso protege seus dados e permite que o mesmo código rode em desenvolvimento, teste e produção com configurações diferentes.</p>
<p>Quando você inicia uma aplicação Node.js, o objeto <code>process.env</code> contém todas as variáveis de ambiente disponíveis. Entender como acessá-las e gerenciá-las é uma habilidade fundamental que diferencia projetos amadores de profissionais.</p>
<h2>Acessando e Configurando Variáveis de Ambiente</h2>
<h3>Leitura Básica com process.env</h3>
<p>O acesso mais direto é através do objeto global <code>process.env</code>. Observe este exemplo prático:</p>
<pre><code class="language-javascript">// src/config.js
const dbHost = process.env.DB_HOST | | 'localhost'; const dbPort = process.env.DB_PORT || 5432;
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('API_KEY não definida. Configure a variável de ambiente.');
}
module.exports = {
database: {
host: dbHost,
port: parseInt(dbPort, 10),
},
apiKey,
};</code></pre>
<p>Use este arquivo em sua aplicação para centralizar todas as configurações. Isso torna fácil identificar quais variáveis são obrigatórias e quais têm defaults sensatos.</p>
<h3>Usando Arquivo .env com dotenv</h3>
<p>Para desenvolvimento local, a biblioteca <code>dotenv</code> carrega variáveis de um arquivo <code>.env</code> automaticamente. Instale com <code>npm install dotenv</code>.</p>
<p>Crie um arquivo <code>.env</code> na raiz do projeto:</p>
<pre><code>DB_HOST=localhost
DB_PORT=5432
DB_USER=admin
DB_PASSWORD=senha123
NODE_ENV=development
API_KEY=sk-abc123xyz</code></pre>
<p>Carregue essas variáveis no início da sua aplicação (antes de qualquer outro código):</p>
<pre><code class="language-javascript">// src/index.js (primeira linha)
require('dotenv').config();
const config = require('./config');
const express = require('express');
const app = express();
app.get('/status', (req, res) => {
res.json({
environment: process.env.NODE_ENV,
database: config.database.host,
});
});
app.listen(3000, () => {
console.log('Servidor rodando em http://localhost:3000');
});</code></pre>
<p><strong>Importante:</strong> Adicione <code>.env</code> ao <code>.gitignore</code> para nunca fazer commit de dados sensíveis:</p>
<pre><code class="language-gitignore">.env
.env.local
.env*.local
node_modules/</code></pre>
<h2>Estruturas de Configuração Avançadas</h2>
<h3>Padrão de Múltiplos Ambientes</h3>
<p>Em projetos profissionais, você pode criar arquivos <code>.env.development</code>, <code>.env.test</code> e <code>.env.production</code>. Controle qual carregar conforme o ambiente:</p>
<pre><code class="language-javascript">// src/loadEnv.js
const path = require('path');
require('dotenv').config({
path: path.resolve(__dirname, ../.env.${process.env.NODE_ENV || 'development'}),
});
require('dotenv').config({
path: path.resolve(__dirname, '../.env'),
override: false, // Não sobrescreve variáveis já definidas
});</code></pre>
<h3>Validação com Zod ou Joi</h3>
<p>Validar configurações na inicialização previne bugs em produção:</p>
<pre><code class="language-javascript">// src/validateConfig.js
const z = require('zod');
const configSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']),
DB_HOST: z.string().min(1),
DB_PORT: z.coerce.number().int().positive(),
DB_USER: z.string().min(1),
DB_PASSWORD: z.string().min(8),
API_KEY: z.string().min(1),
JWT_SECRET: z.string().min(32),
PORT: z.coerce.number().int().positive().default('3000'),
});
const validated = configSchema.parse(process.env);
module.exports = validated;</code></pre>
<p>Execute isso na inicialização. Se alguma variável estiver faltando ou inválida, a aplicação falha imediatamente com mensagens claras:</p>
<pre><code class="language-javascript">// src/index.js
require('dotenv').config();
const config = require('./validateConfig');
console.log(✓ Configuração validada para ${config.NODE_ENV});</code></pre>
<h2>Boas Práticas em Produção</h2>
<h3>Variáveis em Plataformas de Hospedagem</h3>
<p>Em produção, nunca use arquivos <code>.env</code>. Plataformas como Heroku, Vercel e AWS permitem definir variáveis diretamente no painel:</p>
<pre><code class="language-bash"># Heroku CLI
heroku config:set DB_PASSWORD=prodPassword123
heroku config:get DB_PASSWORD</code></pre>
<p>No Docker, use arquivos <code>.env</code> ou passe variáveis ao iniciar o container:</p>
<pre><code class="language-dockerfile">FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
CMD ["node", "src/index.js"]</code></pre>
<pre><code class="language-bash">docker run -e DB_HOST=db.prod.com -e API_KEY=sk-prod123 myapp</code></pre>
<h3>Exemplo Completo com Express</h3>
<pre><code class="language-javascript">// src/index.js
require('dotenv').config();
const config = require('./validateConfig');
const express = require('express');
const app = express();
app.use(express.json());
app.get('/api/status', (req, res) => {
res.json({
status: 'ok',
environment: config.NODE_ENV,
timestamp: new Date().toISOString(),
});
});
app.post('/api/secure', (req, res) => {
const token = req.headers.authorization?.split(' ')[1];
if (token === config.JWT_SECRET) {
return res.json({ message: 'Autenticado' });
}
res.status(401).json({ error: 'Não autorizado' });
});
const PORT = config.PORT;
app.listen(PORT, () => {
console.log(Servidor rodando em porta ${PORT});
console.log(Modo: ${config.NODE_ENV});
});</code></pre>
<h2>Conclusão</h2>
<p>Dominar variáveis de ambiente e configuração em JavaScript é fundamental para construir aplicações profissionais. Os três pontos essenciais são: <strong>(1)</strong> use <code>process.env</code> e <code>dotenv</code> para separar dados sensíveis do código; <strong>(2)</strong> implemente validação rigorosa de configurações na inicialização para falhar rápido e claro; <strong>(3)</strong> nunca commite arquivos <code>.env</code> e sempre passe variáveis via painel em produção, não via arquivos. Com essas práticas, seu código fica seguro, portável e pronto para escalar.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://nodejs.org/api/process.html#process_process_env" target="_blank" rel="noopener noreferrer">Node.js process.env Documentation</a></li>
<li><a href="https://www.npmjs.com/package/dotenv" target="_blank" rel="noopener noreferrer">dotenv - npm package</a></li>
<li><a href="https://zod.dev" target="_blank" rel="noopener noreferrer">Zod - TypeScript-first schema validation</a></li>
<li><a href="https://12factor.net/config" target="_blank" rel="noopener noreferrer">12 Factor App - Config</a></li>
<li><a href="https://owasp.org/www-project-top-ten/" target="_blank" rel="noopener noreferrer">OWASP: Sensitive Data Exposure</a></li>
</ul>