Cours JavaScript et React · Module 1: Bases de React

Créer un projet React avec Vite

6 min de lecture
Dans cette leçon6

Lors d'un voyage cosmique à travers le monde de React, il te faut un vaisseau adapté pour partir. Autrefois, le choix standard était Create React App (CRA), mais cet outil a été officiellement déprécié et n'est plus maintenu. Le standard moderne pour créer des projets React est Vite - un bundler ultrarapide de nouvelle génération.

Ra, notre guide cosmique, dit : « Abandonne la vieille navette CRA - Vite est le nouveau moteur à distorsion qui t'emmènera vers la galaxie React plus vite que jamais ! »

Pourquoi Vite ?

Vite (prononcé « vite », du français « rapide ») est un outil moderne pour construire des applications front-end, créé par Evan You (le créateur de Vue.js). La documentation de React le cite (avec Parcel et Rsbuild) parmi les outils recommandés quand tu construis une application sans framework.

Pourquoi Vite a remplacé CRA :

  • Démarrage du serveur ultra-rapide - Vite s'appuie sur les modules ES natifs du navigateur (ESM), de sorte que le serveur de développement démarre en 1 à 2 secondes (CRA avait besoin de 20 à 40 secondes)
  • Hot Module Replacement (HMR) instantané - les modifications de code apparaissent dans le navigateur en ~50 ms, quelle que soit la taille de l'application
  • Architecture moderne - bâtie sur ESM plutôt que sur l'ancien Webpack
  • Builds de production rapides - depuis Vite 8, utilise Rolldown (auparavant Rollup) pour regrouper les fichiers en bundles
  • Prise en charge prête à l'emploi - TypeScript, JSX, CSS Modules et PostCSS fonctionnent sans configuration supplémentaire

Créer un nouveau projet avec Vite

Pour créer un nouveau projet React avec Vite, ouvre le terminal et tape :

1npm create vite@latest my-react-app -- --template react

Cette commande :

  1. Utilise npm create pour lancer le générateur Vite
  2. vite@latest garantit l'utilisation de la dernière version
  3. my-react-app est le nom de ton projet
  4. --template react sélectionne le template React (également disponible : react-ts pour TypeScript)

Après avoir créé le projet, navigue dans le répertoire et installe les dépendances :

1cd my-react-app
2npm install

Puis démarre le serveur de développement :

1npm run dev

Ton application sera disponible à l'adresse http://localhost:5173 dans le navigateur. Remarque : Vite utilise par défaut le port 5173, et non 3000.

Structure d'un projet Vite + React

Après avoir créé le projet, tu verras la structure suivante :

1my-react-app/
2├── node_modules/         # Dépendances installées
3├── public/               # Fichiers statiques (copiés tels quels)
4│   ├── favicon.svg       # Icône du site
5│   └── icons.svg         # Icônes
6├── src/                  # Code source
7│   ├── assets/           # Ressources (images, polices)
8│   │   └── react.svg     # Logo React
9│   ├── App.css           # Styles du composant App
10│   ├── App.jsx           # Composant principal App
11│   ├── index.css         # Styles globaux
12│   └── main.jsx          # Point d'entrée de l'application
13├── index.html            # Fichier HTML principal (à la racine !)
14├── vite.config.js        # Configuration de Vite
15├── package.json          # Infos du projet et dépendances
16├── .gitignore            # Fichiers ignorés par Git
17└── .oxlintrc.json        # Configuration du linter (Oxlint)

Différences clés avec CRA

Remarque quelques différences importantes :

  • index.html est à la racine, et non dans public/ - Vite le considère comme le point d'entrée
  • Les fichiers utilisent l'extension .jsx au lieu de .js - cela signale clairement qu'un fichier contient du JSX
  • Le point d'entrée est main.jsx, et non index.js
  • vite.config.js au lieu d'une configuration Webpack cachée - tu as le contrôle total

index.html

Avec Vite, le fichier index.html se trouve à la racine du projet et ressemble à ceci :

1<!DOCTYPE html>
2<html lang="en">
3  <head>
4    <meta charset="UTF-8" />
5    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7    <title>Vite + React</title>
8  </head>
9  <body>
10    <div id="root"></div>
11    <script type="module" src="/src/main.jsx"></script>
12  </body>
13</html>

La ligne clé est <script type="module" src="/src/main.jsx"></script> - Vite charge l'application comme un module ES natif, ce qui garantit un démarrage ultra-rapide.

src/main.jsx

C'est le point d'entrée de l'application React :

1import React from 'react'
2import ReactDOM from 'react-dom/client'
3import App from './App.jsx'
4import './index.css'
5
6ReactDOM.createRoot(document.getElementById('root')).render(
7  <React.StrictMode>
8    <App />
9  </React.StrictMode>,
10)

Ce code :

  1. Importe React et ReactDOM
  2. Crée une « racine » React dans l'élément ayant l'id root
  3. Rend le composant principal App à l'intérieur de StrictMode

src/App.jsx

Le composant principal de ton application :

1import { useState } from 'react'
2import reactLogo from './assets/react.svg'
3import viteLogo from '/vite.svg'
4import './App.css'
5
6function App() {
7  const [count, setCount] = useState(0)
8
9  return (
10    <>
11      <div>
12        <a href="https://vite.dev" target="_blank">
13          <img src={viteLogo} className="logo" alt="Vite logo" />
14        </a>
15        <a href="https://react.dev" target="_blank">
16          <img src={reactLogo} className="logo react" alt="React logo" />
17        </a>
18      </div>
19      <h1>Vite + React</h1>
20      <div className="card">
21        <button onClick={() => setCount(c => c + 1)}>
22          count is {count}
23        </button>
24      </div>
25    </>
26  )
27}
28
29export default App

vite.config.js

Le fichier de configuration de Vite - simple et lisible :

1import { defineConfig } from 'vite'
2import react from '@vitejs/plugin-react'
3
4export default defineConfig({
5  plugins: [react()],
6})

C'est tout ce dont tu as besoin ! Le plugin @vitejs/plugin-react fournit la prise en charge de JSX, le Fast Refresh (HMR) et d'autres fonctionnalités de React.

Scripts disponibles

Dans le package.json du projet Vite, tu trouveras :

  • npm run dev - démarre le serveur de développement avec le HMR
  • npm run build - construit l'application pour le déploiement en production
  • npm run preview - prévisualise localement la version de production construite
  • npm run lint - vérifie le code avec un linter (dans le modèle actuel : Oxlint)

Vite vs CRA - comparaison

CaractéristiqueCRA (déprécié)Vite
StatutDéprécié, plus de mises à jourActivement maintenu
Démarrage du serveur20-40 secondes1-2 secondes
HMR1-3 secondes~50 ms
BundlerWebpackRolldown (depuis Vite 8 ; auparavant esbuild + Rollup)
ConfigurationCachée (eject)Explicite (vite.config.js)
ModulesCommonJSModules ES natifs
TypeScriptNécessite une configurationFonctionne prêt à l'emploi

Autres outils de l'écosystème React

Outre Vite, il vaut la peine de connaître d'autres outils populaires :

  • Next.js - un framework React avec SSR (Server-Side Rendering), SSG et routage basé sur les fichiers. Idéal pour les applications nécessitant un bon SEO
  • React Router (anciennement Remix) - un framework React axé sur les fondamentaux du web et l'amélioration progressive
  • Gatsby - un générateur de sites statiques avec GraphQL

Pour apprendre React et construire des applications SPA (Single Page Application), Vite est le meilleur choix - rapide, simple et cité dans la documentation de React.

Ra résume : « Vite est le moteur de nouvelle génération de ton vaisseau spatial React. Démarrage rapide, réactions instantanées aux changements de trajectoire et contrôle total de la configuration : tout ce dont tu as besoin pour conquérir la galaxie ! »

Code de cette leçon : App.jsx
1import React, { useState } from 'react';
2
3// Démonstration de la structure d'un projet Vite + React
4function ViteProjectDemo() {
5  const [activeFile, setActiveFile] = useState('App.jsx');
6
7  const fileStructure = [
8    { name: 'node_modules/', type: 'folder', description: 'Paquets installés' },
9    { name: 'public/', type: 'folder', description: 'Fichiers statiques' },
10    { name: '  vite.svg', type: 'file', description: 'Logo Vite' },
11    { name: 'src/', type: 'folder', description: 'Code source' },
12    { name: '  assets/', type: 'folder', description: 'Ressources (images, polices)' },
13    { name: '  App.jsx', type: 'file', description: 'Composant principal', active: true },
14    { name: '  App.css', type: 'file', description: 'Styles du composant' },
15    { name: '  main.jsx', type: 'file', description: "Point d'entrée" },
16    { name: '  index.css', type: 'file', description: 'Styles globaux' },
17    { name: 'index.html', type: 'file', description: 'HTML principal (à la racine !)' },
18    { name: 'vite.config.js', type: 'file', description: 'Configuration de Vite' },
19    { name: 'package.json', type: 'file', description: 'Configuration du projet' },
20  ];
21
22  const fileContents = {
23    'App.jsx': `import { useState } from 'react'
24import './App.css'
25
26function App() {
27  const [count, setCount] = useState(0)
28
29  return (
30    <>
31      <h1>Vite + React</h1>
32      <div className="card">
33        <button onClick={() => setCount(c => c + 1)}>
34          count is {count}
35        </button>
36      </div>
37    </>
38  )
39}
40
41export default App`,
42    'main.jsx': `import React from 'react'
43import ReactDOM from 'react-dom/client'
44import App from './App.jsx'
45import './index.css'
46
47ReactDOM.createRoot(
48  document.getElementById('root')
49).render(
50  <React.StrictMode>
51    <App />
52  </React.StrictMode>,
53)`,
54    'vite.config.js': `import { defineConfig } from 'vite'
55import react from '@vitejs/plugin-react'
56
57export default defineConfig({
58  plugins: [react()],
59})`,
60    'package.json': `{
61  "name": "mon-app",
62  "version": "0.0.0",
63  "type": "module",
64  "scripts": {
65    "dev": "vite",
66    "build": "vite build",
67    "preview": "vite preview"
68  },
69  "dependencies": {
70    "react": "^18.2.0",
71    "react-dom": "^18.2.0"
72  },
73  "devDependencies": {
74    "@vitejs/plugin-react": "^4.2.0",
75    "vite": "^5.0.0"
76  }
77}`
78  };
79
80  return (
81    <div style={{
82      fontFamily: 'Arial, sans-serif',
83      maxWidth: '1000px',
84      margin: '0 auto',
85      padding: '20px'
86    }}>
87      <header style={{
88        background: 'linear-gradient(135deg, #61dafb 0%, #21a1f1 100%)',
89        padding: '30px',
90        borderRadius: '12px',
91        color: 'white',
92        textAlign: 'center',
93        marginBottom: '30px'
94      }}>
95        <h1 style={{ margin: 0, fontSize: '2rem' }}>Vite + React</h1>
96        <p style={{ margin: '10px 0 0 0', opacity: 0.9 }}>
97          Structure du projet et fichiers de base
98        </p>
99      </header>
100
101      <div style={{
102        backgroundColor: '#1e1e1e',
103        borderRadius: '8px',
104        padding: '20px',
105        marginBottom: '30px',
106        fontFamily: 'monospace'
107      }}>
108        <div style={{ color: '#888', marginBottom: '10px' }}>Terminal:</div>
109        <div style={{ color: '#00ff00' }}>$ npm create vite@latest mon-app -- --template react</div>
110        <div style={{ color: '#888', marginTop: '5px' }}>Scaffolding project in /mon-app...</div>
111        <div style={{ color: '#00ff00', marginTop: '5px' }}>Done. Now run: cd mon-app && npm install && npm run dev</div>
112      </div>
113
114      <div style={{ display: 'grid', gridTemplateColumns: '300px 1fr', gap: '20px' }}>
115        <div style={{
116          backgroundColor: '#252526',
117          borderRadius: '8px',
118          padding: '15px'
119        }}>
120          <h3 style={{ color: '#cccccc', margin: '0 0 15px 0', fontSize: '14px' }}>
121            EXPLORER
122          </h3>
123          {fileStructure.map((item, index) => (
124            <div
125              key={index}
126              onClick={() => item.type === 'file' && setActiveFile(item.name.trim())}
127              style={{
128                padding: '8px 10px',
129                color: item.type === 'folder' ? '#dcb67a' : '#9cdcfe',
130                cursor: item.type === 'file' ? 'pointer' : 'default',
131                backgroundColor: activeFile === item.name.trim() ? '#094771' : 'transparent',
132                borderRadius: '4px',
133                fontSize: '14px',
134                fontFamily: 'monospace'
135              }}
136            >
137              {item.type === 'folder' ? '▸' : '•'} {item.name}
138            </div>
139          ))}
140        </div>
141
142        <div style={{
143          backgroundColor: '#1e1e1e',
144          borderRadius: '8px',
145          padding: '20px'
146        }}>
147          <div style={{
148            color: '#888',
149            fontSize: '12px',
150            marginBottom: '10px',
151            borderBottom: '1px solid #333',
152            paddingBottom: '10px'
153          }}>
154            {activeFile}
155          </div>
156          <pre style={{
157            color: '#d4d4d4',
158            margin: 0,
159            fontSize: '14px',
160            lineHeight: '1.5',
161            overflow: 'auto'
162          }}>
163            {fileContents[activeFile] || '// Choisis un fichier dans la liste'}
164          </pre>
165        </div>
166      </div>
167
168      <div style={{
169        marginTop: '30px',
170        padding: '20px',
171        backgroundColor: '#fff3e0',
172        borderRadius: '8px'
173      }}>
174        <h3 style={{ color: '#e65100', marginTop: 0 }}>Commandes de démarrage</h3>
175        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '15px' }}>
176          <div style={{ backgroundColor: 'white', padding: '15px', borderRadius: '8px' }}>
177            <code style={{ color: '#e65100' }}>npm run dev</code>
178            <p style={{ margin: '5px 0 0 0', fontSize: '14px', color: '#666' }}>
179              Démarre le serveur de développement
180            </p>
181          </div>
182          <div style={{ backgroundColor: 'white', padding: '15px', borderRadius: '8px' }}>
183            <code style={{ color: '#e65100' }}>npm run build</code>
184            <p style={{ margin: '5px 0 0 0', fontSize: '14px', color: '#666' }}>
185              Construit la version de production
186            </p>
187          </div>
188        </div>
189      </div>
190    </div>
191  );
192}
193
194export default function App() {
195  return <ViteProjectDemo />;
196}

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. 1. À quoi sert Vite dans l'écosystème React ?

  2. 2. Qu'est-ce que le hot reloading dans React ?

Tâches pratiques dans le jeu

  • Clique dans l'ordre

    Ordonne les étapes de création de ta première application React :

  • Tri vertical

    Ordonne les étapes de la transpilation du code par Babel, de haut en bas :

  • Éditeur de code

    Crée un simple composant App React qui affiche un titre et un paragraphe de bienvenue.

  • Clique dans l'ordre

    Construis la commande pour créer un nouveau projet React avec Vite :

Articles utiles