Comment migrer de Create React App vers Next.js
Ce guide vous aidera à migrer un site existant créé avec Create React App (CRA) vers Next.js.
Pourquoi effectuer la migration ?
Plusieurs raisons peuvent vous pousser à migrer de Create React App vers Next.js :
Temps de chargement initial lent
Create React App utilise React exclusivement côté client. Les applications uniquement côté client, aussi appelées applications monopages (SPA), subissent souvent des temps de chargement initiaux lents. Cela est dû à plusieurs facteurs :
- Le navigateur doit attendre que le code React et l'ensemble de votre bundle applicatif soient téléchargés et exécutés avant que votre code puisse envoyer des requêtes pour charger les données.
- Votre code applicatif grossit avec chaque nouvelle fonctionnalité et dépendance ajoutée.
Pas de découpage de code automatique
Le problème précédent des temps de chargement lents peut être partiellement résolu avec le découpage de code. Cependant, si vous essayez de le faire manuellement, vous risquez d'introduire involontairement des cascades de requêtes réseau. Next.js fournit un découpage de code automatique et un élagage d'arbre intégrés à son routeur et pipeline de build.
Cascades de requêtes réseau
Une cause fréquente de mauvaise performance survient lorsque les applications effectuent des requêtes client-serveur séquentielles pour récupérer des données. Un modèle courant pour la récupération de données dans une SPA est de rendre un élément de substitution, puis de récupérer les données après que le composant a été monté. Malheureusement, un composant enfant ne peut commencer à récupérer des données qu'après que son parent a fini de charger ses propres données, ce qui crée une "cascade" de requêtes.
Bien que la récupération de données côté client soit supportée dans Next.js, Next.js vous permet aussi de déplacer cette récupération côté serveur. Cela élimine souvent complètement les cascades client-serveur.
États de chargement rapides et intentionnels
Avec le support natif du streaming via React Suspense, vous pouvez définir quelles parties de votre UI se chargent en premier et dans quel ordre, sans créer de cascades réseau.
Cela vous permet de construire des pages qui se chargent plus rapidement et éliminent les décalages de mise en page.
Choisissez votre stratégie de récupération de données
Selon vos besoins, Next.js vous permet de choisir votre stratégie de récupération de données au niveau de la page ou du composant. Par exemple, vous pourriez récupérer des données depuis votre CMS et pré-rendre des articles de blog au moment du build (SSG) pour des temps de chargement rapides, ou récupérer les données au moment de la requête (SSR) quand nécessaire.
Middleware
Le Middleware Next.js vous permet d'exécuter du code côté serveur avant qu'une requête ne soit complétée. Par exemple, vous pouvez éviter un flash de contenu non authentifié en redirigeant un utilisateur vers une page de login dans le middleware pour les pages nécessitant une authentification. Vous pouvez aussi l'utiliser pour des fonctionnalités comme les tests A/B, l'expérimentation et l'internationalisation.
Optimisations intégrées
Les images, polices et scripts tiers ont souvent un impact important sur les performances d'une application. Next.js inclut des composants spécialisés et des APIs qui les optimisent automatiquement pour vous.
Étapes de migration
Notre objectif est d'obtenir une application Next.js fonctionnelle aussi rapidement que possible pour que vous puissiez ensuite adopter les fonctionnalités de Next.js progressivement. Pour commencer, nous traiterons votre application comme une application purement côté client (SPA) sans remplacer immédiatement votre routeur existant. Cela réduit la complexité et les conflits de fusion.
Note : Si vous utilisez des configurations avancées de CRA comme un champ
homepage
personnalisé dans votrepackage.json
, un service worker personnalisé ou des ajustements spécifiques de Babel/webpack, veuillez consulter la section Considérations supplémentaires à la fin de ce guide pour des conseils sur la réplication ou l'adaptation de ces fonctionnalités dans Next.js.
Étape 1 : Installer la dépendance Next.js
Installez Next.js dans votre projet existant :
Étape 2 : Créer le fichier de configuration Next.js
Créez un fichier next.config.ts
à la racine de votre projet (même niveau que votre package.json
). Ce fichier contient vos options de configuration Next.js.
Note : Utiliser
output: 'export'
signifie que vous faites une exportation statique. Vous n'aurez pas accès aux fonctionnalités serveur comme le SSR ou les APIs. Vous pouvez supprimer cette ligne pour profiter des fonctionnalités serveur de Next.js.
Étape 3 : Créer la mise en page racine
Une application Next.js avec App Router doit inclure un fichier de mise en page racine, qui est un composant serveur React qui englobera toutes vos pages.
L'équivalent le plus proche du fichier de mise en page racine dans une application CRA est public/index.html
, qui inclut vos balises <html>
, <head>
et <body>
.
- Créez un nouveau répertoire
app
dans votre dossiersrc
(ou à la racine de votre projet si vous préférezapp
à la racine). - Dans le répertoire
app
, créez un fichierlayout.tsx
(oulayout.js
) :
Maintenant copiez le contenu de votre ancien index.html
dans ce composant <RootLayout>
. Remplacez body div#root
(et body noscript
) par <div id="root">{children}</div>
.
Bon à savoir : Next.js ignore par défaut le
public/manifest.json
de CRA, les icônes supplémentaires et la configuration de test. Si vous en avez besoin, Next.js les supporte avec son API Metadata et sa configuration de test.
Étape 4 : Métadonnées
Next.js inclut automatiquement les balises <meta charset="UTF-8" />
et <meta name="viewport" content="width=device-width, initial-scale=1" />
, vous pouvez donc les supprimer de <head>
:
Tous les fichiers de métadonnées comme favicon.ico
, icon.png
, robots.txt
sont automatiquement ajoutés à la balise <head>
de l'application tant qu'ils sont placés à la racine du répertoire app
. Après avoir déplacé tous les fichiers supportés dans le répertoire app
, vous pouvez supprimer leurs balises <link>
en toute sécurité :
Enfin, Next.js peut gérer vos dernières balises <head>
avec l'API Metadata. Déplacez vos dernières informations de métadonnées dans un objet metadata
exporté :
Avec les changements ci-dessus, vous êtes passé de la déclaration de tout dans votre index.html
à l'utilisation de l'approche conventionnelle de Next.js intégrée au framework (API Metadata). Cette approche vous permet d'améliorer plus facilement votre SEO et la partageabilité web de vos pages.
Étape 5 : Styles
Comme CRA, Next.js supporte les CSS Modules nativement. Il supporte aussi les imports CSS globaux.
Si vous avez un fichier CSS global, importez-le dans votre app/layout.tsx
:
Si vous utilisez Tailwind CSS, consultez notre documentation d'installation.
Étape 6 : Créer la page d'entrée
Create React App utilise src/index.tsx
(ou index.js
) comme point d'entrée. Dans Next.js (App Router), chaque dossier à l'intérieur du répertoire app
correspond à une route, et chaque dossier doit avoir un page.tsx
.
Comme nous voulons garder l'application comme une SPA pour l'instant et intercepter toutes les routes, nous utiliserons une route attrape-tout optionnelle.
- Créez un répertoire
[[...slug]]
dansapp
.
- Ajoutez ce qui suit à
page.tsx
:
Cela indique à Next.js de générer une seule route pour le slug vide (/
), mappant ainsi toutes les routes à la même page. Cette page est un composant serveur, pré-rendu en HTML statique.
Étape 7 : Ajouter un point d'entrée client uniquement
Ensuite, nous intégrerons le composant racine App de votre CRA dans un composant client pour que toute la logique reste côté client. Si c'est votre première fois avec Next.js, il est bon de savoir que les composants clients (par défaut) sont toujours pré-rendus côté serveur. Vous pouvez les considérer comme ayant la capacité supplémentaire d'exécuter du JavaScript côté client.
Créez un fichier client.tsx
(ou client.js
) dans app/[[...slug]]/
:
- La directive
'use client'
fait de ce fichier un composant client. - L'import dynamique avec
ssr: false
désactive le rendu côté serveur pour le composant<App />
, le rendant véritablement client uniquement (SPA).
Maintenant mettez à jour votre page.tsx
(ou page.js
) pour utiliser votre nouveau composant :
Étape 8 : Mettre à jour les imports d'images statiques
Dans CRA, importer un fichier image renvoie son URL publique sous forme de chaîne :
Avec Next.js, les imports d'images statiques renvoient un objet. Cet objet peut ensuite être utilisé directement avec le composant <Image>
de Next.js, ou vous pouvez utiliser la propriété src
de l'objet avec votre balise <img>
existante.
Le composant <Image>
offre des avantages supplémentaires comme l'optimisation automatique des images. Le composant <Image>
définit automatiquement les attributs width
et height
de la balise <img>
résultante en fonction des dimensions de l'image. Cela évite les décalages de mise en page lors du chargement de l'image. Cependant, cela peut causer des problèmes si votre application contient des images dont une seule dimension est stylée sans que l'autre ne soit définie sur auto
. Si elle n'est pas stylée sur auto
, la dimension prendra par défaut la valeur de l'attribut de dimension de la balise <img>
, ce qui peut déformer l'image.
Conserver la balise <img>
réduira le nombre de modifications dans votre application et évitera les problèmes mentionnés ci-dessus. Vous pourrez ensuite migrer ultérieurement vers le composant <Image>
pour profiter de l'optimisation des images en configurant un loader, ou en passant au serveur Next.js par défaut qui offre une optimisation automatique des images.
Convertissez les chemins d'import absolus pour les images importées depuis /public
en imports relatifs :
Passez la propriété src
de l'image au lieu de l'objet image entier à votre balise <img>
:
Alternativement, vous pouvez référencer l'URL publique de l'image en fonction de son nom de fichier. Par exemple, public/logo.png
servira l'image à l'URL /logo.png
pour votre application, qui sera la valeur de src
.
Avertissement : Si vous utilisez TypeScript, vous pourriez rencontrer des erreurs de type lors de l'accès à la propriété
src
. Pour les corriger, vous devez ajouternext-env.d.ts
au tableauinclude
de votre fichiertsconfig.json
. Next.js générera automatiquement ce fichier lorsque vous exécuterez votre application à l'étape 9.
Étape 9 : Migrer les variables d'environnement
Next.js prend en charge les variables d'environnement de manière similaire à CRA, mais requiert un préfixe NEXT_PUBLIC_
pour toute variable que vous souhaitez exposer dans le navigateur.
La principale différence est le préfixe utilisé pour exposer les variables d'environnement côté client. Remplacez toutes les variables d'environnement avec le préfixe REACT_APP_
par NEXT_PUBLIC_
.
Étape 10 : Mettre à jour les scripts dans package.json
Mettez à jour les scripts de votre package.json
pour utiliser les commandes Next.js. Ajoutez également .next
et next-env.d.ts
à votre .gitignore
:
Vous pouvez maintenant exécuter :
Ouvrez http://localhost:3000. Vous devriez voir votre application fonctionnant désormais sur Next.js (en mode SPA).
Étape 11 : Nettoyer
Vous pouvez maintenant supprimer les artefacts spécifiques à Create React App :
public/index.html
src/index.tsx
src/react-app-env.d.ts
- La configuration
reportWebVitals
- La dépendance
react-scripts
(désinstallez-la depackage.json
)
Considérations supplémentaires
Utilisation d'un homepage
personnalisé dans CRA
Si vous avez utilisé le champ homepage
dans votre package.json
de CRA pour servir l'application sous un sous-chemin spécifique, vous pouvez le reproduire dans Next.js en utilisant la configuration basePath
dans next.config.ts
:
Gestion d'un Service Worker
personnalisé
Si vous avez utilisé le service worker de CRA (par exemple, serviceWorker.js
de create-react-app
), vous pouvez apprendre à créer des applications web progressives (PWA) avec Next.js.
Proxification des requêtes API
Si votre application CRA utilisait le champ proxy
dans package.json
pour rediriger les requêtes vers un serveur backend, vous pouvez le reproduire avec les rewrites de Next.js dans next.config.ts
:
Configuration personnalisée de Webpack / Babel
Si vous aviez une configuration personnalisée de webpack ou Babel dans CRA, vous pouvez étendre la configuration de Next.js dans next.config.ts
:
Remarque : Cela nécessitera de désactiver Turbopack en supprimant
--turbopack
de votre scriptdev
.
Configuration TypeScript
Next.js configure automatiquement TypeScript si vous avez un tsconfig.json
. Assurez-vous que next-env.d.ts
est listé dans le tableau include
de votre tsconfig.json
:
Compatibilité du bundler
Create React App et Next.js utilisent par défaut webpack pour le bundling. Next.js propose également Turbopack pour un développement local plus rapide avec :
Vous pouvez toujours fournir une configuration webpack personnalisée si vous avez besoin de migrer des paramètres webpack avancés depuis CRA.
Prochaines étapes
Si tout a fonctionné, vous avez maintenant une application Next.js fonctionnelle en tant qu'application monopage. Vous n'utilisez pas encore les fonctionnalités de Next.js comme le rendu côté serveur ou le routage basé sur les fichiers, mais vous pouvez désormais le faire progressivement :
- Migrez de React Router vers le routeur d'application Next.js pour :
- Le découpage de code automatique
- Le rendu côté serveur en streaming
- Les composants serveur React
- Optimisez les images avec le composant
<Image>
- Optimisez les polices avec
next/font
- Optimisez les scripts tiers avec le composant
<Script>
- Activez ESLint avec les règles recommandées par Next.js en exécutant
npx next lint
et en le configurant selon les besoins de votre projet
Remarque : L'utilisation d'une exportation statique (
output: 'export'
) ne prend pas en charge actuellement le hookuseParams
ou d'autres fonctionnalités serveur. Pour utiliser toutes les fonctionnalités de Next.js, supprimezoutput: 'export'
de votrenext.config.ts
.