Files
binome/GUIDE_DEVELOPPEMENT.md
Julien Calixte c433d0d7bf migrate to Vue3
2025-07-21 01:20:57 +02:00

644 lines
12 KiB
Markdown

# Guide de Développement - Application Binôme (Stack Moderne)
## 🚀 Vue d'Ensemble
L'application **Binôme** est maintenant basée sur une stack moderne Vue 3 + Vite + Pinia, optimisée pour le développement et la performance.
### Stack Technique
- **Frontend** : Vue 3.5.17 + TypeScript
- **Build Tool** : Vite 7.0.5
- **State Management** : Pinia 3.0.3 avec persistence
- **Routing** : Vue Router 4.5.1
- **Styling** : SCSS avec variables globales
- **PWA** : vite-plugin-pwa
- **Package Manager** : pnpm
- **Node.js** : v20 (LTS)
---
## 🛠️ Prérequis et Installation
### Prérequis Système
```bash
# Node.js version 20 (LTS)
node --version # doit afficher v20.x.x
# pnpm installé globalement
npm install -g pnpm@latest
```
### Installation du Projet
```bash
# Cloner le projet
git clone <repository-url>
cd binome
# Installer les dépendances
pnpm install
# Vérifier l'installation
pnpm dev
```
---
## 📜 Scripts Disponibles
### Scripts de Développement
```bash
# Démarrer le serveur de développement
pnpm dev
# → Lance Vite dev server sur http://localhost:8080
# → Hot Module Replacement (HMR) activé
# → Ouverture automatique du navigateur
# Prévisualiser la build de production
pnpm preview
# → Sert la version buildée localement
# → Utile pour tester avant déploiement
```
### Scripts de Build
```bash
# Build de production
pnpm build
# → Génère le dossier /dist optimisé
# → Minification et tree-shaking automatiques
# → Source maps incluses
# Analyser la build
pnpm build --analyze
# → Affiche la taille des bundles
# → Identifie les dépendances lourdes
```
### Scripts de Qualité
```bash
# Linter ESLint
pnpm lint
# → Vérifie et corrige automatiquement le code
# → Supporte .vue, .ts, .js files
# → Configuration dans .eslintrc.js
# Type checking TypeScript
pnpm type-check
# → Vérifie les types sans compilation
# → Utile en CI/CD
```
---
## 🏗️ Architecture du Projet
### Structure des Dossiers
```
src/
├── assets/ # Ressources statiques (SVG, images)
├── components/ # Composants Vue réutilisables
│ ├── ChilledMusic.vue
│ ├── DevSession.vue
│ ├── IntervalInput.vue
│ ├── SpotifyMusic.vue
│ ├── SWNewVersion.vue
│ └── ZoneMusic.vue
├── hooks/ # Composables Vue 3
│ ├── useInterval.ts
│ ├── useMusic.ts
│ ├── useSpotify.ts
│ ├── useTimer.ts
│ └── useWakeLock.ts
├── lib/ # Bibliothèques externes
│ └── spotify-player.js # ⚠️ CRITIQUE - Ne pas modifier
├── locales/ # Fichiers de traduction i18n
│ ├── en.json
│ └── fr.json
├── router/ # Configuration Vue Router
│ └── index.ts
├── store/ # Store Pinia
│ └── index.ts
├── styles/ # Styles SCSS globaux
│ ├── app.scss
│ ├── plume.scss
│ └── variables.scss
├── types/ # Types TypeScript
│ └── StopwatchState.ts
├── utils/ # Utilitaires
│ ├── notification.ts
│ └── spotify.ts
├── views/ # Pages/Vues principales
│ ├── Home.vue
│ ├── Privacy.vue
│ └── SpotifyCallback.vue
├── App.vue # Composant racine
├── i18n.ts # Configuration internationalisation
└── main.ts # Point d'entrée de l'application
```
---
## 🎯 Patterns de Développement
### 1. Composants Vue 3
#### Composition API avec `<script setup>`
```vue
<template>
<div class="my-component">
<h2>{{ title }}</h2>
<button @click="increment">Count: {{ count }}</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
// Props avec TypeScript
interface Props {
title: string
initialCount?: number
}
const props = withDefaults(defineProps<Props>(), {
initialCount: 0
})
// État réactif
const count = ref(props.initialCount)
// Méthodes
const increment = () => {
count.value++
}
// Émissions d'événements
const emit = defineEmits<{
countChanged: [value: number]
}>()
// Watcher
watch(count, (newValue) => {
emit('countChanged', newValue)
})
</script>
<style lang="scss" scoped>
.my-component {
padding: 1rem;
border: 1px solid $primary-color; // Variable SCSS globale
}
</style>
```
#### Composables (Hooks Personnalisés)
```typescript
// hooks/useCounter.ts
import { ref, computed } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const increment = () => count.value++
const decrement = () => count.value--
const reset = () => count.value = initialValue
const isEven = computed(() => count.value % 2 === 0)
return {
count: readonly(count),
increment,
decrement,
reset,
isEven
}
}
```
### 2. Store Pinia
#### Définition du Store
```typescript
// store/modules/timer.ts
import { defineStore } from 'pinia'
interface TimerState {
currentTime: number
isRunning: boolean
interval: number
}
export const useTimerStore = defineStore('timer', {
state: (): TimerState => ({
currentTime: 0,
isRunning: false,
interval: 5
}),
getters: {
formattedTime: (state) => {
const minutes = Math.floor(state.currentTime / 60)
const seconds = state.currentTime % 60
return `${minutes}:${seconds.toString().padStart(2, '0')}`
}
},
actions: {
startTimer() {
this.isRunning = true
},
stopTimer() {
this.isRunning = false
},
resetTimer() {
this.currentTime = 0
this.isRunning = false
}
},
// Persistence automatique
persist: {
key: 'timer-store',
storage: localStorage,
paths: ['interval'] // Seuls certains champs
}
})
```
#### Utilisation dans les Composants
```vue
<script setup lang="ts">
import { useTimerStore } from '@/store'
const timerStore = useTimerStore()
// Accès direct aux propriétés réactives
const { currentTime, isRunning, formattedTime } = storeToRefs(timerStore)
// Accès aux actions
const { startTimer, stopTimer, resetTimer } = timerStore
</script>
```
### 3. Internationalisation (i18n)
#### Utilisation dans les Composants
```vue
<template>
<div>
<h1>{{ $t('welcome.title') }}</h1>
<p>{{ $t('welcome.message', { name: userName }) }}</p>
</div>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n()
// Changement de langue
const switchLanguage = (lang: string) => {
locale.value = lang
}
</script>
```
#### Ajout de Nouvelles Traductions
```json
// locales/fr.json
{
"welcome": {
"title": "Bienvenue dans Binôme",
"message": "Bonjour {name}, prêt pour une session de programmation ?"
}
}
```
---
## 🎨 Styling et Thèmes
### Variables SCSS Globales
```scss
// styles/variables.scss
$primary-color: #f8efba;
$secondary-color: #333;
$font-family: 'Arial', sans-serif;
$border-radius: 8px;
$spacing-unit: 1rem;
// Breakpoints
$mobile: 768px;
$tablet: 1024px;
$desktop: 1200px;
```
### Utilisation dans les Composants
```vue
<style lang="scss" scoped>
.component {
background-color: $primary-color;
padding: $spacing-unit;
border-radius: $border-radius;
@media (max-width: $mobile) {
padding: $spacing-unit / 2;
}
}
</style>
```
---
## 🔧 Configuration de Développement
### Vite Configuration ([`vite.config.ts`](vite.config.ts:1))
```typescript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [
vue(),
VitePWA({
registerType: 'autoUpdate',
workbox: {
skipWaiting: true,
clientsClaim: true
}
})
],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
server: {
port: 8080,
open: true,
hmr: true
}
})
```
### TypeScript Configuration
```json
// tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"paths": {
"@/*": ["src/*"]
}
}
}
```
---
## 🧪 Tests et Qualité
### ESLint Configuration
```javascript
// .eslintrc.js
module.exports = {
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/typescript/recommended'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}
```
### Commandes de Vérification
```bash
# Vérification complète avant commit
pnpm lint && pnpm type-check && pnpm build
```
---
## 📱 PWA et Service Worker
### Configuration PWA
L'application est configurée comme PWA avec :
- **Manifest** : Icônes, couleurs, mode d'affichage
- **Service Worker** : Cache automatique, mise à jour en arrière-plan
- **Raccourcis** : Accès rapide aux fonctionnalités
### Gestion des Mises à Jour
```vue
<!-- components/SWNewVersion.vue -->
<template>
<div v-if="needRefresh" class="update-banner">
<p>{{ $t('notification.update.body') }}</p>
<button @click="updateSW">{{ $t('update') }}</button>
</div>
</template>
<script setup lang="ts">
import { useRegisterSW } from 'virtual:pwa-register/vue'
const { needRefresh, updateServiceWorker } = useRegisterSW()
const updateSW = async () => {
await updateServiceWorker()
}
</script>
```
---
## 🎵 Intégration Spotify
### Fichier Critique : [`spotify-player.js`](src/lib/spotify-player.js:1)
⚠️ **ATTENTION** : Ce fichier ne doit JAMAIS être modifié
- Contient le SDK Spotify personnalisé
- 571 lignes de code critique
- Toute modification peut casser l'intégration Spotify
### Utilisation du Player Spotify
```typescript
// hooks/useSpotify.ts
import { ref } from 'vue'
export function useSpotify() {
const player = ref<any>(null)
const isReady = ref(false)
const initializePlayer = (token: string) => {
// Utilisation du spotify-player.js
player.value = new window.Spotify.Player({
name: 'Binôme Player',
getOAuthToken: (cb: (token: string) => void) => {
cb(token)
}
})
}
return {
player,
isReady,
initializePlayer
}
}
```
---
## 🚀 Déploiement
### Build de Production
```bash
# Génération des fichiers optimisés
pnpm build
# Vérification de la build
pnpm preview
```
### Netlify (Configuration dans [`netlify.toml`](netlify.toml:1))
```toml
[build]
command = "pnpm build"
publish = "dist"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
```
### Variables d'Environnement
```bash
# .env.local (non versionné)
VITE_SPOTIFY_CLIENT_ID=your_client_id
VITE_API_BASE_URL=https://api.example.com
```
---
## 🐛 Debugging et Outils
### Vue DevTools
- Extension navigateur pour Vue 3
- Inspection des composants et du store Pinia
- Timeline des événements
### Vite DevTools
- HMR (Hot Module Replacement)
- Source maps automatiques
- Inspection des modules
### Console de Debug
```typescript
// Activation du debug en développement
if (import.meta.env.DEV) {
console.log('Mode développement activé')
// Exposition du store pour debug
window.__PINIA__ = pinia
}
```
---
## 📚 Ressources et Documentation
### Documentation Officielle
- [Vue 3](https://vuejs.org/)
- [Vite](https://vitejs.dev/)
- [Pinia](https://pinia.vuejs.org/)
- [Vue Router](https://router.vuejs.org/)
### Outils Recommandés
- **IDE** : VS Code avec extensions Vue
- **Extensions** : Vetur, TypeScript Vue Plugin
- **Browser** : Chrome/Firefox avec Vue DevTools
---
## 🔄 Workflow de Développement
### 1. Démarrage d'une Nouvelle Fonctionnalité
```bash
# Créer une branche
git checkout -b feature/nouvelle-fonctionnalite
# Démarrer le serveur de dev
pnpm dev
```
### 2. Développement
- Modifier les fichiers dans `src/`
- Tester en temps réel avec HMR
- Utiliser Vue DevTools pour debug
### 3. Tests et Validation
```bash
# Vérification du code
pnpm lint
# Build de test
pnpm build && pnpm preview
```
### 4. Commit et Push
```bash
# Commit avec message descriptif
git add .
git commit -m "feat: ajout de la nouvelle fonctionnalité"
git push origin feature/nouvelle-fonctionnalite
```
---
**Guide créé le 20 juillet 2025**
**Version de l'application** : Stack moderne Vue 3 + Vite + Pinia
**Prochaine mise à jour** : Après résolution des problèmes techniques identifiés