9

I'm trying to use a top level await during testing with Jest but Jest complains that

error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.

Here's the file (src/lib/mongodb.ts)which is problematic:

import { MongoClient } from 'mongodb';
import mongoUri from 'mongo-uri-tool';
import { getMongoURI } from './settings/settings.js';

const getConnectionOptions = () => {
  const uri = getMongoURI();

  return {
    uri,
    parsedUri: mongoUri.parseUri(uri),
  };
};

const connectToMongoDB = async () => {
  const connectionOptions = getConnectionOptions();

  const mongodb = await MongoClient.connect(connectionOptions.uri);

  return mongodb.db(connectionOptions.parsedUri.db);
};

export const MongoDB = await connectToMongoDB();

Here's the test (src/api/trips/trips.test.ts) file which is ultimately import the above:

import { Trips } from './index'; // <--------- this is the import which leads to importing mongodb
import generateId from '../../lib/generateId';

describe('find trip by id', () => {
  test('find trip by id', async () => {
    const id = generateId();
    const slug = 'lol';
    await Trips.insertOne({ _id: id, slug });

    const trip = await Trips.findOne({ _id: id });
    expect(trip._id).toStrictEqual(id);
  });
});

When I run npx tsc no problems are reported:

11:12AM /Users/paymahn/code/tripvector/tripvector-mono/backend testing ✭ ✱ ➜ ◼
 ❮❮❮ npx tsc
11:12AM /Users/paymahn/code/tripvector/tripvector-mono/backend testing ✭ ✱ ➜ ◼

Here's my tsconfig.json which has the correct module and target:

{
    "compilerOptions": {
      "sourceMap": true,
      "esModuleInterop": true,
      "allowJs": true,
      "noImplicitAny": true,
      "moduleResolution": "node",
      "lib": ["es2022", "DOM"],
      "module": "es2022",
      "target": "es2017",
      "rootDir": "src",
      "baseUrl": ".",
      "paths": {
        "*": ["node_modules/*", "src/types/*"]
      },
      "types": ["node", "jest"],
      "typeRoots": ["node_modules/@types", "src/types"],
      "outDir": "./built"
    },
    "include": ["./src/**/*", "jest.config.js"],
    "exclude": ["node_modules", "dist"]
  }

and here's my jest.config.cjs:

const { jsWithTsESM: tsjPreset } = require("ts-jest/presets");

module.exports = {
  ...tsjPreset,
  globals: {
    "ts-jest": {
      tsconfig: "tsconfig.json",
    }
  },
  testEnvironment: 'node',
  moduleFileExtensions: ["ts", "js"],
  testRegex: ".*.test.ts"
};

Here's my project structure:

enter image description here

Why is it that Jest and ts-jest complain that I can't use a top-level await but tsc and my IDE (Webstorm) don't complain at all? How can I correctly configure Jest and ts-jest to allow top level awaits with ESM for both JS and TS files (I'm slowly migrating from JS to TS)?

Note that Jest was working great until I added the first test which relies on a top level await. It seems I have Jest and ts-jest correctly configured to work with ESM and a mix of JS and TS files. The new problem is figuring out top level awaits with ts-jest.

EDIT: if I add @ts-ignore to the problematic top level await, I get another similar issue reported by Jest:

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
export const MongoDB = await connectToMongoDB();
    Details:

    /Users/paymahn/code/tripvector/tripvector-mono/backend/src/lib/mongodb.ts:24
    exports.MongoDB = await connectToMongoDB();
                      ^^^^^

    SyntaxError: await is only valid in async functions and the top level bodies of modules

Could this be an issue of which version of node I'm using? I'm currently using v17:

11:53AM /Users/paymahn/code/tripvector/tripvector-mono/backend testing ✭ ✱ ➜ ◼
 ❯❯❯ node --version
v17.6.0
11:53AM /Users/paymahn/code/tripvector/tripvector-mono/backend testing ✭ ✱ ➜ ◼
 ❯❯❯ npm --version
7.6.0

EDIT: interesting, I migrated to mocha and executing mocha with -n loader=ts-node/esm works perfectly. I wonder what's going on with jest...

Paymahn Moghadasian
  • 9,301
  • 13
  • 56
  • 94
  • If you like to check it out, I ran into a similar issue and resolved it. See repro repo https://github.com/RimuTec/express-testing I then got stuck on an issue with vscode-jest-runner which I observe for the "Debug" only but not for the "Run" command. I've filed an issue https://github.com/firsttris/vscode-jest-runner/issues/278 Although this latter issue may be unrelated to your scenario, perhaps the repro repo with its config may help, in particular see setting for "module" in "tsconfig.json". – Manfred Oct 03 '22 at 04:13
  • Does this answer your question? [Jest won't accept top-level-awaits with NodeJS16 & TypeScript](https://stackoverflow.com/questions/70725063/jest-wont-accept-top-level-awaits-with-nodejs16-typescript) – mikemaccana Feb 21 '23 at 14:06
  • You're not the only one, almost everyone using TS Jest has had this issue. – mikemaccana Feb 21 '23 at 14:07

0 Answers0