Auto-run npm ci when JS dependencies change - #13080
Conversation
Uses Make's native timestamp tracking: if package.json or package-lock.json is newer than node_modules/, run npm ci before the build. Covers js, css, components, and lit-components targets. Closes: # (no issue)
|
@lokesh this is based on our discussion in the weekly call today. I'd love to hear your thoughts and if it looks good lets merge it and remove one class of issue from this project forever! |
|
Couple of interesting gotchas:
And an alternative solution: The core idea is good (auto-install when deps change is a real quality-of-life win). The nit is that keying off a folder's timestamp is fragile — a cleaner approach is to key off node_modules/.package-lock.json, a small file npm writes after a successful install specifically so tools can detect "is this install current?" |
We do key in just the package.json and packagelock json. Ultimately, do you think this would be an improvement or be more of an annoyance? You work on frontend much more than me so I think you know. Maybe we should also consider PNPM which seems to have some performance improvements according AI? |
|
re: num 1 re: num 2 package and package lock disagreement The only question that is outstanding, and not blocking, but worth understanding, is what happens if you are offline and run it. Will it wipe your node modules and then fail to install anything? |
lokesh
left a comment
There was a problem hiding this comment.
Though there might be small annoyances and extra build costs on occasion, I think they are worth the trade-off for keeping local dev dependencies up to date.
Problem
When a contributor updates
package.json/package-lock.json(adding or updating a JS dependency), the next person who runsmake js,make css,make frontend, or thebuild-assetsnpm script will get a build error —node_modulesis stale and the new package is missing. This is a common footgun in local dev and CI.Solution
Use Make's native timestamp-based dependency tracking to gate
npm ci:How it works
node_modules/'s mtime againstpackage-lock.jsonandpackage.json.node_modules,npm ciruns before the build target.node_modulesis already up to date, the rule is skipped — zero overhead.npm ciis used overnpm installbecause:package-lock.json(deterministic).package-lock.jsonandpackage.jsonare out of sync.How to test
1. Idempotent build (no unnecessary installs)
2. Stale deps trigger auto-install
3. All build targets are covered
make -n css make -n components make -n lit-components # None of these should show "npm ci" when node_modules is freshTrade-offs considered
post-checkoutgit hookpreparenpm scriptnpm installonly, not ongit pullwith new deps.npm ciper buildnode_modulesis already fresh.Note: Many modern projects sidestep this problem entirely by using pnpm (which has a content-addressable store —
pnpm installis sub-second when the cache is warm, so they just run it unconditionally before every build) or Yarn Berry Zero-Installs (zipped packages committed to git — deps are always present aftergit pull). Switching package managers is out of scope here, but worth knowing those options exist if the team ever evaluates alternatives. Docker dev images (install once at image build time) are another common approach. |