Debug et Logs
SmartCommon fournit un système de logs colorés pour faciliter le debug de votre application.
Activer le mode debug
Dans la configuration du Provider :
const config = {
debug: true, // Active les logs globalement
api: {
debug: true // Active les logs API spécifiquement
}
};
En développement, utilisez la variable d'environnement :
const config = {
debug: import.meta.env.DEV // true en dev, false en prod
};
Utilitaire log
SmartCommon exporte un utilitaire log avec des méthodes colorées :
import { log } from '@cap-rel/smartcommon';
// Logs d'état
log.state('Changement d\'état:', newState);
log.globalState('État global mis à jour:', globalState);
// Logs de cycle de vie
log.effect('useEffect déclenché');
log.page('Page chargée: /dashboard');
// Logs de statut
log.success('Opération réussie');
log.error('Une erreur est survenue:', error);
log.warning('Attention:', message);
log.info('Information:', data);
// Logs API
log.apiLoading('GET', '/api/items');
log.apiSuccess('GET - 200', '/api/items');
log.apiError('GET - 404', '/api/items');
// Logs base de données
log.db('INSERT:', item);
// Logs de localisation
log.location('Navigation vers:', path);
// Log personnalisé
log.custom('MON_TAG', 'purple', 'Mon message', data);
Couleurs des logs
Chaque type de log a une couleur distincte dans la console :
| Méthode | Couleur | Usage |
|---|---|---|
log.state | Bleu | Changements d'état local |
log.globalState | Cyan foncé | Changements d'état global |
log.effect | Violet | Effets React (useEffect) |
log.page | Orange | Chargement de pages |
log.success | Vert | Opérations réussies |
log.error | Rouge | Erreurs |
log.warning | Doré | Avertissements |
log.info | Gris | Informations |
log.apiLoading | Gris | Requête API en cours |
log.apiSuccess | Vert | Requête API réussie |
log.apiError | Rouge | Requête API échouée |
log.db | Bleu nuit | Opérations IndexedDB |
log.location | Rose | Navigation |
createLogger - Logger avec namespace
Pour les projets plus complexes, createLogger permet de créer un logger avec un namespace dédié. Les logs peuvent être filtrés par namespace via localStorage.LOG_FILTER.
import { createLogger } from '@cap-rel/smartcommon';
const logger = createLogger('MyModule');
logger.info('Module initialisé');
logger.success('Données chargées');
logger.error('Échec du chargement');
logger.warning('Données périmées');
logger.state('Changement local:', newState);
logger.globalState('Changement global:', data);
logger.effect('useEffect déclenché');
logger.page('/dashboard');
logger.db('INSERT', item);
// API (premier paramètre = label dynamique)
logger.apiLoading('GET /items');
logger.apiSuccess('GET /items', data);
logger.apiError('GET /items', error);
// Personnalisé
logger.custom('PERF', 'orange', 'Rendu en 12ms');
// Groupes
logger.group('Initialisation');
logger.info('Étape 1');
logger.info('Étape 2');
logger.groupEnd();
Filtrer par namespace
Dans la console du navigateur :
localStorage.LOG_FILTER = 'MyModule,Auth'; // Affiche uniquement ces namespaces localStorage.LOG_LEVEL = 'warn'; // debug | info | warn | error
DebugConsole - Console intégrée
Le composant DebugConsole affiche les logs SmartCommon directement dans l'application (FAB flottant >_ en bas à gauche, panneau avec toolbar de recherche/filtres, logs colorés auto-scrollés).
Activation
La DebugConsole est montée par le Provider uniquement si la prop debug est passée explicitement (ce n'est PAS config.debug qui la déclenche, mais la prop du Provider lui-même) :
import { Provider } from '@cap-rel/smartcommon';
// Active uniquement en mode développement
<Provider config={config} debug={import.meta.env.DEV}>
<App />
</Provider>
// Toujours active
<Provider config={config} debug>
<App />
</Provider>
La prop config.debug reste indépendante : elle contrôle la verbosité des logs produits par les hooks SmartCommon (useStates, useGlobalStates, useApi, etc.), indépendamment de l'affichage de la DebugConsole.
Props
| Prop | Type | Défaut | Description |
|---|---|---|---|
defaultOpen | boolean | false | Console ouverte au démarrage |
position | string | “bottom” | Position : “bottom”, “top”, “left”, “right” |
height | string/number | “40vh” | Hauteur de la console |
maxLogs | number | 500 | Nombre maximum de logs conservés |
showFab | boolean | true | Afficher le bouton flottant “>_” |
Utilisation manuelle (sans Provider)
import { DebugConsole } from '@cap-rel/smartcommon';
<DebugConsole defaultOpen={true} position="bottom" maxLogs={200} />
La console peut être détachée dans une fenêtre séparée via le bouton de détachement. Les logs sont partagés entre les fenêtres via BroadcastChannel.
DebugWarnings - Breakpoints automatiques sur warnings React
Le composant DebugWarnings intercepte console.error pendant qu'il est monté et déclenche debugger dès qu'un warning React connu est émis. Les DevTools (Firefox ou Chrome) mettent alors l'exécution en pause pile au moment du warning, avec la pile React complète accessible pour identifier le composant fautif.
Quand les DevTools sont fermées, debugger est un no-op : aucun impact sur l'exécution normale.
Activation
Comme la DebugConsole, DebugWarnings est automatiquement monté par le Provider quand la prop debug est passée :
<Provider config={config} debug={import.meta.env.DEV}>
<App />
</Provider>
Inactif en production (quand debug est false / absent). Aucune configuration supplémentaire nécessaire dans les projets SmartMaker.
Warnings interceptés
Les motifs suivants déclenchent un breakpoint automatique :
Received NaN for the value attribute- NaN passé à un<input>value prop on input should not be null-value={null}sur un inputchanging a controlled input to be uncontrolled-valuepasse de défini àundefinedchanging an uncontrolled input to be controlled- inverseEach child in a list should have a unique “key”-keymanquante dans un.map()Maximum update depth exceeded- boucle infinie de re-rendersCannot update a component- setState pendant le render d'un autre composantWarning: Failed prop type- prop-types violéWarning: React does not recognize- prop non standard passée au DOM
Diagnostic automatique avant le breakpoint
Avant de déclencher debugger, DebugWarnings affiche un console.group orange contenant :
- Raw console.error args : tableau brut des arguments de React (utile si React inclut un
componentStack) - React hint : extraction du “Check the render method of
XXX” quand React le mentionne - Suspects ciblés : pour les warnings
valueetNaN, la liste des fibers dontmemoizedProps.valuecorrespond au problème, avec l'owner React et la source.jsx - Dump complet des fibers de formulaire (
console.table) : tous les<input>,<textarea>,<select>du DOM avec leurvalue,type,name,owner(nom du composant parent React) etsource(fichier:ligne:col si disponible)
Le dump est construit en parcourant tous les fiber roots via window.REACTDEVTOOLSGLOBALHOOK_. React DevTools doit être installé dans le navigateur pour que le fallback fonctionne complètement.
Dans 90% des cas la table console.table suffit à identifier visuellement la ligne qui a une valeur inattendue (undefined, NaN, null, type incohérent).
### Usage avec les DevTools
- Ouvre les DevTools (F12)
- Onglet Console : repère le bloc orange [DebugWarnings]
- Déroule la table des form fibers → spot la ligne avec une valeur anormale → tu as owner et source
- Si besoin de la Call Stack React : onglet Debugger, l'exécution est en pause sur debugger dans DebugWarnings/index.jsx
- Avec les source maps activées (voir Configuration Vite pour debug ci-dessous), cliquer sur source t'amène directement au fichier .jsx
### Utilisation manuelle
Si tu veux activer uniquement les breakpoints sans la DebugConsole UI :
DebugConsole
import { DebugWarnings } from '@cap-rel/smartcommon';
<App>
{import.meta.env.DEV && <DebugWarnings />}
...
</App>
Ou inversement : sans les breakpoints en le montant manuellement au lieu d'utiliser la prop debug du Provider.
## Configuration Vite pour debug
Le vite.config.js de SmartCommon (et celui de tout projet SmartMaker qui produit une lib) est configuré pour deux modes de build :
npm run buildjavascript
const shouldMinify = process.env.MINIFY !== "false";
export default defineConfig({
build: {
sourcemap: true, // Toujours generer les source maps
minify: shouldMinify, // Minifier sauf si MINIFY=false
lib: { ... }
},
...
});
### Deux modes
^ Commande ^ Usage ^ Taille dist ^
| | Build prod minifié + sourcemap | Normal (~1.2 MB pour smartcommon) |
| MINIFY=false npm run build | Build dev lisible + sourcemap | Plus gros (~1.7 MB) mais noms originaux preserves |
### Pourquoi les source maps
Sans source maps, les stack traces dans Firefox / Chrome affichent des noms minifiés (FM, Nn, ee2…) impossibles à interpreter.
Avec source maps :
* La Call Stack affiche les vrais noms de composants (Tabbar, SignaturePad, HomePage…)
* Cliquer sur une frame t'amène directement au .jsx source, ligne exacte
* DebugWarnings renseigne le champ source dans ses dumps (fichier:ligne:col)
* React DevTools peut remonter correctement aux composants applicatifs
Dans Firefox, si tu vois le message « Le mappage des noms originaux est désactivé », coche « Afficher les variables originales » dans le panneau Portées du Debugger.
### Pourquoi le mode non-minifié (MINIFY=false)
Même avec les source maps, le code minifié peut résister au débugage (noms de variables locales compactés, reassignments hors ordre…). Le mode MINIFY=false garde tous les noms originaux dans le bundle lui-même, ce qui rend le debugger beaucoup plus lisible quand tu mets des breakpoint dans le source smartcommon.
Règle : utiliser MINIFY=false uniquement pour débugger en local, jamais pour la publication.
## Workflow de développement local avec smartcommon
Pour itérer rapidement sur smartcommon sans avoir à publier une version npm à chaque changement, utiliser un symlink depuis les node_modules du projet consommateur.
### Setup initial
dist/bash
# Dans le projet consommateur (ex. smartInterventions mobile)
cd ~/dev/monprojet/mobile
rm -rf node_modules/@cap-rel/smartcommon
ln -s ~/dev/smartcommon node_modules/@cap-rel/smartcommon
Le projet consommateur lit directement le de ~/dev/smartcommon/ via le symlink.
### Boucle de dev
- Modifier le source dans ~/dev/smartcommon/src/
- cd ~/dev/smartcommon && MINIFY=false npm run build (4-5 secondes)
- Dans le projet consommateur : rm -rf node_modules/.vite (purge du pre-bundle Vite)
- Vite recharge automatiquement au prochain hit
### Avantages / inconvénients
* Avantages : pas de npm publish, pas d'attente d'indexation du registre, pas de bump de version à chaque test
* Inconvénient : il faut purger .vite/ à chaque rebuild car Vite pre-bundle les node_modules
### Retour au mode normal
Pour reinstaller la version du registre :
debug: truebash
rm ~/dev/monprojet/mobile/node_modules/@cap-rel/smartcommon
cd ~/dev/monprojet/mobile
npm install @cap-rel/smartcommon@<version>
## Logs automatiques
Quand est activé, SmartCommon log automatiquement :
### useStates
STATE
const st = useStates({
initialStates: { count: 0 },
debug: true // Active les logs pour ce hook
});
st.set('count', 1);
// Console: [STATE] SET count => 1
### useGlobalStates
const gst = useGlobalStates();
gst.local.set('user', userData);
// Console: [GLOBAL STATE] SET user => {...}
### useDb
const db = useDb({
name: 'myApp',
stores: { items: 'id++' },
debug: true
});
await db.items.add({ name: 'Item' });
// Console: [DB] CREATE key = 1, item = {...}
### useApi
// Avec api.debug: true dans la config
api.private.get('items');
// Console: [GET - LOADING] https://api.example.com/items
// Console: [GET - 200] https://api.example.com/items
## Debug conditionnel
Activez le debug uniquement pour certains hooks :
// Debug global désactivé
const config = { debug: false };
// Mais debug activé pour un hook spécifique
const st = useStates({
initialStates: { ... },
debug: true // Override la config globale
});
## Console du navigateur
Les logs SmartCommon utilisent des styles CSS dans la console. Pour les voir correctement :
1. Ouvrez les DevTools (F12)
2. Allez dans l'onglet “Console”
3. Assurez-vous que le filtre “Verbose” est activé
### Filtrer les logs
Dans la console, utilisez le filtre pour afficher uniquement certains types :
* Tapez pour voir les logs d'état
* Tapez API pour voir les logs API
* Tapez DB'' pour voir les logs base de données
## Bonnes pratiques
### Désactiver en production
const config = {
debug: import.meta.env.DEV,
api: {
debug: import.meta.env.DEV
}
};
### Logs personnalisés dans vos composants
import { log } from '@cap-rel/smartcommon';
import { useLibConfig } from '@cap-rel/smartcommon';
const MyComponent = () => {
const { debug } = useLibConfig();
const handleClick = () => {
if (debug) {
log.custom('MY_COMPONENT', 'teal', 'Button clicked');
}
// ...
};
};
### Ne pas logger de données sensibles
// Mauvais
log.info('User logged in:', { password: user.password });
// Bon
log.info('User logged in:', { id: user.id, email: user.email });
## Voir aussi
* Configuration - Configuration du Provider
* Hooks - Documentation des hooks