fix(nix): hashless npm deps via importNpmLock - #48213
Conversation
The npm workspace pins a single npmDepsHash for fetchNpmDeps. Any change to package-lock.json that doesn't also refresh that hash breaks the bundled hermes-tui / hermes-desktop-renderer build for Nix flake consumers, and no nix CI catches it — the workflow that ran fix-lockfiles was removed in 9eb0bcd ("change(ci): rip out nix ci for now"). Fetch the workspace deps with pkgs.importNpmLock instead. It resolves each package from the lockfile's own integrity hashes, so package-lock.json is the single source of truth and there is no separate hash to drift. This also removes: - the fix-lockfiles checker/refresher and its devShell wiring — it existed only to keep npmDepsHash in sync, so it is dead once the hash is gone, and its sole CI consumer was already removed in 9eb0bcd; - the patchPhase that normalized lockfile trailing newlines — importNpmLock's npmConfigHook overwrites the lockfile rather than diffing it, so the normalization is unnecessary. npm-lockfile-fix is retained: importNpmLock requires an integrity-complete lockfile, which that tool guarantees when the lockfile is regenerated.
|
Humbly asking, is there any ETA for this changes? I wanted to try Hermes in nixos as a module but it won’t build :) |
Hi! I don't know how long it will take for the PR to get merged; however, for nix usage, here's another option that's quite stable but at the cost of being up to a day or so behind upstream: https://github.com/numtide/llm-agents.nix |
Thanks for the suggestion, I'll check it out :) |
|
For cross-reference: this PR removes the hand-maintained workspace
(Same class, earlier recurrences: #12965, #15244, #15272, #15314, #19760.) |
|
Thank you for this, @ak2k 🙏 — switching to Your branch had gone stale (~96 commits), so I cherry-picked your commit onto current Appreciate the clean fix and the clear writeup. 🚀 |
What
Fetch the npm workspace dependencies with
pkgs.importNpmLockinstead offetchNpmDeps+ a hand-maintainednpmDepsHash, and remove thefix-lockfilestooling whose only job was keeping that hash in sync.Why
nix/lib.nixpins onenpmDepsHashfor the whole workspace. Any change topackage-lock.jsonthat doesn't also refresh that hash breaks the bundledhermes-tui/hermes-desktop-rendererbuild for Nix flake consumers with a fixed-output hash mismatch. It recurs because the hash is hand-maintained and the workflow that refreshed it (nix-lockfile-fix.yml) was removed along with the rest of nix CI in 9eb0bcd ("change(ci): rip out nix ci for now"). See #37692.importNpmLockresolves each dependency from the lockfile's ownintegrityfield, sopackage-lock.jsonis the single source of truth and there is no separate hash to drift. This removes the failure class instead of re-automating the refresh: the oldfetchNpmDepshook did a byte-for-bytediffof the source lockfile against the realized deps cache — which is what bothfix-lockfilesand the deleted newline-normalizingpatchPhaseworked around — whereasimportNpmLock's hook overwrites the lockfile rather than diffing it, so neither workaround is needed.What changes
nix/lib.nix: the sharednpmDepsbecomespkgs.importNpmLock.importNpmLock { npmRoot = src; }, andmkNpmPassthrusetsnpmConfigHook = pkgs.importNpmLock.npmConfigHook.npmDepsHash,npmDepsFetcherVersion, and the newline-normalizingpatchPhaseare removed.fix-lockfilesis removed — themkFixLockfilesbuilder, itsmkNpmDevShellHookwiring, and the.#fix-lockfilesflake package. It only refreshednpmDepsHash, and its sole CI consumer was already removed in 9eb0bcd.npm-lockfile-fixis retained:importNpmLockrequires an integrity-complete lockfile, which that tool guarantees when the lockfile is regenerated (update_<attr>_lockfile).The four
buildNpmPackageconsumers (tui,web,desktop) are untouched — they spread the samemkNpmPassthruattrs.Testing
I built the workspace packages through this path on
aarch64-darwinand confirmed the deps resolve onx86_64-linux:hermes-tui— esbuild bundlehermes-web— tsc + vite buildhermes-desktoprenderer — includingnpm rebuild node-pty --build-from-sourcestaging the nativepty.nodehermes-agent(.default) — embeds tui + webThe dev shell still evaluates and
.#fix-lockfilesis correctly gone.Notes
importNpmLock's hook runsnpm install --ignore-scriptsthennpm rebuild(the oldfetchNpmDepshook also rannpm ci --ignore-scripts+npm rebuild, so native modules likenode-ptybuild the same way).npm installis more permissive thannpm ci: ifpackage.jsonand the lockfile ever drift, the old path failed at build, whereas this path installs from the lockfile-derived store paths.update_<attr>_lockfilestill ends innix build .#<attr>, so the verify step is preserved; anpm ci --dry-runsync check could restore the stricter guard if wanted.pkgs.importNpmLock(present since 2024; the current pin satisfies it).Closes #37692.