Introdução

Neste tutorial, iremos explorar o desenvolvimento de uma aplicação web de gerenciamento de tarefas em tempo real. Utilizando o Node.js, um ambiente de execução JavaScript no servidor, a biblioteca Socket.IO para comunicação em tempo real e o MongoDB para armazenar nossas tarefas, este projeto será uma introdução prática ao desenvolvimento full stack com tecnologias modernas. Através deste guia passo a passo, você aprenderá a configurar seu ambiente de desenvolvimento, criar a estrutura da aplicação e implementar funcionalidades essenciais como adição, listagem e remoção de tarefas. Será um ótimo exercício para quem deseja aprofundar seu conhecimento em JavaScript e desenvolvimento de aplicativos em tempo real.

Etapas

  1. Configuração do Ambiente de Desenvolvimento

    Certifique-se de ter o Node.js e o MongoDB instalados em sua máquina. Para verificar se o Node.js está instalado, rode `node -v` no terminal. Para o MongoDB, você pode usar o MongoDB Atlas ou instalar localmente. Verifique as versiones instaladas usando os comandos `node -v` e `mongo –version`. Caso não tenha o Node.js ou o MongoDB, siga as instruções em seus sites oficiais.

    commands
    # Verificar a versão do Node.js
    node -v
    # Verificar a versão do MongoDB
    mongo --version

  2. Criação do Projeto Node.js

    Crie um novo diretório para sua aplicação e inicialize um projeto Node.js. No terminal, execute `mkdir task-manager` e `cd task-manager`, então execute `npm init -y` para criar um arquivo package.json. Instale as dependências necessárias usando `npm install express socket.io mongoose`. O Express será usado para estruturar nosso servidor, o Socket.IO para a comunicação em tempo real e o Mongoose para interações com o MongoDB.

    commands
    mkdir task-manager
    cd task-manager
    npm init -y
    npm install express socket.io mongoose

  3. Configuração do Servidor Express

    Crie um arquivo chamado `server.js` na raiz do projeto. Neste arquivo, importamos as dependências necessárias e configuramos o servidor Express, bem como a integração do Socket.IO. Adicionamos um endpoint para retornar tarefas.

    server.js
    const express = require('express');
    const http = require('http');
    const socketIo = require('socket.io');
    const mongoose = require('mongoose');
    
    const app = express();
    const server = http.createServer(app);
    const io = socketIo(server);
    
    // Conexão com o MongoDB
    mongoose.connect('mongodb://localhost/task-manager', { useNewUrlParser: true, useUnifiedTopology: true })
      .then(() => console.log('MongoDB conectado'))
      .catch(err => console.log(err));
    
    app.get('/', (req, res) => {
      res.send('API de Gerenciamento de Tarefas');
    });
    
    // Inicialização do servidor
    const PORT = process.env.PORT || 3000;
    server.listen(PORT, () => console.log(`Servidor rodando na porta ${PORT}`));

  4. Definição do Modelo de Tarefa

    Crie uma nova pasta chamada `models` e adicione um arquivo chamado `Task.js`. Neste arquivo, definimos o modelo Mongoose para representar as tarefas, incluindo título e status (concluída ou não).

    models/Task.js
    const mongoose = require('mongoose');
    
    const TaskSchema = new mongoose.Schema({
      title: {
        type: String,
        required: true
      },
      completed: {
        type: Boolean,
        default: false
      }
    });
    
    module.exports = mongoose.model('Task', TaskSchema);

  5. Implementação das Funcionalidades de Tarefas

    Dentro do arquivo `server.js`, vamos implementar as rotas para adicionar, listar e remover tarefas utilizando Socket.IO. Inclua lógica para emitir eventos quando uma tarefa é criada ou removida para que todos os clientes conectados sejam notificados em tempo real.

    server.js
    const Task = require('./models/Task');
    
    // Gerenciamento de tarefas
    io.on('connection', (socket) => {
      console.log('Novo cliente conectado');
    
      // Escutar evento para adicionar tarefa
      socket.on('add_task', async (task) => {
        const newTask = new Task(task);
        await newTask.save();
        io.emit('task_added', newTask);
      });
    
      // Escutar evento para remover tarefa
      socket.on('remove_task', async (taskId) => {
        await Task.findByIdAndDelete(taskId);
        io.emit('task_removed', taskId);
      });
    
      // Emitir todas as tarefas no início
      socket.emit('load_tasks', await Task.find());
    });

  6. Criando a Interface do Usuário

    Crie um arquivo HTML chamado `index.html` na raiz do projeto. Este será o front-end da aplicação onde os usuários poderão adicionar e visualizar tarefas em tempo real. Utilize o Socket.IO no lado do cliente para se conectar ao servidor e escutar eventos.

    index.html
    <!DOCTYPE html>
    <html lang="pt-BR">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Gerenciador de Tarefas</title>
        <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
    </head>
    <body>
        <h1>Gerenciador de Tarefas</h1>
        <input id="task" placeholder="Nova Tarefa" />
        <button id="addTask">Adicionar Tarefa</button>
        <ul id="taskList"></ul>
    
        <script>
            const socket = io();
    
            document.getElementById('addTask').onclick = () => {
              const task = document.getElementById('task').value;
              socket.emit('add_task', { title: task });
              document.getElementById('task').value = '';
            };
    
            socket.on('task_added', task => {
              const li = document.createElement('li');
              li.textContent = task.title;
              document.getElementById('taskList').appendChild(li);
            });
    
            socket.on('load_tasks', tasks => {
              tasks.forEach(task => {
                const li = document.createElement('li');
                li.textContent = task.title;
                document.getElementById('taskList').appendChild(li);
              });
            });
        </script>
    </body>
    </html>

  7. Executando a Aplicação

    Com tudo configurado, agora você pode iniciar o servidor. Execute `node server.js` no terminal. Abra seu navegador e vá para `http://localhost:3000`. Aplique alguns testes adicionando e removendo tarefas no front-end. Veja a atualização em tempo real utilizando múltiplas abas do navegador.

    commands
    # Iniciando o servidor
    node server.js

  8. Implementação de Testes Unitários

    Adicione um arquivo chamado `test.js` para implementar testes básicos de unidade utilizando a biblioteca Mocha e Chai. Certifique-se de que as dependências estão instaladas com `npm install mocha chai –save-dev`.

    test.js
    const chai = require('chai');
    const expect = chai.expect;
    const Task = require('./models/Task');
    const mongoose = require('mongoose');
    
    describe('Task Model', () => {
      before(async () => {
        await mongoose.connect('mongodb://localhost/task-manager', { useNewUrlParser: true, useUnifiedTopology: true });
      });
    
      it('deve criar uma nova tarefa', async () => {
        const task = new Task({ title: 'Testar Tarefa' });
        await task.save();
        expect(task.title).to.equal('Testar Tarefa');
      });
    
      after(async () => {
        await mongoose.connection.close();
      });
    });

  9. Executando os Testes

    Finalmente, execute seus testes de unidade utilizando o Mocha. No terminal, rode `npx mocha test.js` para verificar se tudo está funcionando corretamente.

    commands
    # Executando os testes
    npx mocha test.js

Conclusão

Neste tutorial, você aprendeu a construir uma aplicação de gerenciamento de tarefas em tempo real utilizando Node.js, Socket.IO e MongoDB. Desde a criação da estrutura do projeto até a implementação das funcionalidades front-end e back-end, bem como a realização de testes unitários, você desenvolveu uma aplicação completa. Essa experiência permite que você se familiarize com tecnologias modernas e conceitos de desenvolvimento web, preparando-o para desafios maiores em suas futuras aplicações.

Hashtags

#NodeJS #SocketIO #MongoDB #JavaScript #DesenvolvimentoWeb #RealTime