Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use top-level await #2057

Closed
dandv opened this issue Oct 23, 2020 · 26 comments
Closed

Can't use top-level await #2057

dandv opened this issue Oct 23, 2020 · 26 comments

Comments

@dandv
Copy link
Contributor

dandv commented Oct 23, 2020

🐛 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
@dandv dandv added Bug Report Needs Repo Need a minimium repository to reproduce the problem Needs Triage labels Oct 23, 2020
@ahnpnl
Copy link
Collaborator

ahnpnl commented Oct 23, 2020

Just to confirm, are you using node 14.3.0+ ?

@ahnpnl
Copy link
Collaborator

ahnpnl commented Oct 23, 2020

A source I found

With v14.8.0, top level await has been unflagged and now just works. The only catch is that top level await is only supported in ES modules. This means either adding "type": "module" to your package.json file or renaming your .js file to .mjs.

This means it only works within ESM, so ya it has to wait for jest full support ESM first #1709

@ahnpnl ahnpnl removed Bug Report Needs Repo Need a minimium repository to reproduce the problem labels Oct 23, 2020
@dandv
Copy link
Contributor Author

dandv commented Oct 23, 2020

Just to confirm, are you using node 14.3.0+ ?

Yes, I was using Node v14.10.1. BTW, the bug template could ask for that, so I've sent a PR.

@ahnpnl
Copy link
Collaborator

ahnpnl commented Oct 23, 2020

I put on hold for now while waiting for jestjs/jest#9860 (your issue 😃) because there is a need for guidance from jest how to do it for transformer.

@LinqLover
Copy link

I'm experiencing the same issue. The error message requires that "the 'module' option is set to 'esnext' or 'system'", but as per @ahnpnl your comment here, "jest expects module in your tsconfig.spec.ts to set to commonjs". Don't these requirements conflict which each other? How can I get this working?

#937 (comment)

@ahnpnl
Copy link
Collaborator

ahnpnl commented Jun 2, 2021

ts-jest v27 does support ESM. You can follow the ESM support documentation https://kulshekhar.github.io/ts-jest/docs/guides/esm-support

When turning on ESM mode, ts-jest will emit ESM codes based on module from your tsconfig. However, this emission depends on whether Jest allows it. If Jest allows, ts-jest will do its job to compile to ESM codes and after that Jest runs it.

Whether or not Jest can run it depends on Node version.

In general, ts-jest only takes care of compiling, not running the codes.

@LinqLover
Copy link

Thank you for clarification. I'm already using the latest node version. Looks as if my problem comes from another source ... But I have no clue from what. 😅

TomerAberbach/parse-imports#3 (comment)

@dandv
Copy link
Contributor Author

dandv commented Aug 17, 2021

I'm now able to use top-level await and simplify testing code with const = await ... instead of creating a bunch of variables and initializing them later in beforeAll(). Thanks!

@mayacoda
Copy link

mayacoda commented Aug 23, 2021

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

@dandv
Copy link
Contributor Author

dandv commented Aug 24, 2021

@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',
};

@mayacoda
Copy link

mayacoda commented Sep 1, 2021

Unfortunately, @dandv's solution didn't work for me either. I found a workaround in the meantime, but would still be very interested in getting top-level await working for tests.

@brendonco
Copy link

@mayacoda did you manage to test top level await?

@fernandopasik
Copy link

Isn't top level await a es2022 feature?
Typescript 4.5 will enable that I think
https://devblogs.microsoft.com/typescript/announcing-typescript-4-5-beta/#module-es2022

@mayacoda
Copy link

mayacoda commented Oct 3, 2021

@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.

@fernandopasik
Copy link

Thanks for clarifying. I tried as well and couldn't make it work. I got a empty and unknown error in jest

@HerbCaudill
Copy link

@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.

@mschipperheyn
Copy link

@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 does help, but using ESM creates a corollary issue that imports don't work as expected anymore (as described here: nodejs/node#32137), which require you to change a bunch of import statements.

@shrinktofit
Copy link

@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 does works. Another thing to note: if you had them transformed into CommonJS, you should clean all jest cache.

@Creative-Difficulty
Copy link

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

@samestep
Copy link

@Creative-Difficulty not sure why you mentioned me; I'm not a contributor to this repo.

@Creative-Difficulty
Copy link

I migrated to bun just today, sry for the ping

@jameshalsall
Copy link

This is very much still a problem.

@Creative-Difficulty
Copy link

@dandv Please reopen

@thekeith
Copy link

thekeith commented Dec 28, 2023

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

@dandv
Copy link
Contributor Author

dandv commented Mar 6, 2024

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.

@tony13tv
Copy link

tony13tv commented Nov 8, 2024

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 one was a life savior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests