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

Error: Worker terminated due to reaching memory limit: JS heap out of memory #875

Open
WINOFFRG opened this issue Apr 3, 2023 · 14 comments

Comments

@WINOFFRG
Copy link

WINOFFRG commented Apr 3, 2023

Hi!

While building I am getting this error

DTS Build start
node:events:491
      throw er; // Unhandled 'error' event
      ^

Error [ERR_WORKER_OUT_OF_MEMORY]: Worker terminated due to reaching memory limit: JS heap out of memory
    at new NodeError (node:internal/errors:399:5)
    at [kOnExit] (node:internal/worker:277:26)
    at Worker.<computed>.onexit (node:internal/worker:199:20)
Emitted 'error' event on Worker instance at:
    at [kOnExit] (node:internal/worker:277:12)
    at Worker.<computed>.onexit (node:internal/worker:199:20) {
  code: 'ERR_WORKER_OUT_OF_MEMORY'
}

Node.js v18.14.2

I feel there is some issue with my tsconfig.json Here is the link to the current tsconfig which causes this issue
https://github.com/WINOFFRG/limeplay/blob/c7b4342dc74cdbded43c0c39101eb8dd10bd98ac/packages/limeplay-core/tsconfig.json

Please check the root tsconfig.json as well! If I don't extend the root config to package config ./tsconfig.json to packages/limeplay-core/tsconfig.json with the below config

{
	"compilerOptions": {
		"target": "ESNext",
		"useDefineForClassFields": true,
		"lib": ["DOM", "DOM.Iterable", "ESNext"],
		"allowJs": true,
		"checkJs": false,
		"skipLibCheck": true,
		"esModuleInterop": false,
		"allowSyntheticDefaultImports": true,
		"strict": false,
		"forceConsistentCasingInFileNames": true,
		"module": "ESNext",
		"moduleResolution": "Node",
		"resolveJsonModule": true,
		"isolatedModules": false,
		"noEmit": true,
		"noEmitOnError": true,
		"jsx": "react-jsx",
		"declaration": true,
		"emitDecoratorMetadata": true,
		"experimentalDecorators": true,
		"noImplicitAny": true,
		"preserveConstEnums": true,
		"typeRoots": ["./src/types"]
	},
	"include": ["src", "../../@types"],
	"exclude": ["node_modules"]
}

The build succeeds but when extended with the config shared above in the URL, It fails. Here is the link to error from Actions

https://github.com/WINOFFRG/limeplay/actions/runs/4589372907/jobs/8104219650#step:4:224

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@juniorwmr
Copy link

Same here.

@anhntcv
Copy link

anhntcv commented May 17, 2023

I have the same problem

@Achaak
Copy link

Achaak commented May 17, 2023

{
	"compilerOptions": {
		"target": "ESNext",
		"useDefineForClassFields": true,
		"lib": ["DOM", "DOM.Iterable", "ESNext"],
		"allowJs": true,
		"checkJs": false,
		"skipLibCheck": true,
		"esModuleInterop": false,
		"allowSyntheticDefaultImports": true,
		"strict": false,
		"forceConsistentCasingInFileNames": true,
		"module": "ESNext",
		"moduleResolution": "Node",
		"resolveJsonModule": true,
		"isolatedModules": false,
		"noEmit": true,
		"noEmitOnError": true,
		"jsx": "react-jsx",
		"declaration": true,
		"emitDecoratorMetadata": true,
		"experimentalDecorators": true,
		"noImplicitAny": true,
		"preserveConstEnums": true,
		"typeRoots": ["./src/types"]
	},
	"include": ["src", "../../@types"],
	"exclude": ["node_modules"]
}

I have the same probleme but when I tested your tsconfig, it works.
And I tested to merge with mine and the problem was "typeRoots": [] which was missing
When I add this empty array in my configuration, it works.

@anhntcv
Copy link

anhntcv commented May 18, 2023

thank you @Achaak , I tried with "typeRoots": [] and it fixed the error. RAM reaches 4GB threshold when build.

bengry added a commit to bengry/typedash that referenced this issue May 18, 2023
@kysley
Copy link

kysley commented Aug 1, 2023

Wow! Thanks @Achaak. This also fixed the problem in our pipeline 🤯

@coopbri
Copy link

coopbri commented Aug 31, 2023

Unfortunately, I am still encountering this issue despite the workarounds above. I have a React component library with ~40 components and a single entry point (though I tested multiple entry points). The builds (ESM and CJS in my case) are fast, but the *.d.ts generation eventually OOMs after ~10 minutes. I also made sure I don't have any cyclic dependencies.

mairh added a commit to Hero24Oy/frontend that referenced this issue Oct 30, 2023
# PR Overview

## Why Are We Making This Change?

Both builds are failing

## How Is The Codebase Changing?

– bump version to deploy
– removed generation .d.ts files to handle out-of-memory issue on eas
build
– add preparation script before deploy

## Notes

- [Issue OOM](egoist/tsup#875)

https://expo.dev/accounts/hero24

<img width="1286" alt="Screenshot 2023-10-27 at 15 12 23"
src="https://github.com/Helpdor/frontend/assets/4072250/0de326af-00e9-455f-9a76-bfe4b5cbe0c5">
@9vfQbg7z4ajrGQxR
Copy link

same like @coopbri

@antonio-ivanovski
Copy link

Have the same issue on TS only library (not React involved), and not even that large. The DTS step in order to be successful has pulled 14GB memory from my machine, this is unacceptable for CI runners.

What I have tried but it didn't work:

  • Only generate ESM or CJS
  • Emit declarations only
  • Setting typeRoots to empty array (same amount of time + build error because it didn't find the types)

Only thing that worked was downgrading to 6.6 as suggested.

@egoist @sxzz Do you have any idea what could be the issue here? Providing minimal reproducing example may be harder since it mostly happens in medium to large codebases.

@antonio-ivanovski
Copy link

antonio-ivanovski commented Nov 6, 2023

Downgrading to 6.6 made me remove the top-level async logic from my tsup.config.js. This made my build work, but then I bumped the tsup version to 7.2 and by having no top-level async in the config, the memory requirement went down from 14GB to 4GB, bit more manageable by CI.

Looking more into the issues, found #1018 that is somewhat expected to solve this, but not sure since running the build, it still take around 4GB.

Probably part of my issue is (please confirm if true) that I am being lazy to define actual entry points so I wrote a method that fetches all the .ts files in the source and defines those as entry points. It also uses these entries to generate the package.json#exports. Reducing the set of entries to the actual entries reduces the memory footprint to ~2,5GB.

For reference, the build on tsup 6.6 takes <500MB with 1/10th of the time.

@antonio-ivanovski
Copy link

After bit of debugging decided to time the hooks execution times. As suspected the rollup dts plugin is the culprit with the hook for options that in my case took ~30s to execute. Will investigate further to find what exactly is the issue.

@millerized
Copy link

millerized commented Dec 13, 2023

As an extra data point (same as @coopbri) I can confirm that something in v6.7.0 has created a performance regression -- both in speed and memory usage (OOM).

I tried v8.0.1 today and the problem still persists and seems worse now that my codebase is a little larger. Seems like this is most likely due to entry point count.

Probably part of my issue is (please confirm if true) that I am being lazy to define actual entry points so I wrote a method that fetches all the .ts files in the source and defines those as entry points.

@ToTeTo I wouldn't say this is your issue because I have mine setup to do tsup src/**/**/index.ts .. etc which essentially creates an entry point for every component in my library (30). I do this intentionally to avoid huge barrel file exports because of perf issues in user land.

@nolde
Copy link

nolde commented Jun 3, 2024

I have been using onSuccess hook to just use tsc to compile the types, while tsup takes care of code. This took any memory issues away, and allowed me to build .d.ts files for all internal files, allowing deep lib reference with exports. It fixed my memory issues during build.

// tsup.config.ts
import { copyFile } from 'node:fs/promises'
import { exec } from 'node:child_process'
import { promisify } from 'node:util'

import glob from 'tiny-glob'
import { defineConfig } from 'tsup'

const pexec = promisify(exec)

export default defineConfig({
  cjsInterop: true,
  clean: true,
  entry: ['src/**/*.ts', '!src/**/*.test.ts'],
  format: ['cjs', 'esm'],
  shims: true,
  sourcemap: false,
  splitting: true,
  target: 'node20',
  //
  async onSuccess () {
    try {
      await pexec('tsc --emitDeclarationOnly --declaration')
      const files = await glob('dist/**/*.d.ts')
      await Promise.all(files.map(file => copyFile(file, file.replace('.d.ts', '.d.mts')))) // or to `.d.cjs` for "type": "module" projects
    } catch (err) {
      console.error()
      console.error('Typescript compilation error:')
      console.error()
      console.error(err.stdout)
      throw err
    }
  }
})

Don't forget to add "outDir": "./dist" to your tsconfig.

@tysonclugg
Copy link

As per #920 (comment) this may have been fixed upstream in Node v21 and above. Can someone please test and confirm if this is the case?

@faithfulojebiyi
Copy link

I have been using onSuccess hook to just use tsc to compile the types, while tsup takes care of code. This took any memory issues away, and allowed me to build .d.ts files for all internal files, allowing deep lib reference with exports. It fixed my memory issues during build.

// tsup.config.ts
import { copyFile } from 'node:fs/promises'
import { exec } from 'node:child_process'
import { promisify } from 'node:util'

import glob from 'tiny-glob'
import { defineConfig } from 'tsup'

const pexec = promisify(exec)

export default defineConfig({
  cjsInterop: true,
  clean: true,
  entry: ['src/**/*.ts', '!src/**/*.test.ts'],
  format: ['cjs', 'esm'],
  shims: true,
  sourcemap: false,
  splitting: true,
  target: 'node20',
  //
  async onSuccess () {
    try {
      await pexec('tsc --emitDeclarationOnly --declaration')
      const files = await glob('dist/**/*.d.ts')
      await Promise.all(files.map(file => copyFile(file, file.replace('.d.ts', '.d.mts')))) // or to `.d.cjs` for "type": "module" projects
    } catch (err) {
      console.error()
      console.error('Typescript compilation error:')
      console.error()
      console.error(err.stdout)
      throw err
    }
  }
})

Don't forget to add "outDir": "./dist" to your tsconfig.

Have you had any issues where ot generated wrong types

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

No branches or pull requests