avajs / typescript

Test TypeScript projects using AVA.
MIT License
73 stars 16 forks source link

Excessive memory use in ava 4, leading to out of memory errors #44

Closed corinnaSchultz closed 2 years ago

corinnaSchultz commented 2 years ago

What you're trying to do I have a suite of tests that run and work fine with Ava 3. I would like to upgrade to Ava 4.

What happened When I upgraded to Ava 4, I started to get constant timeouts, especially when I ran with -u. I tracked the issue down to Javascript heap memory being exhausted. On a recent run, I opened my Activity Monitor (I'm on Mac Moneterey), and saw over 10GB is memory being used by node shortly before the test run exited with another timeout.

I tried running with every version from ava 4.0.0 through the current version 4.3.1, and none of them finished with all my tests running.

I didn't not change anything about the config when I upgraded (other than renaming the file to mjs); though I also tried disabling the worker threads, that didn't help the issue.

I saw the timeout failures on my local machine, as well as our Jenkins/Docker-based CICD build machine.

What you expected to happen I expect that tests working under Ava 3 would still work with Ava 4. I would expect that memory consumption would be similar (though I still find it excessive, especially for running in a CI/CD build machine).

I have been unable to find relevant documentation to help me understand what's going on, though it probably has something to do with ts-node and compilation. It would be helpful if there were actual error messages other than just a timeout message.

I found github discussions suggesting precompiling, or using transpile-only, but those solutions didn't work for me; I got a bunch of type-related errors as ava couldn't seem to resolve various identifiers. I'm also not sure if it's possible to maybe use ava with my webpack bundle instead of the source tree.

Any pointers to documentation describing alternatives to just running ts-node would be helpful

Config files:

ava.config.mjs:

export default {
  extensions: ['ts', 'tsx'],
  files: ['src/**/*.test.*'],
  verbose: true,
  failWithoutAssertions: true,
  environmentVariables: {
    TS_NODE_PROJECT: './src/tsconfig.json',
    TS_NODE_COMPILER_OPTIONS: '{"module":"commonjs"}',
  },
  require: [
    './_setup-unit-test-env.js',
    'tsconfig-paths/register',
    'ts-node/register',
    'isomorphic-fetch',
  ],
  timeout: '80s',
}

tsconfig.js:

{
  "compilerOptions": {
    "experimentalDecorators": true, // @computed
    "baseUrl": ".",
    "typeRoots": [
      "../node_modules/@types",
    ],
    "sourceMap": true,
    "module": "es6",
    "moduleResolution": "node",
    "target": "es6",
    "outDir": "build",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "paths": {
      "~/*": ["./*"]
    },
    "jsx": "react-jsx",
    "jsxImportSource": "preact"
  },
  "include": ["./"],
  "ts-node": {
    "files": true
  },
  "files": ["./environment.d.ts"]
}

invoke via package.json script: "test": "c8 ava",

Node version 16.16.0, but also tested with 18.7.0

novemberborn commented 2 years ago

This may be better discussed in the main forum: https://github.com/avajs/ava/discussions. This repository is specific to the official support for using pre-compiled TypeScript (or having AVA invoke tsc before running tests).

That said, I do agree that ts-node is likely to be the problem. The idea with precompilation is that AVA then is only loading JS code, no other big libraries are loaded doing work, so it should all go a bit better. But you'd have to work out how to compile your project using just tsc.