typescript - Jest ne transformera pas le module - SyntaxError : Impossible d'utiliser l'instruction import en dehors d'un module
Je n'ai pas pu me débarrasser de cette erreur SyntaxError: Cannot use import statement outside a module peu importe ce que j'ai essayé et c'était tellement frustrant. Y a-t-il quelqu'un ici qui a résolu ce problème ? J'ai lu des millions de fils de discussion sur Stack Overflow et GitHub. Aucune solution claire.
Ceci est un projet React, Typescript, Webpack. J'essaie de tester un module. Mais Jest ne transforme pas le module en javascript simple d'une manière ou d'une autre.
L'erreur que je reçois est
/Users/me/dev/Project/project/node_modules/variables/src/variables.js:12
import './main.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
17 |
18 | */
> 19 | import { GlobalVars } from 'variables'
| ^
20 |
21 | export const Vars = new GlobalVars()
22 |
Ce que j'ai essayé pour résoudre cela (et qui n'a pas fonctionné) :
Utilisation de la configuration
envdansbabel.config:env.test.preset : ['@babel/plugin-transform-modules-commonjs']modifier la configuration
transformdans Jest comme'^.+\\.jsx?': 'babel-jest', '^.+\\.tsx?': 'ts-jest'et toutes les autres possibilités autour de cela.Dans la configuration de Jest,
testPathIgnorePatterns,transformIgnorePatternsUtiliser
.babel.config.jsau lieu de.babelrc.js
...et plus.
J'ai cette configuration :
package.json
"jest": {
"preset": "ts-jest",
"testEnvironment": "node"
}
.babelrc.js
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-react',
'@babel/preset-typescript',
],
plugins: [
'@babel/plugin-transform-runtime',
'@babel/proposal-class-properties',
'@babel/transform-regenerator',
'@babel/plugin-transform-template-literals',
'react-hot-loader/babel',
],
}
variables.ts
import { GlobalVars } from 'variables'
export const Vars = new GlobalVars()
variables.spec.ts
import { Vars } from './variables.ts'
describe('Test The Package', () => {
it('Should accept new variables', () => {
Vars.newVariable = 'new variable'
expect(Vars.newVariable).toEqual('new variable')
})
})
Une idée sur la façon de résoudre ce problème ?
Réponse #1
Même si je les ai essayés séparément, je ne les ai pas essayés ensemble (transform et transformIgnorePatterns). Donc, cette configuration de jest a résolu mon problème :
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"transform": {
"node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"
},
"transformIgnorePatterns": [
"node_modules/(?!variables/.*)"
]
},
Mes erreurs étaient :
- Ne pas utiliser
transformettransformIgnorePatternsensemble. - Et définir
babel-jestcomme transformateur au lieu dets-jest(je suppose que c’est un problème lorsque le pré-réglage de jest est défini commets-jest. Parce que si je le change pourbabel-jest, cela renvoie à nouveau la même erreur.)
--- "node_modules/variables/.+\\.(j|t)sx?$": "babel-jest"
+++ "node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"
Réponse #2
Utilisez Vitest.
J'ai essayé la plupart des suggestions faites ici. J'ai trouvé que Jest était assez difficile à installer correctement, tandis que Vitest fonctionne immédiatement sans aucune configuration. C'est mon expérience personnelle. Il m'a fallu des jours pour que Jest fonctionne un peu. J'ai eu Vitest qui fonctionnait immédiatement après l'installation.
Je ne veux pas critiquer Jest, je pense en fait que c'est un outil de test merveilleux et intuitif. Mais en fin de compte, Vitest « fonctionne simplement » (tm), et vous pouvez utiliser la même API simple de style Jest que nous avons tous appris à aimer.
Étapes (j'utilise pnpm, mais bien sûr vous pourriez faire la même chose avec yarn ou npm) :
pnpm remove jest ts-jest @types/jest
pnpm add -D vite vitest
Supprimez jest.config.js et créez vite.config.ts :
/// <reference types="vitest" />
import { defineConfig } from 'vite'
export default defineConfig({
test: {
/* for example, use global to avoid globals imports (describe, test, expect): */
// globals: true,
},
})
Ajouter à vos tests :
import { assert, expect, test } from 'vitest'
Mettez à jour votre package.json :
"test": "vitest",
Réponse #3
Mon problème était différent d’une manière que jest échouait sur les fichiers .js de l’une des dépendances dans node_modules avec SyntaxError: Cannot use import statement outside a module.
Je devais m'assurer que ts-jest n'ignore pas (lors de la transformation) les fichiers .js dans la dépendance problématique.
Après avoir lu attentivement à propos des presets, j'ai réalisé que cela les laisse « tels quels » avec preset: 'ts-jest'. Je l'ai changé en preset: 'ts-jest/presets/js-with-ts' et j'ai défini "allowJs": true dans tsconfig.json.
Pour ne pas gâcher le tsconfig.json de mon projet, j'en ai un séparé pour jest.
Finalement, mon jest.config.js ressemble principalement à ceci :
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: "node",
globals: {
'ts-jest': {
tsconfig: '<rootDir>/test/tsconfig.json',
},
},
transformIgnorePatterns: [
"node_modules/(?!troublesome-dependency/.*)",
],
}
P.S. Je n'avais pas besoin d'un champ transform, puisque le préréglage est déjà dessus.
P.P.S. Je n'ai pas eu besoin d'ajouter de configuration babel
Réponse #4
Puisque Jest ne fonctionne pas bien avec les esmodules, vous devez ajouter ces configurations dans jest.config.js pour indiquer à Jest d'utiliser les builds commonJS à la place
moduleNameMapper: {
'^variables$': 'variables/dist/cjs',
'^[NAME OF MODULE YOU WANT TO IMPORT]$': '[NAME OF MODULE YOU WANT TO IMPORT]/dist/cjs'
}
