Next.js vs Create React App (CRA)

La situation est complexe dans l’écosystème Javascript, vous devez tout d’abord déterminer le framework que vous allez utiliser. Le choix est très large (Vue, React, Angular, Ember…).

Le but de cet article n’est pas de guider les lecteurs dans le choix d’un framework javascript, il existe de très nombreux articles sur le web qui abordent ce sujet. De toute façon les entreprises prennent souvent le framework à la mode du moment.

Juste un mot sur les 3 premiers frameworks. Seul Vue permet de s’intégrer facilement à un site existant. Si vous voulez moderniser un site existant avec React ou Angular vous allez devoir réécrire entièrement le code. Il est très difficile d’ajouter React et Angular à une page PHP préexistante.

Dans cet article on ne s’intéresse qu’à React.

Vous vous dites le plus dur est fait, vous avez choisi le framework mais non, détrompez-vous ! Il faut maintenant choisir un autre framework, celui qui va créer l’application.

On pourra s’imaginer qu’il est facile de créer une application avec React, ce n’est pas le cas, il faut un framework en plus du framework. On peut essayer comme exercice de formation de construire une application React en partant simplement des bibilothèques React de base. C’est un très bon exercice. Malheureusement dans la réalité l’installation est si complexe qu’il faut installer un nouveau framework pour utiliser le premier framework.

Il faut comprendre qu’il y a énormément de modifications effectuées entre le code écrit par le développeur et le code généré pour la production sur un serveur. Cela n’a strictement rien à voir. Pour effectuer ces transformations tout un tas d’outils ont été créées. Ils sont disponibles avec NPM (Node Packet Manager), il suffit de taper une commande pour les rapatrier sur son PC et les utiliser. Les deux outils les plus importants sont Babel et Webpack.

Webpack gère tous les modules de votre code et les rassemble dans un seul fichier. Mais il ne fait pas que cela, le fichier de configuration de Webpack sert aussi à construire le site web et lance de nombreux traitements. Par exemple c’est dans le fichier de configuration de Webpack que vous allez effectuer toutes les modifications CSS.

Le problème est que le fichier de configuration de Webpack est très délicat à manipuler. Vous pouvez voir sur la documentation officielle un exemple de fichier de configuration qui se nomme webpack.config.js.

Bien sûr vous pouvez le créer tout seul mais il faut avoir des personnes dédiées à ce genre de tâche et qui comprennent très bien tous les traitements effectués.

Il existe principalement deux solutions pour éviter toutes ces fastidieuses tâches de configuration.

Les deux permettent de créer des applications React très facilement en une seule ligne de commande. Le code React ne va pas changer entre les deux frameworks ce qui va changer ce sont les services apportés en plus. Next.js comporte beaucoup plus de fonctionnalités que CRA.

Prenons un exemple les deux permettent le live reload c’est à dire que si vous modifiez votre code et que vous le sauvegardez, vous allez voir les modifications dans votre navigateur s’afficher automatiquement. Next.js utilise une solution qu’ils appellent Fast Refresh qui peut recharger automatiquement le composant sans recharger toute la page. CRA va tout le temps recharger les composants. Dans les deux cas tout cela est très rapide et la différence est peu visible.

Création d’un nouveau projet avec Next.js

Taper la commande suivante dans un terminal npx create-next-app

Structure d’une application Next.js

next.js files

Il ne reste plus qu’à lancer la commande npm run start et ouvrir son navigateur favori sur le port 3000 : http://localhost:3000 pour voir la page de présentation.

next.js landing page

Le projet de base a créé 14 000 fichiers sur votre PC et la taille du projet est de 100 Mo ! Bien sûr cela n’a rien à voir avec la taille du site en production.

Création d’un nouveau projet avec Create React App

Taper la commande suivante dans un terminal npx create-react-app cra1

Structure d’une application Create React App

Create react app files

Il ne reste plus qu’à lancer la commande npm start et ouvrir son navigateur favori sur le port 3000 : http://localhost:3000 pour voir la page de présentation.

Create React app landing page

Le projet de base a créé 44 000 fichiers sur votre PC et la taille du projet est de 215 Mo ! Le double d’un projet Next.js

Analyse de la structure des deux projets

La structure des 2 projets est assez semblable, le projet Next est quand même mieux organisé.

Les répertoires

npm_module : contient toutes les bibliothèques nécessaires à votre projet. C’est dans ce répertoire que se trouve la majorité des fichiers, il ne faut pas le toucher, toutes les modifications sont faites avec des commandes NPM comme npm install qui va installer de nouveaux packages dans ce répertoire.

public : contient tous les fichiers statiques de votre site : les images, les vidéos, les musiques... Il ne doit pas contenir de fichiers CSS ou JS qui sont modifiés par React.

Répertoires src ou pages suivant le framework : ce sont les répertoires qui vont contenir les composants React qui vont s’afficher à l’écran.

.next (seulement sur Next.js) : c’est un répertoire spécifique qui contient toute la machinerie pour faire fonctionner le site. Tout est généré automatiquement dans ce répertoire.

A partir de cette base vous pouvez bien sûr gérer votre projet comme vous l’entendez.

Dans les 2 cas le fichier le plus important webpack.config n’est pas visible, il est situé dans le répertoire npm_module. Qu’est-ce-que cela signifie ? Vous ne pourrez pas modifier le process de build. Vous pouvez néanmoins étendre la configuration en ajoutant un fichier de configuration dans votre répertoire.

CRA propose une autre option, la commande eject permet de s’affranchir de Create React App et de reprendre le contrôle total de l’application, ce sera alors à vous de gérer le fichier de configuration de webpack manuellement. C’est une option à déconseiller car vous ne profiterez plus des mises à jour du module. Vous pouvez essayer la commande npm run eject sur un projet de test pour voir le fichier webpack.config et comprendre comment la magie s ‘opère.

Un extrait du fichier web.config.js généré par CRA

webpack.config.js

A noter dans les deux cas c’est dans le fichier de configuration de NPM (package.json) que se trouve les commandes des scripts de lancement.

On se retrouve avec le fichier de configuration de webpack qui gère les transformations du CSS et le fichier de configuration de NPM qui contient les scripts de lancement.

Les différences entre Create React App et Next.js

Passons en revue la liste des fonctionnalités de Next.js et comparons-la avec CRA.

Zero config

Comme nous l’avons vu les 2 frameworks sont très simples à mettre en œuvre, vous n’avez aucun fichier de configuration à gérer.

Egalité

TypeScript Support

TypeScript est un langage de programmation développé au-dessus de Javascript qui apporte un tas de fonctionnalités supplémentaires à Javascript.

Les deux frameworks permettent de mettre en place TypeScript, Il suffit de l’incorporer dans le processus de build. La configuration est un peu plus facile avec Next.js

Egalité

Fast Refresh

Cette fonctionnalité est utile pour les développeurs, ils peuvent voir les modifications du code instantanément dans le navigateur.

La fonctionnalité est présente dans les deux frameworks, celle de Next.js semble plus performante.

Egalité

File-system Routing

Cette fonctionnalité n’existe qu’avec Next.js. Le principe est simple, vous placez un nouveau composant dans le répertoire « pages » et celui-ci devient une nouvelle page de votre site.

React n’a pas de fonction prédéfinie pour effectuer ce genre de routage, il faut ajouter une nouvelle bibliothèque : le React Router. L’installation n’est pas difficile.

Le terme routeur est trompeur, dans le cas de CRA le routage ne concerne pas du tout le réseau, les requêtes sont internes à React. On utilise un routeur pour que l’utilisateur parcourt les pages comme dans un site web. Dans le cas de Next.js le routage est un routage côté serveur comme dans un site web classique, des requêtes sont envoyées sur le réseau.

Avantage Next.js

API Route

Cette fonctionnalité est très similaire à la fonction précédente. Elle propose de créer des routes automatiquement pour des API.

Si vous placez une fonction dans le fichier pages/api/utilisateur vous pouvez faire un fetch directement sans vous souciez du routage et répondre à la demande en renvoyant la liste de tous les utilisateurs par exemple.

Cette fonctionnalité n’existe pas du tout avec Create React App et pour cause ce n’est pas une fonctionnalité côté client mais côté serveur. Create React App vous laisse libre dans le choix de votre langage de programmation côté serveur. Vous pouvez très bien avoir une application React qui communique avec PHP ou JavaScript avec Express par exemple. Dans le cas de Next.js vous avez tout ce qu’il vous faut pour travailler très vite côté serveur en JavaScript. L’inconvénient est que le code côté serveur est aussi en JavaScript. Toutes vos requêtes SQL doivent être appelées à partir de JavaScript. Next.js ne vous impose pas d’utiliser le répertoire api pour créer des API. Vous pouvez aussi utiliser PHP si vous le souhaitez.

Avantage Next.js (si vous voulez que votre back office soit codé en JavaScript)

Built-In CSS Support

Ils existent de nombreuse façon d’incorporer du CSS dans React.

Le deux frameworks permettent de gérer tous les cas, cela nécessitera peut-être l’ajout de nouveaux modules pour effectuer les traitements.

Egalité

Pre-render page at build time (SSG)

Cette fonctionnalité est la différence majeure entre les deux frameworks. Commençons par analyser comment fonctionne Create React App.

CRA créé automatiquement un projet React c’est à dire une SPA (Single Page Application). Tout le code de l’application est téléchargé au départ lors du premier accès au site. Votre site est constitué d’une seule page : index.html. Cette page contient tout le JavaScript et le CSS de votre site. Lorsque vous voulez voir les résultats de votre équipe préférée, vous allez cliquer sur un lien sur la page d’accueil, JavaScript va alors envoyer un message au serveur, récupérer les résultats de votre équipe, les mettre en forme dans un beau tableau et les afficher.

Il n’y a plus de page complète qui transite sur le réseau seulement des informations qui sont mises en forme avec JavaScript.

Le temps d’accès à la première page de votre site peut être un peu plus long car il faut télécharger tout le code du site et ensuite les informations qui vont être affichées sur la page d’accueil. Par contre les temps d’accès aux autres pages sont écourtés car une partie du travail se fait dans le navigateur du client (on n'a rien sans rien).

La question qui se pose : est-ce-que Google référence correctement les sites construits avec ce modèle de Single Page Application ? On appelle cela le référencement d’un site.

Google analyse les pages de tous les sites pour déterminer les informations qui y sont présentes. Tous les jours des milliards de messages sont envoyés pour récupérer les contenus des sites et les indexer. L’indexation des SPA est plus complexe car elle se déroule en deux temps : chargement du code JavaScript qui va lui-même récupérer les informations de votre site pour les afficher. Google a longtemps eu du mal à indexer ce genre de sites avec beaucoup de JavaScript. Apparemment ce n’est plus le cas et l’indexation des SPA est du même niveau que celle des autres sites (si votre site est rapide).

Le SEO (Search Engine Optimization) est un ensemble de techniques pour améliorer votre référencement et pour apparaître en haut de la première page de Google. Le SEO dit que le fait d’avoir beaucoup de JavaScript dans un site n’est pas une bonne chose pour le référencement. React ne contient que du JavaScript ! Comment faire ?

Next.js propose des solutions pour améliorer son référencement même avec l’utilisation de React cela se nomme le Server Side Rendering (SSR) et le Static Site Generation (SSG).

Définissons le SSG (génération de site statique)

Comme nous l’avons vu vous pouvez créer une nouvelle page en ajoutant un nouveau composant dans le répertoire « Pages » d’un projet Next.js. Imaginons que cette page ne contienne que du HTML par exemple une page d’informations sur le traitement des données (Legal.js). Que va faire Next.js au moment de la compilation ? Il va créer une page legal.html qui va contenir toute la page. Quand un utilisateur va demander la page sur les informations légales, il va directement recevoir la page complète et pas une page avec beaucoup de JavaScript. Bien sûr si la page contient du JavaScript pour un système de notation par exemple Next.js va conserver tout le code JavaScript nécessaire pour le fonctionnement de la notation dans le page HTML.

Un problème peut survenir si votre page a besoin d’information provenant d’une base de données. Comment faire ?

C’est simple, Next.js a prévu des fonctions spécifiques qui sont appelées au moment de la compilation. Ces fonctions vont envoyer des requêtes vers votre base de données et récupérer les données. Au moment de la compilation, Next va générer un fichier HTML mais il va être associé à un fichier JSON comprenant le résultat des requêtes sur votre base de données. Ces fichiers sont ensuite transférés chez le client pour être lus sur le poste du client.

L'idée de préparer une page toute prête n'est pas nouvelle, elle existe depuis très longtemps avec tous les frameworks PHP, ASP ou Java, on nomme cela la mise en cache.

Exemple de la génération d’un site statique avec Next.js

Nous partons du projet que nous avons déjà créé.

Pour simplifier je n’utilise pas une base de données mais un simple fichier JSON qui représente ma base de données.

Objectif

: Le but est de créer une page detail/id qui affiche les informations sur un client suivant son id.

detail/0 affichera les informations du client avec l’id 0 (l’id est simplement la place du client dans le tableau pour simplifier).


Dans un nouveau répertoire data

Fichier dataClient.js

const dataClient = 
[
    {
        nom: "Durand",
        prenom : "Jean",
        ville : "Paris"
    },
    {
        nom : "Martin",
        prenom : "Paul",
        ville : "Lyon"
    },
    {
        nom: "Lopez",
        prenom: "Carlos",
        ville : "Brest"
    }
];

export default dataClient;

Dans le répertoire pages

On ajoute le répertoire detail

On crée le fichier [id].js

import React, {Component} from 'React';
import dataClient from '../../data/dataClient'
export default class DetailClient extends Component
{

    render()
    {
        return <div>
                <h1>Informations sur le client</h1>
                <ul>
                    <li>nom : {this.props.dataClient.nom}</li>
                    <li>prenom : {this.props.dataClient.prenom}</li>
                    <li>ville : {this.props.dataClient.ville}</li>
                </ul>
            </div>
        }
}

export async function getStaticProps(context) {
    const id = context.params?.id
    return {
    props: {dataClient : dataClient[id]},
    }
}

export async function getStaticPaths() {
    return {
        paths: [
        { params: { id: '0' } },
        { params: { id: '1' } },
        { params: { id: '2' } }
        ],
        fallback: false
    };
}

J’utilise une classe à titre d’exemple.

La fonction getStaticProps est appelée au moment de la compilation, elle fait appel à la base de données (ici un simple fichier) et retourne les données.

La fonction getStaticPath est aussi appelée au moment de la compilation, elle détermine les id des pages html qui seront créés. Vous n’êtes pas obligé de générer toutes les pages de votre site.

Le fallback est très important, il permet de ne pas générer les pages au moment de la compilation mais lors de la demande du premier utilisateur. La page html restera présente pour les autres utilisateurs. Cela permet de ne pas générer trop de pages au moment de la compilation.

Dans le fichier index.js

On ajoute un lien pour accéder à la nouvelle page.

    import Link from 'next/link';

Après le Head de la fonction Home

<Link href="/Detail/0">
<a>Détail Client 1 </a>
</Link>
<Link href="/Detail/1">
<a>Détail Client 2 </a>
</Link>
<Link href="/Detail/2">
<a>Détail Client 3 </a>
</Link>

Vous pouvez tester en mode dev avec la commande

npm run dev

Le plus intéressant est de passer en mode production. Vous lancez la commande de build pour construire les fichiers HTML.

npm run build

Si vous allez dans le répertoire .next/server/pages/detail vous pouvez voir les 3 fichiers HTML ainsi que les fichiers json associés.

Un extrait du fichier HTML généré par Next.js. Il y a beaucoup de fichiers JavaScript mais ils ne sont pas très gros.

generated html file with next.js

Pour lancer le site en mode production

npm run start

Il est indéniable que la génération des pages statiques rend votre site beaucoup plus rapide, toutes les données sont déjà présentes, l’appel à la base de données n’est plus forcément nécessaire.

Nous avons abordé la génération de site statique (SSG), le SSR est la même chose mais en plus dynamique, la page n’est pas construite une seule fois pendant la compilation, elle est construite à chaque requête des utilisateurs. Si les données de la page changent très souvent cela ne sert à rien de générer des pages HTML qui vont être obsolètes très vite. Il faut noter qu’avec ce modèle on se rapproche très fortement de la page PHP classique.

Les philosophies sont donc différentes au niveau des deux frameworks, Create React App conserve l’esprit originel de React qui est de créer des SPA ou des applications. Next.js offre beaucoup plus de fonctionnalités et peut se suffire à lui-même. La question reste la même : est-ce que Google pénalise les sites React ?

Si vous le pensez vous devez opter pour Next.js

Le déploiement

Le passage en production est plus simple avec CRA.

Il suffit de lancer la commande npm run build et CRA vous crée un répertoire build qui contient tous les fichiers nécessaires. Il suffit ensuite de les copier sur votre serveur. Vous êtes aussi obligé de gérer un site web pour recevoir les requêtes venant de React.

Comme Next.js peut lancer des outils lors des demandes des utilisateurs, il a besoin de beaucoup plus de fichiers et d’avoir Node installé sur le serveur. Il n’y a pas de fonctionnalité pour créer un package avec tout ce qui est nécessaire.

Conclusion

Les deux frameworks sont assez semblables sauf au niveau du Server Side Rendering qui n’est proposé que par Next.js. La solution Next.js est séduisante, les pages de votre site vont s’afficher très rapidement et l’indexation par Google sera très bonne. Tout dépend de ce que vous désirez faire si vous développez une application pour un intranet la solution Create React App est plus intéressante.

On peut même s’orienter sur une solution PHP + Vue avec une mise en cache côté serveur. Ah non, cela ne semble pas possible, les développeurs ne veulent plus de PHP, trop ringard. Il faut le remplacer par Python !

A vous de choisir désormais.