Skip to content

module: avoid reparsing package.json in esm format detection - #66982

Open
gurgunday wants to merge 1 commit into
nodejs:mainfrom
gurgunday:perf/module-package-scope-lazy
Open

gurgunday wants to merge 1 commit into
nodejs:mainfrom
gurgunday:perf/module-package-scope-lazy

Conversation

@gurgunday

@gurgunday gurgunday commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Determining the format of a .js or .ts module calls getPackageScopeConfig(), which spreads the deserialized package configuration and therefore invokes its lazy exports and imports getters

Every resolved module parses those maps again so load time and memory grows with the number of modules in a package times the size of its exports map

Instead of crating yet another cache, use getPackageType() for format detection and only look up the package.json path when warning about a typeless package

Build exports=0 exports=700 (~130 KB map)
main 91c4436 12–14 ms, 65 MB 55–66 ms, 134–157 MB
this branch 10–12 ms, 64–65 MB 11–13 ms, 66–67 MB

Both date-fns and drizzle-orm are affected by this and should improve the same way

Supersedes #65812 and fixes #66485

Determining the format of a `.js` or `.ts` module called
`getPackageScopeConfig()`, which spread the deserialized package
configuration and thereby invoked its lazy `exports` and `imports`
getters. Every resolved module parsed those maps again, so load time
and memory grew with the number of modules in a package times the
size of its `exports` map.

Use `getPackageType()` for format detection and only look up the
package.json path when warning about a typeless package. Stop
spreading the configuration in `getPackageScopeConfig()` so that the
maps are parsed only when accessed.

Fixes: nodejs#66485
Signed-off-by: Gürgün Dayıoğlu <hey@gurgun.day>
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/loaders

@nodejs-github-bot nodejs-github-bot added esm Issues and PRs related to the ECMAScript Modules implementation. module Issues and PRs related to the module subsystem. needs-ci PRs that need a full CI run. labels Oct 24, 2026
@codecov

codecov Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.59%. Comparing base (91c4436) to head (ac7d34f).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #66982      +/-   ##
==========================================
- Coverage   92.93%   90.59%   -2.35%     
==========================================
  Files         428      797     +369     
  Lines      195236   278301   +83065     
  Branches    30176    53520   +23344     
==========================================
+ Hits       181442   252115   +70673     
- Misses      13467    16556    +3089     
- Partials      327     9630    +9303     
Files with missing lines Coverage Δ
lib/internal/modules/esm/get_format.js 98.64% <100.00%> (+24.67%) ⬆️
lib/internal/modules/package_json_reader.js 99.34% <100.00%> (+11.59%) ⬆️

... and 499 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

esm Issues and PRs related to the ECMAScript Modules implementation. module Issues and PRs related to the module subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

esm: resolving each .js module re-parses the whole package.json "exports" map (memory grows with edges x exports size)

2 participants