Skip to content

fix: set import-x/resolver-next with a reusable createNodeResolver instance#42

Merged
B4nan merged 1 commit intomasterfrom
fix/configure-resolver-next
Apr 11, 2026
Merged

fix: set import-x/resolver-next with a reusable createNodeResolver instance#42
B4nan merged 1 commit intomasterfrom
fix/configure-resolver-next

Conversation

@B4nan
Copy link
Copy Markdown
Member

@B4nan B4nan commented Apr 11, 2026

Summary

`eslint-plugin-import-x`'s legacy `node` resolver path — the default fall-through when `import-x/resolver-next` is not configured — constructs a fresh `unrs-resolver.ResolverFactory` on every import resolution. `unrs-resolver` is a Rust binding that allocates native memory invisible to V8 heap limits, so per-call construction causes worker RSS to grow without bound over a lint run.

On a large lerna monorepo (apify/apify-core, ~60 packages, thousands of files), this reliably OOM-killed CI workers within 2 minutes, regardless of how much JS heap we gave them. Bumping `--max-old-space-size` didn't help because the leak is in native memory.

Fix

`eslint-plugin-import-x` v4.6.0+ already has proper instance reuse — but only on the new resolver path. You opt in by passing a single reusable `createNodeResolver()` instance via `import-x/resolver-next`. Since our shared config is the obvious chokepoint, set it here so every consumer gets the fix automatically and nobody has to rediscover the leak via an OOM.

Context

Verification

Tested on apify-core by configuring the same thing locally in its `eslint.config.mjs`. `npx eslint ./src/packages --concurrency=auto` with 8 GB heap now completes cleanly where it previously OOM-killed the worker every time.

…stance

`eslint-plugin-import-x`'s legacy `node` resolver path (the default
fall-through when `import-x/resolver-next` is not configured) constructs
a fresh `unrs-resolver.ResolverFactory` on every import resolution.
`unrs-resolver` is a Rust binding that allocates native memory invisible
to V8 heap limits, so per-call construction causes worker RSS to grow
without bound over a lint run.

On a large lerna monorepo (apify/apify-core, ~60 packages, thousands
of files), this reliably OOM-killed CI workers within 2 minutes.

`import-x` v4.6.0+ already has proper instance reuse on the new resolver
path — you just have to opt in by passing a single `createNodeResolver()`
instance via `import-x/resolver-next`. See:
  https://github.com/un-ts/eslint-plugin-import-x/releases/tag/v4.6.0
  un-ts/eslint-plugin-import-x#481 (review)

Set it in the shared config so every consumer gets the fix automatically
and nobody has to rediscover it via an OOM.
@github-actions github-actions bot added this to the 138th sprint - Tooling team milestone Apr 11, 2026
@github-actions github-actions bot added the t-tooling Issues with this label are in the ownership of the tooling team. label Apr 11, 2026
@B4nan B4nan merged commit bce9e29 into master Apr 11, 2026
1 check failed
@B4nan B4nan deleted the fix/configure-resolver-next branch April 11, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants