Jean Jacques Bagui

React Native : comprendre l'erreur @providesModule naming collision

La litanie de commandes qui circule règle le symptôme une fois sur deux. Voici ce que Haste reproche réellement au projet, et comment supprimer la cause.

· 3 min de lecture · mis à jour le 3 août 2026

Un matin, le bundler refuse de démarrer :

jest-haste-map: @providesModule naming collision:
  Duplicate module name: react-native
  Paths: /node_modules/react-native/package.json collides with
         /node_modules/react-native-router-flux/node_modules/react-native/package.json

This warning is caused by a @providesModule declaration with the same name
across two different files.

La réponse qu'on trouve partout est un enchaînement de commandes. Elle fonctionne — parfois. Quand elle échoue, personne ne sait pourquoi, parce qu'elle ne dit pas ce qui cloche.

Ce que Metro reproche au projet

React Native n'utilise pas la résolution de modules de Node. Il s'appuie sur Haste, un système hérité de Facebook où chaque module est enregistré sous un nom global et unique, indépendamment de son chemin sur le disque.

Cette table est plate. Un nom, un module. Quand Haste rencontre deux package.json déclarant react-native, il ne peut pas choisir — et il s'arrête.

D'où vient le doublon ? De npm. Une dépendance déclare une contrainte incompatible avec la version installée à la racine :

// node_modules/react-native-router-flux/package.json
{ "dependencies": { "react-native": "^0.43.0" } }

Le projet est en 0.44.0, la contrainte impose 0.43.x : npm installe une seconde copie imbriquée. Deux copies sur le disque, deux déclarations du même nom Haste, collision.

C'est bien un problème d'arbre de dépendances — pas un problème de cache.

Poser le diagnostic

Avant de nettoyer quoi que ce soit, regardez l'arbre :

npm ls react-native
mon-app@1.0.0
├── react-native@0.44.0
└─┬ react-native-router-flux@3.38.0
  └── react-native@0.43.3   ← la copie imbriquée

La copie imbriquée est la cause. Tout le reste est du symptôme.

Corriger la cause

Trois issues, par ordre de préférence.

1. Aligner les versions. Si la dépendance sait fonctionner avec votre version de React Native, mettez-la à jour — c'est le cas le plus fréquent, la contrainte étant juste périmée :

npm install react-native-router-flux@latest
npm ls react-native   # doit ne montrer qu'une seule entrée

2. Forcer la déduplication. Quand les contraintes sont compatibles mais que l'arbre est resté imbriqué à cause d'un ordre d'installation malheureux :

npm dedupe

3. Imposer la résolution. En dernier recours, quand la dépendance déclare une contrainte trop stricte que vous savez fausse. Avec npm ≥ 8 :

{
  "overrides": {
    "react-native": "0.44.0"
  }
}

L'équivalent Yarn est le champ resolutions. À utiliser en connaissance de cause : vous affirmez que la dépendance fonctionnera avec une version qu'elle n'a pas déclarée.

Nettoyer les caches — ensuite

Une fois l'arbre corrigé, les caches gardent encore la trace de l'ancienne carte des modules. C'est que le nettoyage a un sens :

watchman watch-del-all              # oublier les répertoires surveillés
rm -rf node_modules && npm install  # réinstaller sur un arbre sain
rm -rf $TMPDIR/react-* $TMPDIR/metro-*
npm start -- --reset-cache          # invalider le cache du bundler

Fait dans cet ordre, ce nettoyage finalise la correction. Fait à la place de la correction, il la repousse au prochain npm install.

Et aujourd'hui ?

Depuis React Native 0.59, Metro a remplacé Haste par la résolution Node classique pour le code applicatif : deux copies d'une même bibliothèque peuvent coexister sans collision de noms. L'erreur @providesModule a donc largement disparu.

Le problème sous-jacent, lui, n'a pas bougé — il s'exprime autrement :

  • Invariant Violation: Tried to register two views with the same name (modules natifs dupliqués),
  • deux instances de React qui cassent les hooks,
  • une taille de bundle qui double sans raison apparente.

Le réflexe reste le même : npm ls <paquet> avant tout nettoyage. Un arbre de dépendances propre règle une classe entière de bugs que le cache ne fera que masquer.

Version réécrite et actualisée d'un article publié le 27 avril 2017 sur Medium.

Une première version de cet article a été publiée sur Medium.