fix: set import-x/resolver-next with a reusable createNodeResolver instance#42
Merged
fix: set import-x/resolver-next with a reusable createNodeResolver instance#42
Conversation
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.