Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA

Aula 2 de 6

Módulos e package.json: organize o projeto Node.js

Separe funções em módulos, entenda export e import e use package.json para registrar scripts e o formato de módulos do seu projeto Node.js.

40 minutos · leitura + prática · nível iniciante

Ao terminar esta aula, você vai conseguir

  • Explicar a responsabilidade de um módulo
  • Exportar e importar funções com ES Modules
  • Configurar type e scripts no package.json
Uma requisição sai do navegador, passa pelo Node.js e volta como JSON.

Um arquivo único resolve o primeiro exercício, mas logo passa a misturar regras, entrada e saída. Um módulo é uma unidade de código com uma responsabilidade e uma interface explícita. Em Node.js, você pode exportar valores de um arquivo e importá-los em outro, sem transformar tudo em variável global.

Imagine uma oficina: uma bancada mede peças, outra monta e outra confere o resultado. Cada bancada entrega algo definido à próxima. Um módulo faz essa separação no programa. O limite da comparação é importante: arquivos não são obrigatoriamente equipes isoladas; módulos ainda dependem uns dos outros, e uma divisão ruim apenas espalha a confusão.

Declare o formato do projeto

Na pasta do projeto, crie um package.json mínimo:

json
{
  "name": "pedidos-node",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "start": "node src/app.js"
  }
}

O package.json descreve o pacote. private reduz o risco de publicação acidental; type: module informa que arquivos .js usam ES Modules; e scripts.start dá um nome estável ao comando. Depois disso, npm start executa node src/app.js. O npm não substitui Node: ele apenas encontra e roda o script declarado.

Exporte uma regra, importe no ponto de entrada

Crie a pasta src. Em src/pedido.js, escreva:

js
export function calcularTotal(itens) {
  return itens.reduce((soma, item) => soma + item.preco, 0);
}

export function pedidoValido(itens) {
  return Array.isArray(itens) && itens.length > 0;
}

Agora crie src/app.js:

js
import { calcularTotal, pedidoValido } from './pedido.js';

const itens = [{ nome: 'Mouse', preco: 90 }, { nome: 'Cabo', preco: 30 }];

if (!pedidoValido(itens)) {
  console.error('Pedido sem itens');
  process.exitCode = 1;
} else {
  console.log(`Total: R$ ${calcularTotal(itens).toFixed(2)}`);
}

Rode npm start. A saída deve ser Total: R$ 120.00. pedido.js concentra regras do domínio; app.js escolhe os dados, chama essas regras e apresenta o resultado. A extensão .js no caminho relativo faz parte da resolução de ES Modules no Node e não deve ser omitida nesse exemplo.

Uma interface pequena reduz acoplamento

Acoplamento é o quanto uma parte conhece detalhes de outra. Se app.js precisasse conhecer todos os passos internos do cálculo, qualquer mudança teria efeito espalhado. Ao importar calcularTotal, ele depende apenas do nome, dos argumentos e do retorno da função. Isso não elimina dependências; torna o contrato visível.

No laboratório, as funções aparecem juntas porque o sandbox executa um único script do navegador. Não estamos simulando import nem package.json. A prática verificável é outra: alterar a taxa afeta o cálculo, enquanto a função de formatação continua igual. Depois você aplica a mesma separação em arquivos no projeto Node real.

Faça também um teste de fronteira: renomeie calcularTotal apenas no módulo e rode o projeto. O erro de importação mostra que o nome exportado pertence ao contrato. Em seguida, atualize a importação e confirme a saída novamente. Esse experimento curto torna a dependência visível. Se uma função só é usada dentro de pedido.js, não a exporte por precaução; manter a superfície pública pequena deixa menos detalhes disponíveis para acoplamento acidental.

Scripts nomeados também padronizam o trabalho da equipe. Uma pessoa não precisa memorizar em qual pasta está o ponto de entrada; ela consulta o manifesto e roda o mesmo comando. Quando você mudar a estrutura interna, ajuste o script uma vez. O nome público pode continuar estável. Essa é outra forma de contrato: detalhes do caminho ficam encapsulados pelo pacote.

Erro comum: misturar CommonJS e ES Modules

Node também suporta CommonJS, com require e module.exports. O erro aparece quando um projeto declara type: module e o código tenta usar require como se nada tivesse mudado. Escolha um sistema conscientemente; nesta trilha usamos import e export. Ao copiar um exemplo antigo, confira primeiro em qual formato ele foi escrito.

Para concluir a missão, extraia validarPedido, importe em app.js e rode npm start. Teste uma lista preenchida e outra vazia. O programa precisa aprovar a primeira e rejeitar a segunda sem duplicar a regra. Na próxima aula, veremos como continuar organizado quando uma operação demora e termina no futuro.

Laboratório ao vivo

Funções separadas por responsabilidade

O sandbox usa um arquivo só. Treine funções independentes: altere a taxa e confirme que calcularTotal muda sem alterar a função que formata a saída.

Pronto para testar
Resultado

Pare e pense

O que o campo type com valor module informa ao Node.js?

Escolha uma resposta
Missão da aula

Faça sem copiar

Extraia uma função validarPedido para pedido.js, importe-a em app.js e crie um script start. A missão passa quando npm start exibe um pedido válido.

Fontes para consultar

Terminou a missão?

Marque apenas quando você conseguir explicar o conceito e concluir o desafio. O progresso fica salvo somente neste navegador.

Próxima: Assincronia no Node.js: Promises, async e event loop →