Pourquoi Deployer Express sur Heroku ?
Deployer une application Express sur Heroku permet aux développeurs de déployer leurs applications web en production sans avoir à gérer les infrastructures serveur. Cela permet un déploiement rapide et flexible, avec des options de mise à l'échelle automatique.
Un cas d'usage concret : Vous avez développé une application de gestion de tâches personnelle qui nécessite d'être accessible en ligne 24/7. En déployant cette application sur Heroku, vous pouvez garantir que votre application est toujours disponible et évitez les problèmes liés à la gestion des serveurs.
Prerequis
- Connaissance intermédiaire de JavaScript et Node.js
- Familiarité avec le terminal et les commandes Unix/Linux
- Installation d'Node.js et npm (https://nodejs.org/)
- Création d'un compte Heroku (https://signup.heroku.com/)
Concepts fondamentaux
1. Projet Express Initial
Un projet Express initial comprend les fichiers suivants :
myapp/
├── app.js
├── package.json
└── public/
└── index.html
app.js est le fichier principal de l'application, où vous définissez les routes et la configuration de votre application.
2. Installation des Dépendances
Pour créer un nouveau projet Express, nous commençons par initialiser un nouveau projet Node.js et installer Express.
## Créer un nouveau dossier pour le projet
mkdir myapp
cd myapp
## Initialiser un nouveau projet Node.js
npm init -y
## Installer Express
npm install express
3. Configuration de l'Application
Créons un fichier app.js avec le contenu suivant :
// app.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
4. Configuration de package.json
Ajoutez un script start dans le fichier package.json pour démarrer l'application :
{
"name": "myapp",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.18.2"
}
}
Mise en pratique : projet fil rouge
Mini-projet complet : Gestionnaire de Tâches
Étape 1 : Initialisation du Projet
mkdir task-manager
cd task-manager
npm init -y
npm install express body-parser
Étape 2 : Création des Fichiers
Créez les fichiers suivants :
touch app.js package.json public/index.html models/taskModel.js routes/tasksRoutes.js
Étape 3 : Configuration de l'Application
app.js :
// app.js
const express = require('express');
const bodyParser = require('body-parser');
const tasksRoutes = require('./routes/tasksRoutes');
const app = express();
const port = process.env.PORT || 3000;
app.use(bodyParser.json());
app.use(express.static('public'));
app.use('/api/tasks', tasksRoutes);
app.listen(port, () => {
console.log(`Task Manager listening at http://localhost:${port}`);
});
Étape 4 : Création des Modèles et Routes
models/taskModel.js :
// models/taskModel.js
const mongoose = require('mongoose');
const taskSchema = new mongoose.Schema({
title: String,
description: String,
completed: Boolean
});
module.exports = mongoose.model('Task', taskSchema);
routes/tasksRoutes.js :
// routes/tasksRoutes.js
const express = require('express');
const Task = require('../models/taskModel');
const router = express.Router();
router.get('/', async (req, res) => {
try {
const tasks = await Task.find();
res.json(tasks);
} catch (error) {
res.status(500).json({ message: error.message });
}
});
router.post('/', async (req, res) => {
const task = new Task({
title: req.body.title,
description: req.body.description,
completed: false
});
try {
const newTask = await task.save();
res.status(201).json(newTask);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
module.exports = router;
Étape 5 : Création de l'Interface Utilisateur
public/index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Task Manager</title>
</head>
<body>
<h1>Task Manager</h1>
<form id="taskForm">
<input type="text" id="title" placeholder="Title">
<textarea id="description" placeholder="Description"></textarea>
<button type="submit">Add Task</button>
</form>
<script>
const taskForm = document.getElementById('taskForm');
const tasksList = document.getElementById('tasks');
async function fetchTasks() {
const response = await fetch('/api/tasks');
const tasks = await response.json();
renderTasks(tasks);
}
async function addTask(event) {
event.preventDefault();
const title = document.getElementById('title').value;
const description = document.getElementById('description').value;
const task = {
title,
description
};
await fetch('/api/tasks', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(task)
});
fetchTasks();
}
function renderTasks(tasks) {
tasksList.innerHTML = '';
tasks.forEach(task => {
const li = document.createElement('li');
li.textContent = task.title;
tasksList.appendChild(li);
});
}
taskForm.addEventListener('submit', addTask);
fetchTasks();
</script>
</body>
</html>
Étape 6 : Lancement de l'Application
npm start
Ouvrez votre navigateur et accédez à http://localhost:3000. Vous devriez voir la liste des tâches et pouvoir ajouter de nouvelles tâches.
Erreurs frequentes et debugging
1. Erreur : Cannot find module 'express'
// ❌ Mauvais
const express = require('express');
// ✅ Correct
const express = require('express');
2. Erreur : listen EADDRINUSE: address already in use
// ❌ Mauvais
app.listen(3000, () => {
console.log('Server started on port 3000');
});
// ✅ Correct
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
3. Erreur : SyntaxError: Unexpected token '<' in JSON at position 1
// ❌ Mauvais
res.json('Not found');
// ✅ Correct
res.status(404).json({ message: 'Not found' });
Pour aller plus loin
1. Authentification avec JWT
Ajoutez une authentification basée sur les jetons JSON Web Tokens (JWT) pour sécuriser votre application.
2. Stockage des Tâches dans une Base de Données MongoDB
Utilisez MongoDB en tant que base de données pour stocker et récupérer les tâches.
3. Intégration avec React ou Vue.js
Intégrez votre backend Express avec un frontend React ou Vue.js pour une application web complète.
Défi pratique
Développez une API simple pour un service de notes (notes manager) en utilisant Express et MongoDB. Créez des routes pour créer, lire, mettre à jour et supprimer des notes.