Skip to content

feat: add node_modules caching for yarn builds#334

Open
WVerlaek wants to merge 1 commit intomainfrom
wv/node-modules-cache
Open

feat: add node_modules caching for yarn builds#334
WVerlaek wants to merge 1 commit intomainfrom
wv/node-modules-cache

Conversation

@WVerlaek
Copy link
Member

@WVerlaek WVerlaek commented Jan 27, 2026

Description

Add LEEWAY_NODE_MODULES_CACHE environment variable to enable caching of node_modules directories between yarn package builds. This allows CI systems to cache and restore node_modules, avoiding repeated yarn install operations.

image

Before:

[frontend/dashboard:app-skip-tests] package build succeeded in 134.49s (prep 0.1s, pull 74.5s, build 57.5s)

After:

[frontend/dashboard:app-skip-tests] package build succeeded in 69.98s (prep 3.1s, pull 4.8s, build 59.8s)

Related Issue(s)

N/A

How to test

  1. Set LEEWAY_NODE_MODULES_CACHE to a directory path
  2. Build a yarn package: leeway build :some-yarn-package
  3. Verify node_modules is saved to the cache directory
  4. Build again and verify node_modules is restored from cache (check logs for "Restoring node_modules from cache...")
  5. Modify yarn.lock and rebuild - cache should be invalidated (new hash directory created)

Add LEEWAY_NODE_MODULES_CACHE env var to cache node_modules between
yarn package builds. Speeds up CI builds by avoiding repeated yarn
install operations.

Co-authored-by: Ona <no-reply@ona.com>
@WVerlaek WVerlaek marked this pull request as ready for review January 27, 2026 14:02
Copy link
Contributor

@kylos101 kylos101 left a comment

Choose a reason for hiding this comment

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

✅ to unblock, added a couple non-blocking suggestions.

yarnLockPath := filepath.Join(wd, "yarn.lock")
yarnLockHash, err := computeSHA256(yarnLockPath)
if err != nil {
log.WithField("package", p.FullName()).WithError(err).Debug("cannot compute yarn.lock hash for node_modules cache")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion, not blocking:
This feels like we should bump to warn. If this were to happen with an existing yarn component, we'd want to surface it more easily, I think.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion, not blocking:
Consider adding unit tests to cover new feature. Perhaps in pkg/leeway/build_integration_test.go? Ona suggested peeking at TestYarnPackage_LinkDependencies_Integration for a reference.

To test node_modules caching, you could extend this pattern by:

  1. Setting LEEWAY_NODE_MODULES_CACHE env var to a temp directory
  2. Building the package once (should save to cache)
  3. Verifying the cache directory structure exists ($cache/pkg_name/hash[:12]/node_modules)
  4. Building again and checking logs for "Restoring node_modules from cache..."
  5. Modifying yarn.lock and rebuilding to verify cache invalidation (new hash directory)

The existing test at line 2427-2680 would be a good template - it already handles all the yarn package setup boilerplate.

nodeModulesCachePath = filepath.Join(nodeModulesCacheDir, safePkgName, yarnLockHash[:12])

// Restore node_modules from cache if it exists
restoreCmd := fmt.Sprintf("if [ -d \"%s/node_modules\" ]; then echo \"Restoring node_modules from cache...\"; cp -a \"%s/node_modules\" ./node_modules; fi", nodeModulesCachePath, nodeModulesCachePath)
Copy link
Contributor

Choose a reason for hiding this comment

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

TIL about -a flag with cp.

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

Successfully merging this pull request may close these issues.

2 participants