typescript - Jest vil ikke transformere modulen - SyntaxError: Kan ikke bruke import-setning utenfor en modul


Jeg klarte ikke å bli kvitt denne SyntaxError: Cannot use import statement outside a module feilen uansett hva jeg har prøvd, og det ble så frustrerende. Er det noen her som har løst dette problemet? Jeg har lest millioner av Stack Overflow- og GitHub-tråder. Ingen klare løsninger.

Dette er et React-, Typescript- og Webpack-prosjekt. Jeg prøver å teste en modul. Men Jest klarer på en eller annen måte ikke å transformere modulen til vanlig JavaScript.

Feilen jeg får er

/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 | 

Hva jeg har prøvd for å løse dette (og det fungerte ikke):

  • Bruke env-oppsett i babel.config: env.test.preset: ['@babel/plugin-transform-modules-commonjs']

  • endre transform-oppsett i Jest-konfigurasjon til '^.+\\.jsx?$': 'babel-jest', '^.+\\.tsx?$': 'ts-jest' og alle andre muligheter rundt dette.

  • I Jest-konfigurasjon, testPathIgnorePatterns, transformIgnorePatterns

  • Bruke .babel.config.js i stedet for .babelrc.js

...og mer.

Jeg har denne oppsettet:

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')
  })
})

Noen idé om hvordan man kan løse dette problemet?

Svar #1

Selv om jeg har prøvd dem hver for seg, har jeg ikke prøvd dem sammen (transform og transformIgnorePatterns). Så denne Jest-konfigurasjonen løste problemet mitt:

  "jest": {
    "preset": "ts-jest",
    "testEnvironment": "node",
    "transform": {
      "node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!variables/.*)"
    ]
  },

Mine feil var:

  1. Ikke bruke transform og transformIgnorePatterns sammen.
  2. Og å definere babel-jest som transformatoren i stedet for ts-jest (jeg antar at det er et problem når preset for jest er definert som ts-jest. For hvis jeg endrer det til å være babel-jest, kaster det samme feilen igjen.):
--- "node_modules/variables/.+\\.(j|t)sx?$": "babel-jest"
+++ "node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"

Svar #2

Bruk Vitest.

Jeg har prøvd de fleste av forslagene som er nevnt her. Jeg syntes det var ganske smertefullt å installere Jest riktig, mens Vitest fungerer rett ut av boksen uten noen konfigurasjon. Dette er min personlige erfaring. Det tok meg dager å få Jest til å fungere sånn noenlunde. Jeg hadde Vitest fungerende umiddelbart etter installasjon.

Jeg vil ikke hate på Jest, jeg synes faktisk det er et fantastisk og intuitivt testverktøy. Men i siste instans «Just Works» Vitest (tm), og du kan bruke den samme enkle Jest-stil API-en vi alle har blitt glad i.

Trinn (jeg bruker pnpm, men selvfølgelig kan du gjøre det samme med yarn eller npm):

pnpm remove jest ts-jest @types/jest
pnpm add -D vite vitest

Slett jest.config.js, og lag 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,
  },
})

Legg til i testene dine:

import { assert, expect, test } from 'vitest'

Oppdater din package.json:

"test": "vitest",

Svar #3

Mitt problem var på en måte annerledes slik at jest ville snuble på .js-filer fra en av avhengighetene i node_modules med SyntaxError: Cannot use import statement outside a module.

Jeg måtte forsikre meg om at ts-jest ikke ville ignorere (når den transformerer) .js-filer i problematisk avhengighet.

Etter å ha lest nøye om forhåndsinnstillinger, innså jeg at det lar dem være 'som de er' med preset: 'ts-jest'. Jeg endret det til preset: 'ts-jest/presets/js-with-ts' og satte "allowJs": true i tsconfig.json.

For å ikke ødelegge prosjektets tsconfig.json, har jeg en separat en for jest.

Til slutt ser min jest.config.js hovedsakelig slik ut:

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. Jeg trengte ikke et transform-felt, siden forhåndsinnstillingen allerede er på det.

P.P.S. Jeg trengte ikke å legge til noen babel-konfigurasjon

Svar #4

Siden Jest ikke fungerer godt med esmoduler, må du legge til disse konfigurasjonene i jest.config.js for å fortelle Jest å bruke commonJS-bygninger i stedet

moduleNameMapper: {
  '^variables$': 'variables/dist/cjs',
  '^[NAME OF MODULE YOU WANT TO IMPORT]$': '[NAME OF MODULE YOU WANT TO IMPORT]/dist/cjs'
}

Relaterte artikler