ts-jest: Can't use top-level await

🐛 Bug Report

Not sure if I’m doing something wrong, or if TLA isn’t supposed to work due to #1709.

To Reproduce

cd into the cloned repro repo, npm install, npm test.

Expected behavior

The test should pass.

Link to repo (highly encouraged)

https://github.com/dandv/ts-jest-tla

envinfo

System:
    OS: Ubuntu Linux 20

Npm packages:
    jest: 26.6.0
    ts-jest: 26.4.1
    typescript: 4.0.3
    babel(optional): not used

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 15
  • Comments: 25 (4 by maintainers)

Most upvoted comments

@mayacoda @brendonco I struggled with this for a bit and finally got it working — see my fork of @dandv’s repo here: https://github.com/HerbCaudill/ts-jest-tla

The key things to make sure of are:

  • You need jest and ts-jest version 27 or higher.

  • These settings need to be in your Jest config:

    "jest": {
      "preset": "ts-jest/presets/default-esm",
      "globals": {
        "ts-jest": {
          "useESM": true
        }
      }
    }
    
  • You need "type": "module" in package.json.

  • In tsconfig.json, you need

      "target": "esnext",
      "module": "esnext"
    

    (The top-level await error says that targeting es2017 or higher would work, but only esnext has worked for me.)

  • Jest needs to be run with the --experimental-vm-modules flag. For example my test script looks like this:

    "test": "node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js"
    

    The --no-warnings flag isn’t strictly necessary, but otherwise you get yelled at on every test run that --experimental-vm-modules is experimental. 🙄

Hope this helps others who run into this.

This is very much still a problem.

@dandv Please reopen

@mayacoda: I used the ESM preset too. The manual configuration led to some error.

module.exports = {
  // https://jestjs.io/docs/ecmascript-modules
  transform: {},
  // https://kulshekhar.github.io/ts-jest/docs/guides/esm-support/#use-esm-presets; 'manual configuration' didn't work
  preset: 'ts-jest/presets/default-esm',
  globals: {
    'ts-jest': {
      useESM: true,
    },
  },
  testEnvironment: 'node',
  testRegex: '.*.test.ts',
};

I’m also getting this issue. Based on the discussion in this thread, this is what my jest.config.js looks like, but it still doesn’t work 😭 I have no clue what you did @dandv, but please share your wisdom.

module.exports = {
  preset: 'ts-jest/presets/default-esm',
  testEnvironment: 'node',
  moduleFileExtensions: [ ...defaults.moduleFileExtensions, 'ts' ],
  globals: {
    'ts-jest': {
      tsconfig: {
        module: 'ESNext',
        target: 'ES2017'
      },
      useESM: true
    }
  }
}

envinfo

System:
    OS: macOS 11.5.1

Npm packages:
    jest: 27.0.6
    ts-jest: 27.0.5
    typescript: 4.3.4
    babel(optional): not used

Node: 16.6.0

Actually the default ESM preset works for me with ts-jest 29.1.2, but only after a bunch of fiddling around that might have cleared the Jest cache, AND with the --experimental-vm-modules passed to node.

jest.config.ts:

import type { JestConfigWithTsJest } from 'ts-jest';

const jestConfig: JestConfigWithTsJest = {
  preset: 'ts-jest/presets/default-esm',
};

export default jestConfig;

tsconfig.json has module: esnext and target: esnext. I’m using Node v18.19.0.

@mayacoda did you manage to test top level await?

I was not able to get it to work with the above described settings, unfortunately.

As for support in TypeScript 4.5, the link @fernandopasik provided also says

This [top-level await] was already supported in --module esnext (and now–module nodenext), but es2022 is the first stable target for this feature.

Which makes me think it should already work with the configuration above and something else is preventing it. Hopefully, I’m wrong and it does get fixed with the new version of TypeScript.

After a lot of spinning wheels tonight, I found a solution that may work for more recent versions.

In order to allow a top-level await, you’ll need to do something slightly different in your jest config.

In jest.config.cjs I used:

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  extensionsToTreatAsEsm: ['.ts'],
  transform: {
    // '^.+\\.[tj]sx?$' to process js/ts with `ts-jest`
    // '^.+\\.m?[tj]sx?$' to process js/ts/mjs/mts with `ts-jest`
    '^.+\\.[tj]sx?$': [
      'ts-jest',
      {
        useESM: true,
      },
    ],
  },
};

I’m use ts-jest and @types/jest in addition. This combined with my tsconfig allowed a top level await to work.

tsconfig.json:

{
  "compilerOptions": {
    "target": "es2022",
    "moduleResolution": "node16",
    "module":"node16",
    "outDir": ".",
    "strict": true,
    "esModuleInterop": true,
  },
  "include": ["_worker.ts"],
  "exclude": ["node_modules"]
}

Edit: forgot to add I changed my test command in package.json to the following:

node --experimental-vm-modules node_modules/.bin/jest

This issue is not fixed, pls reopen someone @dandv @samestep