Cours Next.js · Module 1: Configuration de Next.js
Outils de développement Next.js
Dans cette leçon7
À Quantum Metropolis, chaque ingénieur dispose d'un ensemble avancé d'outils de diagnostic qui permettent de surveiller en temps réel les systèmes de la ville, de détecter les anomalies et d'optimiser les performances de l'infrastructure. De même, Next.js 16 offre aux programmeurs un puissant ensemble d'outils de développement qui accélèrent considérablement le travail et facilitent la recherche des bugs.
Fast Refresh - mises à jour instantanées
Imagine que les ingénieurs de Quantum Metropolis peuvent modifier les systèmes de la ville et voir les effets de leurs changements en une fraction de seconde, sans avoir à redémarrer toute l'infrastructure. C'est exactement ainsi que fonctionne Fast Refresh dans Next.js.
Fast Refresh est un mécanisme de hot reload qui met automatiquement à jour l'aperçu de l'application dans le navigateur après l'enregistrement des changements de code. Fonctionnalités clés :
- Préserve l'état des composants - si tu modifies un composant React, Fast Refresh le met à jour sans réinitialiser l'état de
useStateouuseReducer - Fonctionne instantanément - les changements sont visibles en moins d'une seconde
- Gère les erreurs de syntaxe - si tu fais une erreur, l'application revient à son état normal une fois l'erreur corrigée
1// You edit this component and save the file...
2export default function Dashboard() {
3 const [count, setCount] = useState(0);
4
5 return (
6 <div>
7 <h1>Quantum Panel: {count}</h1>
8 <button onClick={() => setCount(count + 1)}>+1</button>
9 </div>
10 );
11}
12// Fast Refresh updates the component, but count keeps its value!Quand Fast Refresh réinitialise-t-il l'état ? Si tu modifies un fichier qui exporte autre chose qu'un composant React (par ex. une constante, une fonction utilitaire), Fast Refresh rechargera l'ensemble du module. C'est un comportement normal.
Error Overlay - des messages d'erreur lisibles
Dans le centre de commande de Quantum Metropolis, chaque anomalie s'affiche immédiatement sur l'écran principal avec une description exacte du problème et de son emplacement. Next.js propose un mécanisme analogue - Error Overlay.
Lorsqu'une erreur apparaît dans le code, Next.js affiche une superposition en plein écran avec :
- Le type d'erreur - par ex.
TypeError,SyntaxError,ReferenceError - Le message d'erreur - une description lisible du problème
- L'emplacement dans le code - le fichier exact, la ligne et la colonne
- La stack trace - le chemin d'appels menant à l'erreur
1// If you write code with an error like this:
2export default function Page() {
3 const user = null;
4 return <h1>{user.name}</h1>; // TypeError: Cannot read property 'name' of null
5}
6
7// Error Overlay will show:
8// TypeError: Cannot read properties of null (reading 'name')
9// app/page.tsx (3:22)Error Overlay fonctionne à la fois pour les erreurs à la compilation (par ex. les erreurs de syntaxe TypeScript) et pour les erreurs à l'exécution (par ex. les références à des variables non définies). Il suffit de corriger l'erreur et d'enregistrer le fichier - la superposition disparaîtra automatiquement.
Turbopack - le nouveau bundler de Next.js
À Quantum Metropolis, l'ancien générateur d'énergie a été remplacé par TurboCore, un nouveau réacteur quantique bien plus performant. De même, dans Next.js 16, Turbopack est devenu le bundler par défaut et remplace Webpack aussi bien dans next dev que dans next build.
Turbopack est un bundler écrit en Rust, créé par le créateur de Webpack. Ses principaux avantages :
- Builds de production 2 à 5x plus rapides qu'avec Webpack - selon l'équipe Next.js lors de la sortie de Next.js 16
- Fast Refresh (Hot Module Replacement, HMR) jusqu'à 10x plus rapide
- Compilation incrémentale - ne traite que les fichiers modifiés
Dans Next.js 16, tu n'as rien à activer - Turbopack fonctionne d'emblée, et le flag --webpack te ramène à Webpack :
1# Development and production builds - Turbopack by default
2npx next dev
3npx next build
4
5# Switch back to Webpack if your project needs it
6npx next dev --webpack
7
8# Scripts in package.json no longer need the --turbopack flag
9{
10 "scripts": {
11 "dev": "next dev",
12 "build": "next build"
13 }
14}Depuis Next.js 16, Turbopack est utilisé par défaut aussi bien en développement que pour les builds de production. Dans Next.js 15, il n'était stable que pour next dev et il fallait l'activer avec le flag --turbopack. Il accélère considérablement le temps de chargement des pages pendant le développement, surtout dans les grands projets.
React DevTools avec Next.js
Chaque technicien de Quantum Metropolis utilise un scanner avancé pour analyser les systèmes de la ville. Pour les programmeurs React, l'équivalent est l'extension React DevTools.
React DevTools est une extension de navigateur (Chrome, Firefox, Edge) qui permet de :
- Parcourir l'arbre des composants - tu vois la hiérarchie de tous les composants React
- Inspecter les props et l'état - tu peux consulter les valeurs de
props,useState,useContext - Profiler les performances - tu mesures quels composants prennent le plus de temps à rendre
- Mettre en évidence les re-rendus - tu vois visuellement quels composants se re-rendent
1// React DevTools will show the structure:
2// <RootLayout>
3// <Navbar />
4// <MainContent>
5// <Dashboard count={5} />
6// <Sidebar items={[...]} />
7// </MainContent>
8// <Footer />
9// </RootLayout>Dans Next.js, React DevTools reconnaît automatiquement les Server Components et les Client Components, en affichant les étiquettes appropriées.
Les bases du débogage dans Next.js
Chaque ingénieur de Quantum Metropolis doit connaître les outils de diagnostic de base. Voici les techniques clés de débogage dans Next.js :
Console - le terminal de diagnostic
L'outil le plus simple mais très efficace. Dans Next.js, console.log fonctionne à la fois côté serveur (terminal) et côté client (DevTools du navigateur) :
1// Server Component - logs visible in terminal
2export default async function Page() {
3 console.log("This log will appear in the server terminal");
4 const data = await getData();
5 console.log("Fetched data:", data);
6 return <div>{data.title}</div>;
7}
8
9// Client Component - logs visible in browser
10"use client";
11export default function Button() {
12 console.log("This log will appear in the browser console");
13 return <button onClick={() => console.log("Clicked!")}>Click</button>;
14}Onglet Network - surveillance des transmissions
L'onglet Network des DevTools du navigateur te permet de surveiller toutes les requêtes réseau :
- Requêtes API - tu peux voir l'URL, le statut, le temps de réponse
- Ressources statiques - images, CSS, JavaScript
- Prefetching - Next.js récupère automatiquement les données pour les liens visibles à l'écran
Configuration de next.config.js - vue d'ensemble
Le fichier next.config.js (ou next.config.mjs, et next.config.ts dans les projets créés avec create-next-app) est le point central de configuration d'un projet Next.js, semblable au panneau de contrôle principal de Quantum Metropolis. Voici les options les plus importantes :
1// next.config.js
2/** @type {import('next').NextConfig} */
3const nextConfig = {
4 // Image optimization - allowed external servers (images.domains is deprecated)
5 images: {
6 remotePatterns: [
7 { protocol: 'https', hostname: 'example.com' },
8 { protocol: 'https', hostname: 'cdn.example.com' },
9 ],
10 },
11
12 // URL redirects
13 async redirects() {
14 return [
15 {
16 source: '/old-path',
17 destination: '/new-path',
18 permanent: true,
19 },
20 ];
21 },
22
23 // Environment variables available in code
24 env: {
25 APP_VERSION: '1.0.0',
26 },
27};
28
29module.exports = nextConfig;Options de configuration les plus couramment utilisées :
images- configuration de l'optimisation des imagesredirects- redirections d'URL (par ex. après un changement de structure du site)env- variables d'environnement supplémentairesexperimental- fonctionnalités expérimentales de Next.js
Résumé
Les outils de développement Next.js sont comme le système de diagnostic avancé de Quantum Metropolis - ils te permettent de :
- Fast Refresh - voir instantanément les effets des changements de code sans perdre l'état
- Error Overlay - localiser et corriger rapidement les erreurs grâce à des messages lisibles
- Turbopack - travailler avec une compilation ultra-rapide grâce au nouveau bundler écrit en Rust
- React DevTools - analyser la structure des composants, les props et l'état
- Console et onglet Network - déboguer l'application côté serveur comme côté client
- next.config.js - configurer de manière centralisée le comportement du projet
La connaissance de ces outils est le fondement d'un travail efficace avec Next.js. Dans les modules suivants, tu les utiliseras régulièrement pour construire des applications de plus en plus avancées à Quantum Metropolis.
Code de cette leçon : App.tsx
1import React, { useState } from 'react';
2
3// Simulation des outils de développement Next.js
4const DevToolsDemo = () => {
5 const [activeTab, setActiveTab] = useState('fast-refresh');
6 const [code, setCode] = useState('<h1>Bienvenue à Quantum !</h1>');
7 const [logs, setLogs] = useState<string[]>([]);
8 const [error, setError] = useState<string | null>(null);
9
10 const tabs = [
11 { id: 'fast-refresh', label: 'Fast Refresh' },
12 { id: 'error-overlay', label: 'Error Overlay' },
13 { id: 'console', label: 'Console' },
14 ];
15
16 const simulateFastRefresh = () => {
17 setLogs(prev => [...prev, '[Fast Refresh] Changement détecté, mise à jour...']);
18 setTimeout(() => {
19 setLogs(prev => [...prev, '[Fast Refresh] Composant mis à jour (12ms)']);
20 setLogs(prev => [...prev, '[Fast Refresh] État du composant préservé']);
21 }, 300);
22 };
23
24 const simulateError = () => {
25 setError('TypeError: Cannot read properties of null (reading "name")\n at DashboardPage (app/page.tsx:5:18)');
26 setLogs(prev => [...prev, '[Error] Erreur détectée dans le composant']);
27 };
28
29 const fixError = () => {
30 setError(null);
31 setLogs(prev => [...prev, '[Fast Refresh] Erreur corrigée, superposition fermée']);
32 };
33
34 const addConsoleLog = (type: string) => {
35 const messages: Record<string, string> = {
36 server: '[Server] console.log: Données récupérées depuis l\'API (145ms)',
37 client: '[Browser] console.log: Composant monté',
38 network: '[Network] GET /api/data -> 200 OK (89ms)',
39 };
40 setLogs(prev => [...prev, messages[type] || '[Log] Action exécutée']);
41 };
42
43 return (
44 <div style={{ background: '#0f0f23', minHeight: '100vh', padding: '20px', color: '#fff', fontFamily: 'monospace' }}>
45 <h1 style={{ color: '#64ffda', textAlign: 'center', marginBottom: '20px' }}>
46 Next.js Dev Tools - Quantum Lab
47 </h1>
48
49 <div style={{ display: 'flex', gap: '8px', justifyContent: 'center', marginBottom: '20px' }}>
50 {tabs.map(tab => (
51 <button key={tab.id} onClick={() => { setActiveTab(tab.id); setError(null); }}
52 style={{ padding: '8px 16px', background: activeTab === tab.id ? '#7c4dff' : 'rgba(255,255,255,0.1)',
53 border: 'none', borderRadius: '6px', color: '#fff', cursor: 'pointer' }}>
54 {tab.label}
55 </button>
56 ))}
57 </div>
58
59 <div style={{ maxWidth: '800px', margin: '0 auto' }}>
60 {activeTab === 'fast-refresh' && (
61 <div>
62 <div style={{ background: '#1a1a2e', padding: '16px', borderRadius: '8px', marginBottom: '12px' }}>
63 <p style={{ color: '#888', marginBottom: '8px' }}>Éditeur de code (simulation) :</p>
64 <textarea value={code} onChange={(e) => setCode(e.target.value)}
65 style={{ width: '100%', background: '#0d1117', color: '#64ffda', border: '1px solid #333',
66 borderRadius: '4px', padding: '12px', fontFamily: 'monospace', fontSize: '14px', minHeight: '60px' }} />
67 </div>
68 <button onClick={simulateFastRefresh}
69 style={{ padding: '10px 24px', background: '#4caf50', border: 'none', borderRadius: '6px',
70 color: '#fff', cursor: 'pointer', marginBottom: '12px' }}>
71 Enregistrer le fichier (Ctrl+S)
72 </button>
73 <div style={{ background: '#000', padding: '12px', borderRadius: '8px', marginTop: '8px', border: '1px solid #333' }}>
74 <p style={{ color: '#888', marginBottom: '4px' }}>Aperçu :</p>
75 <div dangerouslySetInnerHTML={{ __html: code }} style={{ color: '#64ffda' }} />
76 </div>
77 </div>
78 )}
79
80 {activeTab === 'error-overlay' && (
81 <div>
82 {error ? (
83 <div style={{ background: 'rgba(244,67,54,0.15)', border: '2px solid #f44336', borderRadius: '8px', padding: '20px' }}>
84 <h3 style={{ color: '#f44336', marginBottom: '12px' }}>Unhandled Runtime Error</h3>
85 <pre style={{ color: '#ff8a80', whiteSpace: 'pre-wrap', marginBottom: '16px' }}>{error}</pre>
86 <button onClick={fixError}
87 style={{ padding: '8px 20px', background: '#4caf50', border: 'none', borderRadius: '6px',
88 color: '#fff', cursor: 'pointer' }}>
89 Corriger l'erreur
90 </button>
91 </div>
92 ) : (
93 <div style={{ textAlign: 'center' }}>
94 <p style={{ color: '#4caf50', marginBottom: '16px' }}>Aucune erreur</p>
95 <button onClick={simulateError}
96 style={{ padding: '10px 24px', background: '#f44336', border: 'none', borderRadius: '6px',
97 color: '#fff', cursor: 'pointer' }}>
98 Simuler une erreur
99 </button>
100 </div>
101 )}
102 </div>
103 )}
104
105 {activeTab === 'console' && (
106 <div>
107 <div style={{ display: 'flex', gap: '8px', marginBottom: '12px' }}>
108 <button onClick={() => addConsoleLog('server')}
109 style={{ padding: '8px 16px', background: '#1a73e8', border: 'none', borderRadius: '6px', color: '#fff', cursor: 'pointer' }}>
110 Server Log
111 </button>
112 <button onClick={() => addConsoleLog('client')}
113 style={{ padding: '8px 16px', background: '#ff9800', border: 'none', borderRadius: '6px', color: '#fff', cursor: 'pointer' }}>
114 Client Log
115 </button>
116 <button onClick={() => addConsoleLog('network')}
117 style={{ padding: '8px 16px', background: '#0f9d58', border: 'none', borderRadius: '6px', color: '#fff', cursor: 'pointer' }}>
118 Network
119 </button>
120 <button onClick={() => setLogs([])}
121 style={{ padding: '8px 16px', background: 'rgba(255,0,0,0.2)', border: 'none', borderRadius: '6px', color: '#f44336', cursor: 'pointer' }}>
122 Effacer
123 </button>
124 </div>
125 </div>
126 )}
127
128 <div style={{ background: '#000', borderRadius: '8px', padding: '12px', marginTop: '16px', minHeight: '150px', maxHeight: '250px', overflowY: 'auto' }}>
129 <p style={{ color: '#555', marginBottom: '8px' }}>Logs :</p>
130 {logs.length === 0 ? (
131 <p style={{ color: '#333', textAlign: 'center', paddingTop: '40px' }}>Aucun log...</p>
132 ) : (
133 logs.map((log, i) => (
134 <div key={i} style={{ padding: '2px 0', fontSize: '13px',
135 color: log.includes('Error') ? '#f44336' : log.includes('Server') ? '#1a73e8' : log.includes('Network') ? '#0f9d58' : '#ccc' }}>
136 {log}
137 </div>
138 ))
139 )}
140 </div>
141 </div>
142 </div>
143 );
144};
145
146export default DevToolsDemo;Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Que fait le mécanisme Fast Refresh dans Next.js ?
2. Qu'est-ce que Turbopack dans Next.js 16 ?