Cours JavaScript et React · Module 1: Bases de React

Structure d'un projet React

14 min de lecture
Dans cette leçon8

Une structure de projet bien organisée est essentielle pour la maintenabilité du code, une navigation aisée et l'évolutivité des applications React. Dans cette leçon, nous examinerons les bonnes pratiques de structuration des projets React et comprendrons comment organiser les fichiers et les composants.

Structure de base d'un projet React

Quel que soit l'outil, un projet React plus conséquent (ici avec Vite) a généralement une structure similaire :

1my-react-project/
2├── node_modules/        # Dépendances installées
3├── public/              # Fichiers statiques accessibles publiquement
4├── src/                 # Code source de l'application
5│   ├── components/      # Composants réutilisables
6│   ├── pages/           # Composants représentant des pages entières
7│   ├── assets/          # Ressources telles qu'images, polices, etc.
8│   ├── utils/           # Fonctions utilitaires
9│   ├── services/        # Code responsable de la communication avec l'API
10│   ├── hooks/           # Hooks React personnalisés
11│   ├── context/         # Contextes React
12│   ├── App.jsx          # Composant principal de l'application
13│   └── main.jsx         # Point d'entrée de l'application
14├── index.html           # La page HTML dans laquelle l'application est chargée
15├── vite.config.js       # Configuration de Vite
16├── .gitignore           # Fichiers ignorés par Git
17├── package.json         # Infos du projet et dépendances
18└── README.md            # Documentation du projet

Examinons les répertoires les plus importants et leur rôle :

Le répertoire src/

Le répertoire src/ est le cœur de ton application React. Il contient toute la logique, les composants et les ressources. Voici comment ce répertoire est généralement organisé :

components/

Contient les composants réutilisables utilisés dans diverses parties de l'application. Il existe plusieurs approches pour structurer les composants :

Structure plate

1components/
2├── Button.jsx
3├── Button.css
4├── Header.jsx
5├── Header.css
6├── Footer.jsx
7└── Footer.css

Structure groupée (préférée pour les projets plus importants)

1components/
2├── Button/
3│   ├── Button.jsx
4│   ├── Button.css
5│   └── index.js
6├── Header/
7│   ├── Header.jsx
8│   ├── Header.css
9│   └── index.js
10└── Footer/
11    ├── Footer.jsx
12    ├── Footer.css
13    └── index.js

L'utilisation de fichiers index.js pour exporter les composants simplifie les imports :

1// Au lieu de :
2import Button from './components/Button/Button';
3
4// Tu peux écrire :
5import Button from './components/Button';

pages/

Composants représentant des pages ou des vues entières de l'application. Dans les projets avec routage, chaque fichier de ce répertoire correspond généralement à un chemin d'URL précis :

1pages/
2├── Home/
3│   ├── Home.jsx
4│   └── Home.css
5├── About/
6│   ├── About.jsx
7│   └── About.css
8└── Dashboard/
9    ├── Dashboard.jsx
10    └── Dashboard.css

assets/

Contient toutes les ressources statiques utilisées dans l'application :

1assets/
2├── images/
3│   ├── logo.png
4│   └── background.jpg
5├── fonts/
6│   ├── roboto.ttf
7│   └── open-sans.ttf
8└── styles/
9    ├── variables.css
10    └── global.css

utils/

Fonctions et outils utilitaires utilisés dans toute l'application :

1utils/
2├── formatDate.js
3├── validation.js
4└── helpers.js

services/

Code responsable de la communication avec des API ou services externes :

1services/
2├── api.js           # Configuration de base de l'API
3├── userService.js   # Requêtes liées aux utilisateurs
4└── productService.js # Requêtes liées aux produits

hooks/

Hooks React personnalisés pouvant être utilisés à plusieurs endroits de l'application :

1hooks/
2├── useLocalStorage.js
3├── useFetch.js
4└── useForm.js

context/

Contextes React utilisés pour gérer l'état global :

1context/
2├── AuthContext.js
3├── ThemeContext.js
4└── CartContext.js

Organisation par fonctionnalité vs par type

Il existe deux approches principales pour organiser le code :

Organisation par type (montrée ci-dessus)

Les fichiers sont regroupés par type (composants, hooks, services, etc.).

Organisation par fonctionnalité

Les fichiers sont regroupés par fonctionnalité ou partie de l'application :

1src/
2├── auth/
3│   ├── components/
4│   ├── hooks/
5│   ├── services/
6│   └── context/
7├── products/
8│   ├── components/
9│   ├── hooks/
10│   ├── services/
11│   └── utils/
12└── checkout/
13    ├── components/
14    ├── hooks/
15    └── services/

Cette structure est plus évolutive pour les grands projets, surtout lorsque plusieurs personnes y travaillent.

Conventions de nommage

Un nommage cohérent est tout aussi important que la structure des répertoires :

Composants

  • Utilise le PascalCase : Button.jsx, UserProfile.jsx
  • Les fichiers JSX devraient avoir l'extension .jsx (non obligatoire, mais cela facilite l'identification)

Hooks

  • Commencent toujours par « use » : useLocalStorage.js, useWindowSize.js

Contextes

  • Se terminent généralement par « Context » : AuthContext.js, ThemeContext.js

Services et utilitaires

  • Utilise le camelCase : apiService.js, formatDate.js

Les styles dans React

Il existe plusieurs approches pour organiser les styles dans React :

CSS Modules

1Button/
2├── Button.jsx
3└── Button.module.css

Styled Components

1Button/
2└── Button.jsx  # Contient les définitions styled-components

SCSS/SASS

1Button/
2├── Button.jsx
3└── Button.scss

Bonnes pratiques pour la structure des dossiers

Dans la flotte cosmique React, une structure de dossiers bien organisée est comme un système logistique efficace à bord d'un vaisseau spatial : chaque chose a sa place et tu peux rapidement trouver ce dont tu as besoin. Voici des pratiques éprouvées pour organiser les projets React.

Organisation par fonctionnalité vs par type

Deux approches principales pour organiser le code dans les projets React :

Organisation par type

Fichiers regroupés selon leur rôle technique : tous les composants ensemble, tous les hooks ensemble, etc.

1src/
2├── components/
3│   ├── Button/
4│   ├── Card/
5│   ├── Modal/
6│   ├── UserProfile/
7│   ├── ProductCard/
8│   └── ShoppingCart/
9├── hooks/
10│   ├── useAuth.js
11│   ├── useProducts.js
12│   └── useCart.js
13├── services/
14│   ├── authService.js
15│   ├── productService.js
16│   └── cartService.js
17└── utils/
18    ├── validators.js
19    └── formatters.js

Avantages :

  • Plus simple pour les petits et moyens projets
  • Facile à comprendre pour les nouveaux développeurs
  • Bon pour les applications SPA sans modules distincts

Inconvénients :

  • Dans les grands projets, il est difficile de retrouver tous les fichiers liés à une même fonctionnalité
  • Les composants de différentes fonctionnalités sont mélangés
  • Plus difficile à faire évoluer entre plusieurs équipes

Organisation par fonctionnalité

Fichiers regroupés par fonctionnalité métier : tous les fichiers liés à l'authentification ensemble, tous les fichiers liés aux produits ensemble, etc.

1src/
2├── features/
3│   ├── auth/
4│   │   ├── components/
5│   │   │   ├── LoginForm/
6│   │   │   ├── RegisterForm/
7│   │   │   └── PasswordReset/
8│   │   ├── hooks/
9│   │   │   ├── useAuth.js
10│   │   │   └── useSession.js
11│   │   ├── services/
12│   │   │   └── authService.js
13│   │   ├── utils/
14│   │   │   └── validators.js
15│   │   └── index.js
16│   │
17│   ├── products/
18│   │   ├── components/
19│   │   │   ├── ProductList/
20│   │   │   ├── ProductCard/
21│   │   │   └── ProductDetails/
22│   │   ├── hooks/
23│   │   │   ├── useProducts.js
24│   │   │   └── useProductFilters.js
25│   │   ├── services/
26│   │   │   └── productService.js
27│   │   └── index.js
28│   │
29│   └── cart/
30│       ├── components/
31│       │   ├── ShoppingCart/
32│       │   ├── CartItem/
33│       │   └── Checkout/
34│       ├── hooks/
35│       │   └── useCart.js
36│       ├── services/
37│       │   └── cartService.js
38│       └── index.js
39│
40├── shared/
41│   ├── components/
42│   │   ├── Button/
43│   │   ├── Modal/
44│   │   └── Card/
45│   ├── hooks/
46│   │   ├── useLocalStorage.js
47│   │   └── useDebounce.js
48│   └── utils/
49│       ├── formatDate.js
50│       └── formatCurrency.js
51│
52└── App.jsx

Avantages :

  • Plus facile à faire évoluer pour les grands projets
  • Tous les fichiers liés à une fonctionnalité sont au même endroit
  • Plus pratique pour le travail en équipe (différentes équipes peuvent travailler sur différentes fonctionnalités)
  • Plus facile de supprimer des fonctionnalités entières
  • Meilleur pour le découpage du code (code splitting)

Inconvénients :

  • Plus complexe pour les débutants
  • Demande plus de réflexion à la conception
  • Peut entraîner de la duplication pour de très petits composants

Conventions de nommage

Un nommage cohérent est un élément clé d'un projet bien organisé. Dans React, les conventions suivantes s'appliquent :

Composants - PascalCase

1// BON - PascalCase
2Button.jsx
3UserProfile.jsx
4ShoppingCart.jsx
5ProductCard.jsx
6
7// MAUVAIS - autres conventions
8button.jsx
9user-profile.jsx
10shopping_cart.jsx

Pourquoi le PascalCase ?

  • Il distingue les composants React des fonctions ordinaires
  • C'est une convention adoptée dans tout l'écosystème React
  • JSX exige le PascalCase pour les composants (balises personnalisées)

Hooks - camelCase avec le préfixe « use »

1// BON - camelCase avec « use »
2useAuth.js
3useLocalStorage.js
4useWindowSize.js
5useProductFilters.js
6
7// MAUVAIS - « use » manquant ou mauvaise convention
8Auth.js
9local-storage.js
10WindowSize.js

Pourquoi le préfixe « use » ?

  • React exige que les hooks personnalisés commencent par « use »
  • Il permet à React de valider les règles des hooks
  • Il indique immédiatement qu'il s'agit d'un hook

Contextes - PascalCase avec le suffixe « Context »

1// BON - PascalCase avec « Context »
2AuthContext.js
3ThemeContext.js
4CartContext.js
5UserPreferencesContext.js
6
7// MAUVAIS - « Context » manquant ou mauvaise convention
8auth.js
9theme-context.js
10Cart.js

Utilitaires et services - camelCase

1// BON - camelCase
2formatDate.js
3validateEmail.js
4apiService.js
5authService.js
6
7// MAUVAIS - autres conventions
8FormatDate.js
9validate-email.js
10API_Service.js

Où placer les différents types de fichiers

La planification de l'emplacement des fichiers dans un projet a une importance énorme pour sa lisibilité et son évolutivité.

Hooks (hooks personnalisés)

Approche par fonctionnalité :

1features/
2├── auth/
3│   └── hooks/
4│       ├── useAuth.js
5│       └── useSession.js
6└── products/
7    └── hooks/
8        └── useProducts.js
9
10shared/
11└── hooks/
12    ├── useLocalStorage.js  # Hook partagé
13    ├── useDebounce.js      # Hook partagé
14    └── useFetch.js         # Hook partagé

Approche par type :

1hooks/
2├── useAuth.js
3├── useSession.js
4├── useProducts.js
5├── useLocalStorage.js
6├── useDebounce.js
7└── useFetch.js

Utils (fonctions utilitaires)

Approche par fonctionnalité :

1features/
2├── products/
3│   └── utils/
4│       ├── formatPrice.js
5│       └── filterProducts.js
6└── auth/
7    └── utils/
8        └── validatePassword.js
9
10shared/
11└── utils/
12    ├── formatDate.js       # Partagé
13    ├── debounce.js         # Partagé
14    └── cloneDeep.js        # Partagé

Approche par type :

1utils/
2├── formatPrice.js
3├── formatDate.js
4├── validatePassword.js
5├── filterProducts.js
6├── debounce.js
7└── cloneDeep.js

Types (TypeScript)

Si tu utilises TypeScript, tu as plusieurs options pour les types :

Option 1 : À côté des fichiers qui les utilisent :

1components/
2└── Button/
3    ├── Button.tsx
4    ├── Button.types.ts     # Types uniquement pour Button
5    ├── Button.styles.ts
6    └── index.ts

Option 2 : Types centralisés :

1types/
2├── user.types.ts
3├── product.types.ts
4├── cart.types.ts
5└── api.types.ts

Option 3 : Hybride (le meilleur) :

1features/
2└── products/
3    ├── components/
4    ├── types/              # Types spécifiques à la fonctionnalité
5    │   ├── product.types.ts
6    │   └── filter.types.ts
7    └── index.ts
8
9shared/
10└── types/                  # Types partagés
11    ├── common.types.ts
12    └── api.types.ts

Exemple de structure de projet - bonnes pratiques

Combiner l'organisation par fonctionnalité pour les fonctionnalités principales et par type pour les ressources partagées :

1my-react-app/
2├── public/
3├── src/
4│   ├── features/                    # Fonctionnalités principales
5│   │   ├── auth/
6│   │   │   ├── components/
7│   │   │   │   ├── LoginForm/
8│   │   │   │   │   ├── LoginForm.tsx
9│   │   │   │   │   ├── LoginForm.styles.ts
10│   │   │   │   │   ├── LoginForm.test.tsx
11│   │   │   │   │   └── index.ts
12│   │   │   │   └── RegisterForm/
13│   │   │   ├── hooks/
14│   │   │   │   ├── useAuth.ts
15│   │   │   │   └── useSession.ts
16│   │   │   ├── services/
17│   │   │   │   └── authService.ts
18│   │   │   ├── types/
19│   │   │   │   └── auth.types.ts
20│   │   │   └── index.ts
21│   │   │
22│   │   ├── products/
23│   │   │   ├── components/
24│   │   │   │   ├── ProductList/
25│   │   │   │   ├── ProductCard/
26│   │   │   │   └── ProductFilters/
27│   │   │   ├── hooks/
28│   │   │   │   ├── useProducts.ts
29│   │   │   │   └── useProductFilters.ts
30│   │   │   ├── services/
31│   │   │   │   └── productService.ts
32│   │   │   ├── types/
33│   │   │   │   └── product.types.ts
34│   │   │   └── index.ts
35│   │   │
36│   │   └── cart/
37│   │       └── [structure similaire]
38│   │
39│   ├── shared/                      # Ressources partagées
40│   │   ├── components/
41│   │   │   ├── Button/
42│   │   │   │   ├── Button.tsx
43│   │   │   │   ├── Button.styles.ts
44│   │   │   │   ├── Button.test.tsx
45│   │   │   │   └── index.ts
46│   │   │   ├── Modal/
47│   │   │   ├── Card/
48│   │   │   └── Layout/
49│   │   │
50│   │   ├── hooks/
51│   │   │   ├── useLocalStorage.ts
52│   │   │   ├── useDebounce.ts
53│   │   │   └── useFetch.ts
54│   │   │
55│   │   ├── utils/
56│   │   │   ├── formatDate.ts
57│   │   │   ├── validators.ts
58│   │   │   └── helpers.ts
59│   │   │
60│   │   ├── types/
61│   │   │   ├── common.types.ts
62│   │   │   └── api.types.ts
63│   │   │
64│   │   └── constants/
65│   │       ├── routes.ts
66│   │       └── config.ts
67│   │
68│   ├── layouts/                     # Composants de mise en page
69│   │   ├── MainLayout/
70│   │   ├── AuthLayout/
71│   │   └── DashboardLayout/
72│   │
73│   ├── pages/                       # Composants de page (pour le routage)
74│   │   ├── HomePage/
75│   │   ├── ProductsPage/
76│   │   ├── ProductDetailPage/
77│   │   └── CartPage/
78│   │
79│   ├── context/                     # Contextes globaux
80│   │   ├── AuthContext.tsx
81│   │   ├── ThemeContext.tsx
82│   │   └── CartContext.tsx
83│   │
84│   ├── router/                      # Configuration du routage
85│   │   ├── routes.tsx
86│   │   └── ProtectedRoute.tsx
87│   │
88│   ├── styles/                      # Styles globaux
89│   │   ├── globals.css
90│   │   ├── variables.css
91│   │   └── reset.css
92│   │
93│   ├── App.tsx
94│   └── index.tsx
95│
96├── .eslintrc.js
97├── .prettierrc
98├── tsconfig.json
99├── package.json
100└── README.md

Règles d'organisation des fichiers

  1. Règle des 3 niveaux maximum
    • Évite d'imbriquer au-delà de 3 niveaux
    • Si tu as besoin de plus, ta structure est probablement trop complexe
1// BON - 3 niveaux
2src/features/products/components/
3
4// MAUVAIS - trop profond
5src/modules/ecommerce/features/products/ui/components/
  1. Export via index.ts
    • Chaque dossier contenant un composant possède un index.ts
    • Cela simplifie les imports et masque les détails d'implémentation
1// components/Button/index.ts
2export { default } from './Button';
3export * from './Button.types';
4
5// Utilisation
6import Button from './components/Button';  // lisible
7// au lieu de
8import Button from './components/Button/Button';  // verbeux
  1. Colocation - garder ensemble ce qui est utilisé ensemble
    • Les styles à côté du composant
    • Les tests à côté du composant
    • Les types à côté du composant
1Button/
2├── Button.tsx          # Composant
3├── Button.styles.ts    # Styles
4├── Button.test.tsx     # Tests
5├── Button.types.ts     # Types
6└── index.ts            # Export
  1. Partagé vs spécifique à une fonctionnalité
    • Si quelque chose est utilisé à plus de 2 endroits -> shared
    • Si quelque chose est spécifique à une fonctionnalité -> garde-le dans la fonctionnalité

Conseils pratiques pour la structure d'un projet

  1. Commence simplement - Ne surconçois pas une structure complexe au début d'un projet. Pour une petite application, l'organisation par type peut suffire ; tu pourras ensuite refactoriser vers l'organisation par fonctionnalité à mesure que le projet grandit.

  2. Refactorise au besoin - Adapte la structure à mesure que le projet évolue. Si un dossier contient plus de 10-15 fichiers, envisage de le scinder.

  3. Garde les composants petits - Les composants devraient être petits et concentrés sur une seule tâche. Si un composant dépasse 200-300 lignes, envisage de le scinder.

  4. Regroupe les fichiers liés - Garde ensemble les fichiers étroitement liés. Si tu édites toujours deux fichiers ensemble, ils devraient probablement être dans le même dossier.

  5. Documente - Ajoute un README.md aux principaux répertoires pour expliquer leur but et leur structure.

  6. La cohérence avant tout - Une fois ton organisation choisie (par type, par fonctionnalité ou l'approche hybride décrite plus haut), tiens-t'y dans tout le projet. Le pire est de mélanger les styles au hasard.

Outils qui aident à organiser le code

  1. ESLint - Aide à maintenir un style de code cohérent et à détecter les erreurs potentielles
  2. Prettier - Formate automatiquement le code selon des règles établies
  3. Import sorter - Trie les imports pour une meilleure lisibilité
  4. Alias de chemins (path aliases) - Simplifie les imports à l'aide d'alias comme @components, @utils
1// tsconfig.json ou jsconfig.json
2{
3  "compilerOptions": {
4    "baseUrl": "src",
5    "paths": {
6      "@components/*": ["shared/components/*"],
7      "@features/*": ["features/*"],
8      "@utils/*": ["shared/utils/*"],
9      "@hooks/*": ["shared/hooks/*"]
10    }
11  }
12}
13
14// Utilisation
15import Button from '@components/Button';
16import { useAuth } from '@features/auth';
17import { formatDate } from '@utils/formatDate';

Une structure de projet bien organisée facilite grandement le travail, surtout dans les grandes équipes et les grands projets. N'oublie pas qu'il n'existe pas une seule « bonne » structure : le plus important est qu'elle soit cohérente, logique pour ton équipe et évolutive à mesure que le projet grandit.

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. Quel est le rôle principal du dossier src/ dans un projet React ?

  2. 2. Dans quel dossier se trouvent les principaux fichiers source de React ?

  3. 3. Où se trouve le fichier index.html dans un projet React créé avec Vite ?

Tâches pratiques dans le jeu

  • Tri vertical

    Ordonne la hiérarchie des fichiers d'une application React :

  • Clique dans l'ordre

    Ordonne le flux de travail de développement React :

  • Éditeur de code

    Dans App.jsx, crée la structure de base d'un composant : un import de React, un composant fonctionnel App qui renvoie du JSX et un export par défaut (export default).

Articles utiles