Comment corriger l'erreur « Cannot use import statement outside a module »
Vous écrivez une instruction import propre, exécutez votre code, et vous tombez immédiatement sur ceci :
SyntaxError: Cannot use import statement outside a module
Cette erreur liée aux modules ES de JavaScript est l’une des sources de confusion les plus courantes pour les développeurs travaillant avec Node.js, les navigateurs et les environnements de test. La correction n’est pas toujours la même — et appliquer la mauvaise solution aggrave les choses. Voici comment diagnostiquer votre situation et la résoudre correctement.
Points clés à retenir
- Cette erreur est un problème d’incompatibilité de système de modules, pas une erreur de syntaxe — votre environnement d’exécution attendait du CommonJS mais a rencontré la syntaxe
importdes modules ES. - Dans Node.js, définissez
"type": "module"danspackage.jsonou utilisez l’extension de fichier.mjspour activer l’ESM. - Dans les navigateurs, ajoutez
type="module"à votre balise<script>pour que le moteur traite le fichier comme un module ES. - Dans Jest, configurez Babel pour transformer l’ESM en CommonJS, et ajustez
transformIgnorePatternspour les packages tiers exclusivement ESM. - Diagnostiquez toujours votre environnement en premier — Node.js, navigateur ou test runner — avant d’appliquer une correction.
Pourquoi cette erreur se produit
L’erreur signifie que votre environnement d’exécution a rencontré la syntaxe des modules ES (import) mais attendait autre chose — généralement du CommonJS (require). C’est une incompatibilité de système de modules, pas une erreur de syntaxe dans votre code.
JavaScript dispose de deux systèmes de modules :
| Système | Syntaxe | Par défaut dans |
|---|---|---|
| CommonJS (CJS) | require() | Node.js (legacy) |
| Modules ES (ESM) | import | Navigateurs, Node.js moderne |
L’environnement d’exécution décide quel système utiliser en fonction de la configuration — pas du code lui-même. C’est pourquoi la même instruction import fonctionne dans un projet et échoue dans un autre.
Comment corriger l’erreur Import Statement Outside Module dans Node.js
Node.js traite les fichiers .js comme du CommonJS sauf si "type": "module" est défini dans package.json. Pour utiliser import, vous devez explicitement activer l’ESM.
Option 1 : Définir "type": "module" dans package.json
{
"name": "my-app",
"version": "1.0.0",
"type": "module"
}
Cela indique à Node.js de traiter tous les fichiers .js du projet comme des modules ES. Consultez la documentation officielle sur les modules ES de Node.js pour plus de détails sur la façon dont Node détermine le type de module.
Option 2 : Utiliser l’extension de fichier .mjs
Renommez votre fichier de app.js en app.mjs. Node.js traite toujours les fichiers .mjs comme de l’ESM, indépendamment de package.json.
Option 3 : Utiliser .cjs pour les fichiers CommonJS
Si votre projet utilise "type": "module" mais qu’un fichier a besoin de require(), donnez-lui une extension .cjs.
Important : N’ajoutez pas simplement
"type": "module"sans vérifier vos autres fichiers. Tout fichier utilisantrequire(),module.exportsou__dirnamene fonctionnera plus sous ESM.
Corriger l’erreur dans le JavaScript navigateur
Dans les navigateurs, l’import statique ne fonctionne qu’à l’intérieur d’un script module. Si votre balise <script> ne déclare pas type="module", le navigateur la traite comme un script classique et rejette la syntaxe import.
<!-- Ceci génèrera l'erreur -->
<script src="app.js"></script>
<!-- Ceci fonctionne -->
<script type="module" src="app.js"></script>
Ce comportement fait partie de la spécification standard des modules JavaScript implémentée par les navigateurs modernes.
Notez que les scripts modules ont une portée limitée — les variables déclarées à l’intérieur ne sont pas disponibles globalement. C’est pourquoi vous pourriez ajouter type="module" et ensuite voir une ReferenceError pour une variable que vous pensiez globale. La solution est d’exporter et d’importer les valeurs explicitement plutôt que de s’appuyer sur la portée globale.
Discover how at OpenReplay.com.
Corriger l’erreur dans Jest et autres environnements de test
Jest s’exécute dans Node.js et utilise traditionnellement CommonJS par défaut, même si votre code source utilise l’ESM. C’est une source courante de l’erreur « cannot use import statement outside a module » dans les suites de tests.
Une approche consiste à configurer Babel pour transformer l’ESM en CommonJS pendant les tests :
// babel.config.js
module.exports = {
presets: ['@babel/preset-env'],
}
Alternativement, Jest peut être configuré pour exécuter les tests en mode ESM natif si votre projet utilise déjà les modules ES. Consultez la documentation Jest sur les modules ECMAScript pour plus de détails.
Si un package tiers (comme swiper, lodash-es, ou des bibliothèques similaires exclusivement ESM) provoque l’erreur, vous devez indiquer à Jest de le transformer au lieu de l’ignorer :
// jest.config.js
module.exports = {
transformIgnorePatterns: [
'/node_modules/(?!(swiper|ssr-window|dom7)/)',
],
}
Le point clé : transformIgnorePatterns utilise une assertion anticipée négative. Vous dites « ignore tout dans node_modules sauf ces packages ». Les lister dans des entrées de tableau séparées ne fonctionnera pas — ils doivent être combinés dans un seul motif regex avec |.
Configuration TypeScript
Si vous utilisez TypeScript, vérifiez votre tsconfig.json. Le champ module contrôle quelle syntaxe de module TypeScript émet dans sa sortie compilée :
{
"compilerOptions": {
"module": "ESNext",
"target": "ESNext"
}
}
Définir module sur CommonJS tout en écrivant des instructions import est du TypeScript valide — le compilateur transformera import en require() dans la sortie. Cependant, définir module sur ESNext tout en exécutant la sortie dans un environnement Node.js CommonJS (sans "type": "module" dans package.json) déclenchera l’erreur à l’exécution. Assurez-vous que le paramètre module de votre tsconfig.json correspond à ce que votre environnement d’exécution attend réellement.
Diagnostiquez avant de corriger
La même erreur apparaît dans différents environnements pour différentes raisons. Avant d’appliquer une correction, demandez-vous :
- Où l’erreur se produit-elle — Node.js, navigateur ou test runner ?
- Que dit le champ
"type"de votrepackage.json? - Utilisez-vous un bundler, ou exécutez-vous les fichiers directement ?
Répondre à ces trois questions vous oriente vers la bonne solution à chaque fois.
FAQ
Oui, mais vous devez utiliser les extensions de fichier pour les distinguer. Les fichiers avec une extension .mjs sont toujours traités comme des modules ES, et les fichiers avec une extension .cjs sont toujours traités comme du CommonJS, indépendamment du champ type dans package.json. Cela vous permet d'utiliser les deux systèmes côte à côte dans un seul projet.
Non. Chaque package dans node_modules a son propre package.json, donc votre champ type s'applique uniquement aux fichiers de votre projet. Les dépendances définissent leur propre système de modules indépendamment. L'erreur provient généralement de vos propres fichiers ou de l'importation d'une dépendance exclusivement ESM dans un contexte CommonJS sans transformation appropriée.
Les bundlers comme Webpack et Vite traitent les instructions import pendant l'étape de build et produisent un seul fichier de sortie. Ils résolvent la syntaxe des modules avant que l'environnement d'exécution ne la voie. Lorsque vous exécutez des fichiers directement dans Node.js ou un navigateur sans bundler, l'environnement d'exécution lui-même doit comprendre le format de module, c'est là que les incompatibilités causent cette erreur.
Ces variables globales CommonJS ne sont pas disponibles dans les modules ES. À la place, vous pouvez les reconstruire en utilisant import.meta.url. Par exemple, utilisez new URL(import.meta.url).pathname pour obtenir le chemin du fichier, ou combinez-le avec le module path et fileURLToPath du module url pour reproduire le comportement de __dirname.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.