Tristan
Tristan•2y ago

I m hitting an issue where Jest tests in

I'm hitting an issue where Jest tests in Node.js of ConvexHttpClient seem generate an error "You need to run with a version of node that supports ES Modules in the VM API. See https://jestjs.io/docs/ecmascript-modules." Following those instructions does allow tests to run, but then it appears to cause random segfaults. Before going down the ESM rabbit hole, does this ring a bell? I'd like to avoid setting NODE experimental flags.
24 Replies
Tristan
TristanOP•2y ago
A minimal repro is:
import { expect, test } from "@jest/globals";
import { ConvexHttpClient } from "convex/browser";
import { API } from "../convex/_generated/api";

const url = "https://mellow-meerkat-454.convex.cloud";

test("basic get and set", async () => {
const client = new ConvexHttpClient<API>(url);
const workflowId = await client.mutation("createWorkflow")({
displayName: "Test Workflow",
});
const workflow = await client.query("getWorkflow")({ id: workflowId });
expect(workflowId.equals(workflow._id)).toBe(true);
expect(workflow.displayName).toEqual("Test Workflow");
});
import { expect, test } from "@jest/globals";
import { ConvexHttpClient } from "convex/browser";
import { API } from "../convex/_generated/api";

const url = "https://mellow-meerkat-454.convex.cloud";

test("basic get and set", async () => {
const client = new ConvexHttpClient<API>(url);
const workflowId = await client.mutation("createWorkflow")({
displayName: "Test Workflow",
});
const workflow = await client.query("getWorkflow")({ id: workflowId });
expect(workflowId.equals(workflow._id)).toBe(true);
expect(workflow.displayName).toEqual("Test Workflow");
});
ballingt
ballingt•2y ago
This does ring a bell, unfortunately. We have a blog post coming out tomorrow about using https://vitest.dev/, partly because there are fewer configuration rabbit holes. Next.js' config for babel + Jest + TypeScript works well with Convex, but it's involved. @Tristan for finding something that works, is this a JavaScript or TypeScript file? oh sorry, obviously TypeScript (I see some angle brackets)
Tristan
TristanOP•2y ago
Yeah Typescript. Currently using ts-jest.
ballingt
ballingt•2y ago
We ought to choose a couple common configurations and show demos of them, both to show config to copy and to make sure we keep them working.
Tristan
TristanOP•2y ago
I did try a few different tsconfig settings to see if that helped, but understanding tsconfig these days is tough.
ballingt
ballingt•2y ago
what does your jest.config.js look like? If you're not using ts-jest/presets/js-with-babel you might try that one, but I'm not confident that will work
Tristan
TristanOP•2y ago
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
};
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
};
ballingt
ballingt•2y ago
I'd guess the issue is one of - ts-jest not transforming the import syntax in the generated .js files like convex/_generated/server.js - ts-jest importing the wrong builds of the convex package Any luck if you change the preset from ts-jest to ts-jest/presets/js-with-babel? or ha the other one ts-jest/presets/js-with-ts, might as well try all three 🥹 but seeing this is helpful, we can put together an example of - using Convex with Node.js (edit from Next.js, whoops) - testing with Jest - TypeScript - ts-jest How are you compiling/bundling/running your code (not in tests), so we can do the same in an example? and also - not using --experimental-vm-modules and finally, what version of Node.js?
Tristan
TristanOP•2y ago
no luck
ballingt
ballingt•2y ago
thanks for giving it a shot, sorry about this! the most painless course (if it's not an existing project with a big test suite to migrate) might be vitest, but we need to solve this for the majority of users out there, who use jest, so expect some Jest guidance soon in docs or a Stack post
Tristan
TristanOP•2y ago
I'm not currently using Next for this. I started with the Turborepo Next.js starter but am just doing this in a library. The tsconfig is
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Default",
"compilerOptions": {
"composite": false,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"inlineSources": false,
"isolatedModules": true,
"moduleResolution": "node",
"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveWatchOutput": true,
"skipLibCheck": true,
"strict": true
},
"exclude": ["node_modules"]
}
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Default",
"compilerOptions": {
"composite": false,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"inlineSources": false,
"isolatedModules": true,
"moduleResolution": "node",
"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveWatchOutput": true,
"skipLibCheck": true,
"strict": true
},
"exclude": ["node_modules"]
}
ballingt
ballingt•2y ago
typo from me, I said Next when I mean Node
Tristan
TristanOP•2y ago
I'm assuming the convex/tsconfig.json can be ignored?
ballingt
ballingt•2y ago
for the purposes of ts-jest? I'm not sure, haven't dug into how this works
Tristan
TristanOP•2y ago
Yeah. I don't think that's issue since I can comment out the API import and avoid the generated code and I still see the error.
ballingt
ballingt•2y ago
If you're able to share the repo happy to poke at your config (I'm thomasballinger on GitHub), otherwise I'll get an example repo that follows the setup you described setup in CI so we can make sure it works and keeps working
Tristan
TristanOP•2y ago
I'll see if I can quickly pull out something standalone
Tristan
TristanOP•2y ago
GitHub
GitHub - tristanz/convex-ts-jest
Contribute to tristanz/convex-ts-jest development by creating an account on GitHub.
ballingt
ballingt•2y ago
peeking at this a little tonight, the test runs fine until it hits the import of node-fetch — so neither of the issues I was anticipating. If you're using Node.js 18 then a small change on our side should fix this, since Node.js 18 ships with fetch natively
Tristan
TristanOP•2y ago
Interesting. Yes I’m on 18. FWIW, vitest did work out of the box for me. I'll give that a spin for now. It looks like jest runs tests within the vm module, which causes some issue for node-fetch.
ballingt
ballingt•2y ago
There's a release likely coming out today with the node-fetch fix in it that should fix this particular issue, but Vitest is honestly what I'd recommend in general at this point.
Tristan
TristanOP•2y ago
It does seem nice. Now I'm trying to understanding the vite vs turbopack communities...
jamwt
jamwt•2y ago
@Tristan by sheer coincidence, we just published today: https://stack.convex.dev/testing-react-components-with-convex
Testing React Components with Convex
In this article, we’ll explore options for testing React components that call Convex React hooks using mocking and dependency injection. To do this, I...
ballingt
ballingt•2y ago
@Tristan Convex 0.9.0, out a few minutes ago, has this HTTP fix which should make the HTTP client just work with ts-jest in Node.js 18.

Did you find this page helpful?