Resumo : neste tutorial, você aprenderá sobre os módulos Node.js e entenderá como eles funcionam.
Introdução aos módulos Node.js
Node.js oferece suporte a um sistema de módulos chamado módulos CommonJS por padrão. Posteriormente, ele suporta módulos ES a partir da versão 14.0.0. Este tutorial se concentra nos módulos CommonJS.
Nos módulos CommonJS, o Node.js trata cada arquivo JavaScript como um módulo separado.
Vamos dar um exemplo simples para ver como os módulos funcionam no Node.js.
Criando um novo módulo
Primeiro, crie um novo arquivo chamado logger.js
com o seguinte código:
const error = 'ERROR';
const warning = 'WARNING';
const info = 'INFO';
function log(message, level = info) {
console.log(`${level}: ${message}`);
}
Linguagem de código: JavaScript ( javascript )
O logger.js
contém três constantes e uma função .
A log()
função no logger
módulo aceita dois parâmetros: message
e level
. Se você não passar the level
para a log()
função, o padrão será info
.
No logger.js
módulo, todas as variáveis e funções são privadas. Isso significa que eles são invisíveis e não podem ser usados em outros módulos.
Para utilizar as variáveis e funções de um módulo em outro módulo, é necessário exportá-las no final do logger.js
arquivo:
module.exports.log = log;
module.exports.error = error;
module.exports.info = info;
module.exports.warning = warning;
Linguagem de código: JavaScript ( javascript )
Este código cria novas propriedades no module.exports
objeto e as atribui às variáveis e funções correspondentes.
Além disso, você pode usar nomes diferentes ao exportar os objetos. Por exemplo:
module.exports.fatal = error;
Linguagem de código: JavaScript ( javascript )
Neste caso, outros módulos farão referência à error
constante como fatal
constante.
Agora você está pronto para usar a log()
função e todas as constantes do logger
módulo em outro módulo.
Importando um módulo
Segundo, crie um novo arquivo chamado app.js
que use o logger.js
módulo. Para usar o logger.js
módulo do app.js
, você precisa importar o logger
módulo usando a require()
função:
const logger = require('./logger.js');
Linguagem de código: JavaScript ( javascript )
Ou você pode remover a .js
extensão assim logger.js
:
const logger = require('./logger');
Linguagem de código: JavaScript ( javascript )
Nos bastidores, a require()
função executa o logger.js
arquivo e retorna o exports
objeto. Se a require()
função não conseguir encontrar o arquivo, ocorrerá um erro.
O seguinte mostra os logger
objetos para o console:
const logger = require('./logger');
console.log(logger);
Linguagem de código: JavaScript ( javascript )
Saída:
{
log: [Function: log],
error: 'ERROR',
info: 'INFO',
warning: 'WARNING'
}
Linguagem de código: JavaScript ( javascript )
O logger
objeto contém a log()
função e outras constantes do logger.js
módulo. Você pode referenciá-los da seguinte maneira:
const logger = require('./logger');
logger.log('Node.js module demo 1');
logger.log('Node.js module demo 2', logger.warning);
Linguagem de código: JavaScript ( javascript )
Saída:
INFO: Node.js module demo 1
WARNING: Node.js module demo 2
Linguagem de código: texto simples ( texto simples )
Para tornar o código mais conciso, você pode usar a desestruturação de objetos ao importar um módulo como este:
const { log, error, info, warning } = require('./logger');
Linguagem de código: JavaScript ( javascript )
A desestruturação do objeto atribui as propriedades do exports
objeto retornado pela require()
função às variáveis do lado esquerdo.
Após a desestruturação, você pode usar essas variáveis diretamente:
log('Node.js module demo 1');
log('Node.js module demo 2', warning);
Linguagem de código: JavaScript ( javascript )
Saída:
INFO: Node.js module demo 1
WARNING: Node.js module demo 2
Linguagem de código: JavaScript ( javascript )
Compreendendo a função wrapper do módulo
Antes de o Node.js executar um módulo, ele envolve todo o código dentro desse módulo com um wrapper de função semelhante a este:
(function(exports, require, module, __filename, __dirname) {
// Module code
});
Linguagem de código: JavaScript ( javascript )
Por exemplo, o código do logger.js
módulo antes da execução ficará assim:
(function (exports, require, module, __filename, __dirname) {
const error = 'ERROR';
const warning = 'WARNING';
const info = 'INFO';
function log(message, level = info) {
console.log(`${level}: ${message}`);
}
module.exports.log = log;
module.exports.error = error;
module.exports.info = info;
module.exports.warning = warning;
});
Linguagem de código: JavaScript ( javascript )
Ao fazer isso, o Node.js atinge os seguintes objetivos importantes:
- Mantenha as variáveis de nível superior (
var
,let
econst
) com escopo definido para o módulo em vez do objeto global. - Faça algumas variáveis específicas do módulo, como variáveis globais, por exemplo,
module
eexports
.
Observe que o exports
objeto faz referência a module.exports
:
console.log(module.exports === exports); // true
Linguagem de código: JavaScript ( javascript )
Importando o mesmo módulo várias vezes
Quando você usa a require()
função para incluir um módulo diversas vezes, a require()
função avalia o módulo apenas uma vez na primeira chamada e o coloca em um cache.
Nas chamadas subsequentes, a require()
função usa o objeto exports do cache em vez de executar o módulo novamente.
O exemplo a seguir ilustra como funciona:
Primeiro, crie um novo módulo chamado dblogger.js
que tenha o seguinte código:
console.log('Connected to the DB');
Linguagem de código: JavaScript ( javascript )
Segundo, use a require()
função para incluir o dblogger.js
módulo várias vezes no app.js
:
let dbLogger = require('./dblogger');
dbLogger = require('./dblogger');
Linguagem de código: JavaScript ( javascript )
Saída:
DBLogger is loaded.
Linguagem de código: JavaScript ( javascript )
Neste exemplo, você pode ver a mensagem 'DBLogger is loaded.'
apenas uma vez, não duas. Isso significa que o Node.js avaliou dblogger.js
apenas uma vez.
Resumo
- Nos módulos CommonJS, o Node.js trata um arquivo JavaScript como um módulo.
- Exponha variáveis e funções a outro módulo, atribuindo-as às propriedades do
module.exports
objeto. - O Node.js envolve o código do módulo em uma função wrapper do módulo antes de executá-lo.
- Todas as variáveis, constantes, funções, classes, etc., declaradas em um módulo têm como escopo o módulo, não o escopo global.
- O Node.js executa um módulo apenas uma vez e coloca o resultado no cache para o próximo uso.