Un site web avec Node.js

Un site web avec Node.js

nodejsPublié il y a un an

Sommaire

Si vous avez déjà essayé de chercher un tutoriel sur les internets de comment faire un site web avec Node.js, vous avez très certainement vu l'utilisation d'un framework, et plus spécifiquement ExpressJS.

Ici sur Bout de code on essaie de ne pas utiliser de framework ou de librairie dans la mesure du possible, et réinventer la roue ça nous fait pas peur 💪 !

C'est pourquoi nous allons voir ensemble comment créer un petit site web avec Node.js vanilla, comme disent les jeunes.

Pour ce faire on va avoir besoin de … Node.js bien entendu, mais surtout de son module http. Car oui Node.js est capable, tout seul comme un grand, de comprendre une requête HTTP, la lire et y répondre. Et tout cela en quelques lignes 😎

// index.js

// On récupère le module http
const http = require('http');

const httpServer = http.createServer();

// On écoute sur le port 8080
httpServer.listen(8080);

On exécute notre fichier via le terminal…

$ node index.js

Et voilà 🎉 ! Comme je le disais, créer un serveur HTTP avec Node.js ce n'est vraiment pas compliqué, c'est tellement simple que si on accède avec notre navigateur sur http://localhost:8080 nous obtenons une jolie page blanche.

En effet, on a créé un serveur HTTP, mais nous n'avons rien dit au serveur sur ce qu'il doit faire lorsque quelqu'un le contacte. Ajoutons donc un peu de logique.

// index.js

const http = require('http');

const httpServer = http.createServer();

httpServer.on('request', (request, response) => {
    // On écrit le corps de la réponse
    response.end('<h1>Hello world!</h1>');
});

httpServer.listen(8080);

Bien maintenant si on accède avec notre navigateur sur http://localhost:8080 on obtient un message hello world. Ce qui est bien mais pas top, une véritable page HTML serait idéale.

Pour ce faire nous allons utiliser un autre module de Node.js, fs pour File System ou système de fichiers.

// index.js

const http = require('http');

// On récupère le module fs
const fs = require('fs');

const httpServer = http.createServer();

httpServer.on('request', (request, response) => {
    // On définit le code de retour à 200
    response.statusCode = 200;

    // On spécifie que l'on retourne du HTML
    response.setHeader('Content-Type', 'text/html');

    // On branche le flux du contenu de index.html à la réponse
    fs.createReadStream('/path/to/index.html').pipe(response);
});

httpServer.listen(8080);

Cette fois lorsqu'on accède à http://localhost:8080 on obtient bien une vraie page HTML. Joie 😎

ℹ️ Une remarque sur le code : on préférera envoyer un fichier via un flux (createReadStream) de cette façon on envoie morceau par morceau et non pas la totalité du fichier d'un coup, ce qui consomme moins de RAM et ça c'est bon pour nos machines 🖥️.

On continue, on a vu comment répondre une page HTML lorsque l'on accède à http://localhost:8080, mais que se passe-t-il si l'on veut accéder à http://localhost:8080/about ? Et bien la même chose que pour la route /. En effet nous renvoyons toujours le même contenu pour n'importe quelle route. Il va falloir remédier à cela.

// index.js

const http = require('http');
const fs = require('fs');

const httpServer = http.createServer();

httpServer.on('request', (request, response) => {
    // On vérifie que la route demandée est bien "/"
    if (request.url === '/') {
        response.statusCode = 200;
        response.setHeader('Content-Type', 'text/html');
        fs.createReadStream('/path/to/index.html').pipe(response);

    // Ou si c'est "/about"
    } else if (request.url === '/about') {
        response.statusCode = 200;
        response.setHeader('Content-Type', 'text/html');
        fs.createReadStream('/path/to/about.html').pipe(response);

    // Sinon, Oups erreur 404
    } else {
        response.statusCode = 404;
        response.end('Not found.');
    }
});

httpServer.listen(8080);

Nous nous retrouvons maintenant avec trois possibilités, soit on demande la route /, soit la route /about, soit nous renvoyons une 404. Nous venons, tout simplement, de faire un routeur. Un routeur grossier certes, mais un routeur quand même !

Après ça, je sens que vous bouillonnez de vouloir rendre le tout dynamique et vous avez raison. Un if else c'est bien joli mais quand on a un site avec 10, 100 voir 1000 routes, ça devient vite ingérable !

À vous maintenant de compléter cette base pour créer votre propre framework Node.js 😉


ℹ️ Nous n'avons pas vu comment traiter les données pouvant être envoyées par un client. Sachez que pour des données contenues dans l'URL: le module url de Node.js vous permet d'extraire les informations d'une URL.

const url = require('url');

url.parse('/status?name=ryan');
/*
{
  href: '/status?name=ryan',
  search: '?name=ryan',
  query: 'name=ryan',
  pathname: '/status'
}
*/

Concernant le contenu dans la requête HTTP, c'est déjà plus compliqué et je vous renvoie sur mes travaux https://github.com/kevinbalicot/yion

Commentaire(s) 

Ancun commentaire pour le moment.