Skip to content

Resolve installed dependency versions from lockfiles instead of node_modules#14703

Open
dario-piotrowicz wants to merge 2 commits into
mainfrom
dario/package-resolution-lock-files
Open

Resolve installed dependency versions from lockfiles instead of node_modules#14703
dario-piotrowicz wants to merge 2 commits into
mainfrom
dario/package-resolution-lock-files

Conversation

@dario-piotrowicz

@dario-piotrowicz dario-piotrowicz commented Jul 15, 2026

Copy link
Copy Markdown
Member

getInstalledPackageVersion now consults the nearest lockfile (pnpm-lock.yaml, package-lock.json, yarn.lock, or bun.lock) before falling back to resolving from node_modules. The lockfile is parsed once and memoized, making repeated version lookups significantly faster. This also improves the accuracy of the dependency metadata collected during deploys. All four major package managers (npm, pnpm, yarn, and bun) are supported across their lockfile format versions


Note

I run some benchmarks on this PR's prerelease and I must say that the perf benefit seems to be quite minimal even when dealing with a good number of dependencies (~130). That however might be because of performance fs operations on my system, maybe the different could be more significative on older less powerful machines (also this definitely scaled batter, so the more the dependencies the more this approach speeds things up).


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: performance improvement

A picture of a cute animal (not mandatory, but encouraged)

@changeset-bot

changeset-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9e5beec

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
@cloudflare/workers-utils Minor
wrangler Patch
@cloudflare/autoconfig Patch
@cloudflare/cli-shared-helpers Patch
@cloudflare/deploy-helpers Patch
@cloudflare/vite-plugin Patch
@cloudflare/vitest-pool-workers Patch
@cloudflare/workers-auth Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

✅ All changesets look good

@pkg-pr-new

pkg-pr-new Bot commented Jul 15, 2026

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/@cloudflare/autoconfig@14703

@cloudflare/config

npm i https://pkg.pr.new/@cloudflare/config@14703

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@14703

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/@cloudflare/deploy-helpers@14703

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@14703

miniflare

npm i https://pkg.pr.new/miniflare@14703

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@14703

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@14703

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@14703

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@14703

@cloudflare/workers-auth

npm i https://pkg.pr.new/@cloudflare/workers-auth@14703

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@14703

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@14703

wrangler

npm i https://pkg.pr.new/wrangler@14703

commit: 9e5beec

@ask-bonk

ask-bonk Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

@dario-piotrowicz Bonk workflow was cancelled.

View workflow run · To retry, trigger Bonk again.

@dario-piotrowicz
dario-piotrowicz force-pushed the dario/package-resolution-lock-files branch from 24edfc0 to 2f88b64 Compare July 15, 2026 14:58
@dario-piotrowicz
dario-piotrowicz marked this pull request as ready for review July 15, 2026 23:02
@workers-devprod
workers-devprod requested review from a team and edmundhung and removed request for a team July 15, 2026 23:03
@workers-devprod

workers-devprod commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/lockfile-version-resolution.md: [@cloudflare/wrangler]
  • packages/deploy-helpers/src/deploy/helpers/package-dependencies.ts: [@cloudflare/wrangler]
  • packages/workers-utils/package.json: [@cloudflare/wrangler]
  • packages/workers-utils/src/index.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/index.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/lockfiles-resolution/bun.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/lockfiles-resolution/discovery.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/lockfiles-resolution/index.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/lockfiles-resolution/npm.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/lockfiles-resolution/pnpm.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/lockfiles-resolution/resolve.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/lockfiles-resolution/yarn.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/node-modules.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/package-resolution/package-resolution.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/package-resolution/lockfile-resolution/bun.test.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/package-resolution/lockfile-resolution/npm.test.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/package-resolution/lockfile-resolution/pnpm.test.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/package-resolution/lockfile-resolution/resolve.test.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/package-resolution/lockfile-resolution/share.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/package-resolution/lockfile-resolution/yarn.test.ts: [@cloudflare/wrangler]
  • packages/workers-utils/tests/package-resolution/package-resolution.test.ts: [@cloudflare/wrangler]
  • pnpm-lock.yaml: [@cloudflare/wrangler]

devin-ai-integration[bot]

This comment was marked as resolved.

@dario-piotrowicz
dario-piotrowicz force-pushed the dario/package-resolution-lock-files branch from 2f88b64 to 1d033b4 Compare July 16, 2026 10:29
devin-ai-integration[bot]

This comment was marked as resolved.

@dario-piotrowicz
dario-piotrowicz marked this pull request as draft July 16, 2026 12:28
@dario-piotrowicz
dario-piotrowicz force-pushed the dario/package-resolution-lock-files branch from 1d033b4 to 18f5c12 Compare July 16, 2026 16:36
@dario-piotrowicz
dario-piotrowicz marked this pull request as ready for review July 16, 2026 21:18
devin-ai-integration[bot]

This comment was marked as resolved.

@dario-piotrowicz
dario-piotrowicz force-pushed the dario/package-resolution-lock-files branch from 18f5c12 to 23ebae8 Compare July 17, 2026 09:36
devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Comment thread .changeset/lockfile-version-resolution.md Outdated
…modules

`getInstalledPackageVersion` now consults the nearest lockfile (pnpm-lock.yaml, package-lock.json, yarn.lock, or bun.lock) before falling back to resolving from node_modules. The lockfile is parsed once and memoized, making repeated version lookups significantly faster. This also improves the accuracy of the dependency metadata collected during deploys. All four major package managers (npm, pnpm, yarn, and bun) are supported across their lockfile format versions
@dario-piotrowicz
dario-piotrowicz force-pushed the dario/package-resolution-lock-files branch from 50849a3 to 9e5beec Compare July 17, 2026 11:01

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Comment on lines +55 to +57
const found = findLockfile(projectPath, {
last: opts.stopAtProjectPath === true ? projectPath : undefined,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Dependency version lookups re-scan the folder tree on disk for every package

The nearest lockfile is located by scanning folders on disk (findLockfile at packages/workers-utils/src/package-resolution/lockfiles-resolution/resolve.ts:55) on every single package lookup before the memoization cache is even consulted, so the intended speed-up is undercut because the same directory scan is repeated once per dependency.
Impact: Collecting dependency metadata during a deploy does far more redundant filesystem work than intended, so projects with many dependencies see little of the promised performance benefit.

Discovery runs before the cache check

In getInstalledVersionsFromLockfile (packages/workers-utils/src/package-resolution/lockfiles-resolution/resolve.ts:55-77), findLockfile is invoked unconditionally at the top of the function. Only the parse result (parseLockfile) is memoized in cacheStore keyed by lockfilePath + "\0" + projectPath. findLockfile (discovery.ts:36-58) walks up the directory tree with walk.up and performs up to LOCKFILE_NAMES.length (4) statSync calls per directory level.

When called from the loop in collectPackageDependencies (packages/deploy-helpers/src/deploy/helpers/package-dependencies.ts:83-92), this runs once per dependency — e.g. ~130 full directory-walk + stat sweeps for ~130 deps — even though the discovered lockfile path is identical every time. The cache should also memoize the discovery step (e.g. keyed by projectPath + stopAtProjectPath) so the walk happens once per collection pass. This matches the PR author's own note that the observed speed-up was minimal.

Prompt for agents
In getInstalledVersionsFromLockfile (packages/workers-utils/src/package-resolution/lockfiles-resolution/resolve.ts), findLockfile is called unconditionally at the start of the function on every invocation, before the memoization cache is consulted. Only the parseLockfile result is cached. When called in a loop (once per dependency in collectPackageDependencies), this repeats the full directory-tree walk plus multiple statSync calls per dependency, even though the discovered lockfile is identical each time. This undercuts the stated performance goal of the PR. Consider also memoizing the discovery result — e.g. cache the findLockfile output keyed by projectPath (and the stopAtProjectPath flag), or short-circuit discovery when a cache entry already exists for the (projectPath) — so the directory walk runs once per collection pass rather than once per dependency.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

2 participants