Configurações
Outra funcionalidade básica de qualquer aplicação é a capacidade de carregar as configurações dinamicamente. As configurações podem ser: definição do ambiente de execução (development
, staging
, test
, production
, respectivamente desenvolvimento
, homologação
, testes
, produção
), definição da porta de comunicação do servidor web, detalhes da conexão com o banco de dados, entre outras.
Essas configurações não devem ser informadas diretamente no código-fonte, elas devem ser carregadas dinamicamente durante a inicialização da aplicação para que os valores sejam compartilhados entre os módulos.
No Node.js, essas configurações são informadas através de variáveis de ambientes e carregadas pela aplicação através do objeto process.env
.
Dotenv
Dotenv é uma ferramenta que carrega as variáveis de ambiente dinamicamente do arquivo .env
e disponibiliza os valores no objeto process.env
.
Para mais informações sobre o Dotenv, acesse https://www.npmjs.com/package/dotenv.
Instalando o Dotenv
Para instalar o Dotenv, abra o Terminal e digite:
$ npm i dotenv
Esse comando instala o Dotenv como dependência no package.json
.
"dependencies": {
"dotenv": "6.0.0"
},
Utilizando o Dotenv
Para utilizar o Dotenv no projeto, crie o arquivo .env
.
NODE_ENV = development
Nesse arquivo estamos definindo a variável de ambiente NODE_ENV
com o valor development
.
Para utilizar as variáveis de ambiente na aplicação, edite o arquivo index.js
.
require('dotenv').config();
const logger = require('./logger');
logger.info('Hello dotenv');
logger.info(`NODE_ENV: ${process.env.NODE_ENV}`);
Executando a aplicação, a seguinte informação é exibida no Terminal.
info: Hello dotenv
info: NODE_ENV: development
Centralizando as configurações
Da mesma maneira como fizemos com o módulo de registro de aplicações, é importante separar as configurações em um módulo separado. Os benefícios do módulo de configurações são:
- Centralizar as informações das configurações
- Testar se todas as configurações foram informadas antes de iniciar a aplicação
- Possibilidade de trocar a biblioteca de configurações
Restringindo as configurações
O primeiro passo para garantir que as configurações sejam disponibilizadas apenas pelo módulo de configurações, é adicionar um regra no ESLint para não permitir o uso do objeto process.env
.
Para adicionar a regra no ESLint, edite o arquivo .eslintrc.json
.
{
"extends": ["airbnb-base", "plugin:prettier/recommended"],
"env": {
"es6": true
},
"rules": {
"no-process-env": "error"
}
}
Para realizar a análise estática na aplicação, abra o Terminal e digite:
$ npm run lint
O resultado da análise estática apresenta 01 erro.
/src/index.js
6:26 error Unexpected use of process.env no-process-env
✖ 1 problem (1 error, 0 warnings)
Dica
A extensão ESLint do VS Code sublinha o código-fonte em vermelho e sinaliza que o uso do objeto process.env
não é permitido.
Pronto, acabamos de restringir o uso do objeto process.env
. Agora precisamos centralizar as configurações em um módulo.
Criando o módulo de configurações
Para criar o módulo de configurações, crie o arquivo config.js
.
// importar o dotenv e carregar as configurações do arquivo .env
require('dotenv').config();
// definir as variáveis de ambiente obrigatórias
const environment = ['NODE_ENV'];
// percorrer as variáveis de ambiente obrigatórias
// e disparar um erro caso alguma delas não seja informada
environment.forEach((name) => {
if (!process.env[name]) {
throw new Error(`${name}: ${process.env[name]}`);
}
});
// exportar um objeto com as configurações
module.exports = {
NODE_ENV: process.env.NODE_ENV
};
Realize a análise estática mais uma vez para ver o resultado. Para realizar a análise estática, abra o Terminal e digite:
$ npm run lint
O resultado da análise estática apresenta 04 erros.
/src/config.js
6:8 error Unexpected use of process.env no-process-env
7:33 error Unexpected use of process.env no-process-env
12:13 error Unexpected use of process.env no-process-env
/src/index.js
6:26 error Unexpected use of process.env no-process-env
✖ 4 problems (4 errors, 0 warnings)
Como o módulo config
é o único módulo em que é permitido utilizar process.env
, nós precisamos criar uma exceção no ESLint. Para criar uma exceção no ESLint e permitir o uso do objeto process.env
apenas no módulo config
, adicione a seguinte linha no começo do arquivo config.js
.
/* eslint no-process-env: 0 */
Realize a análise estática mais uma vez para ver o resultado. Para realizar a análise estática, abra o Terminal e digite:
$ npm run lint
O resultado da análise estática apresenta apenas 01 erro.
/src/index.js
6:26 error Unexpected use of process.env no-process-env
✖ 1 problem (1 error, 0 warnings)
Utilizando o módulo de configurações
Para utilizar o módulo de configurações na aplicação, edite o arquivo index.js
.
// importar os módulos de configurações e registro de aplicações
const config = require('./config');
const logger = require('./logger');
// exibir Hello dotenv
logger.info('Hello dotenv');
// exibir NODE_ENV: development
logger.info(`NODE_ENV: ${config.NODE_ENV}`);
Vamos entender detalhadamente o que será executado:
- A aplicação inicia e importa os módulos de configurações e registro de aplicações.
- Quando o módulo de configurações é importado, ele utiliza o
dotenv
para carregar as variáveis de ambiente do arquivo.env
e disponibiliza os valores no objetoprocess.env
. - O módulo de configurações verifica se as variáveis de ambiente obrigatórias foram informadas, caso contrário o módulo dispara um erro.
- O módulo de configurações exporta um objeto que contém a propriedade
NODE_ENV
com o valor deprocess.env.NODE_ENV
. - A aplicação utiliza o módulo de registro de aplicações para exibir o valor de
NODE_ENV
, que está definido comodevelopment
no arquivo.env
.
Realize a análise estática mais uma vez para ver o resultado. Para realizar a análise estática, abra o Terminal e digite:
$ npm run lint
O resultado da análise estática não apresenta erros.
Mundo Real
Informar as configurações diretamente no código-fonte pode gerar problemas de segurança. Um exemplo seria se os detalhes de conexão com o banco de dados estivessem expostos no código-fonte, qualquer desenvolvedor com acesso ao código, teria acesso ao banco de dados.
Protegendo as configurações
As configurações carregam informações sensíves (secretas) da aplicação e devem ser protegidas. O arquivo .env
não deve ser enviado ao controle de versão para que essas informações não sejam reveladas.
Dica
O arquivo .gitignore
, responsável por excluir arquivos e diretórios do controle de versão, já está configurado para ignorar o arquivo .env
.
O carregamento das configurações para o ambiente de produção será abordado no Módulo de Implantação.
Dica
Uma boa prática é adicionar um exemplo do arquivo .env
no README
do projeto para auxiliar outros desenvolvedores. Essa etapa será abordada no Módulo de Documentação.
Resumo
- Implementamos o módulo de configurações
- Entendemos a utilidade da análise estática, além de criar regras e exceções para o ESLint
- Entendemos a importância de não utilizar certas informações direto no código-fonte
- Entendemos a importância de não versionar o arquivo
.env