typescript - Jest não irá transformar o módulo - SyntaxError: Cannot use import statement outside a module
Não consegui me livrar deste erro SyntaxError: Cannot use import statement outside a module não importa o que eu tenha tentado e isso ficou tão frustrante. Alguém aqui já resolveu esse problema? Eu li um milhão de tópicos no Stack Overflow e issues no GitHub. Nenhuma solução clara.
Este é um projeto React, Typescript, Webpack. Estou tentando testar um módulo. Mas o Jest não irá transformar o módulo em javascript puro de alguma forma.
O erro que recebo é
/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 |
O que eu tentei para resolver isso (e não funcionou):
Usando a configuração
envembabel.config:env.test.preset: ['@babel/plugin-transform-modules-commonjs']modificando a configuração
transformno Jest como'^.+\\.jsx?$': 'babel-jest', '^.+\\.tsx?$': 'ts-jest'e todas as outras possibilidades relacionadas a isso.Na configuração do Jest,
testPathIgnorePatterns,transformIgnorePatternsUsando
.babel.config.jsem vez de.babelrc.js
...e mais.
Eu tenho esta configuração:
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')
})
})
Alguma ideia de como resolver esse problema?
Resposta #1
Embora eu os tenha testado separadamente, ainda não os testei juntos (transform e transformIgnorePatterns). Então, esta configuração do jest resolveu meu problema:
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"transform": {
"node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"
},
"transformIgnorePatterns": [
"node_modules/(?!variables/.*)"
]
},
Meus erros foram:
- Não usar
transformetransformIgnorePatternsjuntos. - E definir
babel-jestcomo o transformador em vez dets-jest(eu acho que isso é um problema quando o preset do jest é definido comots-jest. Porque se eu mudar parababel-jestele lança o mesmo erro novamente.):
--- "node_modules/variables/.+\\.(j|t)sx?$": "babel-jest"
+++ "node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"
Resposta #2
Use Vitest.
Eu tentei a maioria das sugestões feitas aqui. Achei o Jest bastante doloroso de instalar corretamente, enquanto o Vitest funciona imediatamente sem nenhuma configuração. Esta é a minha experiência pessoal. Demorei dias para fazer o Jest funcionar mais ou menos. Eu tinha o Vitest funcionando imediatamente após a instalação.
Eu não quero falar mal do Jest, na verdade eu acho que é uma ferramenta de testes maravilhosa e intuitiva. Mas, no final das contas, o Vitest "Simplesmente Funciona" (tm), e você pode usar a mesma API de estilo Jest simples que todos nós aprendemos a amar.
Passos (eu uso pnpm, mas claro que você poderia fazer o mesmo com yarn ou npm):
pnpm remove jest ts-jest @types/jest
pnpm add -D vite vitest
Exclua jest.config.js e crie 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,
},
})
Adicione aos seus testes:
import { assert, expect, test } from 'vitest'
Atualize seu package.json:
"test": "vitest",
Resposta #3
Meu problema era diferente de uma forma que o jest encontraria dificuldades em arquivos .js de uma das dependências no node_modules com SyntaxError: Cannot use import statement outside a module.
Eu tive que ter certeza de que ts-jest não iria ignorar (ao transformar) arquivos .js em uma dependência problemática.
Depois de ler atentamente sobre os presets, percebi que ele os deixa 'como estão' com preset: 'ts-jest'. Eu mudei para preset: 'ts-jest/presets/js-with-ts' e defini "allowJs": true em tsconfig.json.
Para não bagunçar o tsconfig.json do meu projeto, eu tenho um separado para o jest.
No final, meu jest.config.js se parece principalmente com isto:
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. Eu não precisei de um campo transform, já que o preset já está nele.
P.P.S. Eu não precisei configurar nenhum babel
Resposta #4
Como o Jest não está funcionando bem com esmodules, você precisa adicionar essas configurações em jest.config.js para dizer ao Jest para usar builds commonJS em vez disso
moduleNameMapper: {
'^variables$': 'variables/dist/cjs',
'^[NAME OF MODULE YOU WANT TO IMPORT]$': '[NAME OF MODULE YOU WANT TO IMPORT]/dist/cjs'
}
