O 123% więcej zgłoszonych CVE dziennie w 2026 niż przed rokiem.

Zależności

Czym jest lockfile?

Lockfile zapisuje dokładną wersję każdej zależności rozwiązanej przez menedżera pakietów, bezpośredniej i przechodniej, aby kolejna instalacja dała to samo drzewo. To najlepszy plan buildu, jaki Państwo mają. Nie jest to jednak zapis tego, czego build faktycznie użył.

Zaktualizowano

Co zapisuje lockfile

Manifest, taki jak package.json lub pyproject.toml, wymienia pakiety, od których Państwo zależą, oraz akceptowane zakresy wersji. Menedżer pakietów zamienia te zakresy na dokładne wersje dla całego drzewa, łącznie z zależnościami przechodnimi, i zapisuje wynik w lockfile. Według dokumentacji npm package-lock.json opisuje „the exact tree that was generated, such that subsequent installs are able to generate identical trees”.

Pojedynczy wpis w package-lock.json wygląda tak:

"node_modules/raw-body": {
  "version": "3.0.0",
  "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
  "integrity": "sha512-...",
  "dependencies": {
    "bytes": "3.1.2",
    "http-errors": "2.0.0",
    "iconv-lite": "0.6.3",
    "unpipe": "1.0.0"
  }
}
  • version to dokładna wersja, którą wybrano.
  • resolved to miejsce pobrania: adres URL archiwum tarball w rejestrze albo adres URL git z commitem.
  • integrity to hash Subresource Integrity archiwum tarball, dzięki czemu pobranie zmanipulowanego pliku kończy się błędem.
  • dependencies to własne zależności pakietu, dzięki którym drzewo, czyli graf zależności, składa się w całość.

Lockfile według menedżera pakietów

Menedżer pakietów Lockfile Instalacja bez jego zmiany
npmpackage-lock.jsonnpm ci
Yarn (Berry)yarn.lockyarn install --immutable
pnpmpnpm-lock.yamlpnpm install --frozen-lockfile
uvuv.lockuv sync --locked
Poetrypoetry.lockpoetry install
CargoCargo.lockcargo build --locked
BundlerGemfile.lockbundle config set frozen true
Moduły Go Wersje w go.mod i sumy kontrolne w go.sum Polecenia buildu domyślnie nie aktualizują go.mod

W przypadku samego pip typowym zamiennikiem jest requirements.txt z dokładnymi wersjami. Przypina to, co wymienia, ale wszystko, co pomija, jest rozwiązywane od nowa przy każdej instalacji.

W CI należy używać instalacji zamrożonych

Lockfile pomaga tylko wtedy, gdy build instaluje z niego. Zwykłe npm install może zaktualizować package-lock.json, gdy plik nie jest już zgodny z package.json, więc build po cichu rozwiązuje nowe drzewo. npm ci powstało z myślą o środowiskach zautomatyzowanych:

  • Wymaga pliku package-lock.json lub npm-shrinkwrap.json.
  • Jeśli lockfile i package.json są niezgodne, kończy działanie błędem, zamiast aktualizować lockfile.
  • Najpierw usuwa istniejący katalog node_modules.
  • Nigdy nie zapisuje do package.json ani do lockfile.

Pozostałe polecenia z powyższej tabeli robią to samo dla swoich menedżerów pakietów.

Aplikacje i biblioteki

W przypadku aplikacji i wszystkiego, co Państwo wdrażają, lockfile należy commitować. W przypadku bibliotek blokuje on tylko Państwa własne środowisko programistyczne i CI: npm nigdy nie publikuje package-lock.json i ignoruje go wszędzie poza projektem głównym. Aplikacje instalujące Państwa bibliotekę same rozwiązują jej zależności w ramach Państwa zakresów wersji. Jedynym wyjątkiem w npm jest npm-shrinkwrap.json, który jest publikowany i ma pierwszeństwo, a którego większość bibliotek nie powinna używać.

Dlaczego lockfile nie jest zapisem tego, co dostarczono

Lockfile to plan dla jednego menedżera pakietów w jednym projekcie. Build, który wytworzył Państwa wydanie, zrobił więcej, niż tylko wykonał ten plan:

  • Mógł go nie użyć. Instalacja niezamrożona, brak lockfile lub drugi lockfile w monorepo oznaczają, że drzewo rozwiązano inaczej, niż wynika z pliku, na który Państwo patrzą.
  • Cache. Pakiety przywrócone z cache CI są instalowane bez pobierania, a cache przywrócony na podstawie częściowego klucza może być starszy niż bieżący lockfile. Zob. co ukrywa cache GitHub Actions.
  • Narzędzia buildu. Akcje konfiguracyjne, kompilatory, lintery i generatory kodu trafiają do buildu innymi kanałami, z własnymi drzewami zależności.
  • Pobrania i skrypty instalacyjne. curl w kroku buildu lub skrypt instalacyjny pakietu pobiera kod, którego nie wymienia żaden lockfile.
  • Obrazy bazowe. Build kontenera pobiera obrazy i pakiety systemu operacyjnego, które znajdują się poza lockfile każdego języka.

Hashe integrity w niczym tu nie pomagają. Dowodzą, że pakiety z lockfile nie zostały zmanipulowane; nie mówią nic o tym, co build pobrał poza nim. Narzędzia SCA, które zamieniają lockfile w SBOM, dziedziczą te same martwe punkty.

Rejestrować build, zachować lockfile

Proszę nadal commitować lockfile i instalować z nich w trybie zamrożonym. Dzięki temu buildy są powtarzalne. Jeśli chodzi o zapis zawartości wydania, CRACI rejestruje sam build: proxy rozpoznające pakiety na jego runnerach GitHub Actions rejestruje każdy pakiet pobrany przez każde zadanie, łącznie z pakietami przywróconymi z cache CI, a SBOM każdego zadania określa własną kompletność. Ten zapis daje pełniejszy obraz używanych zależności niż skan lockfile. Zob. SBOM-y z czasu buildu lub proszę umówić demo, aby porównać oba podejścia na jednym z Państwa buildów.

Lockfile: najczęściej zadawane pytania

Czym jest lockfile?

Lockfile to plik, który menedżer pakietów zapisuje, aby zarejestrować dokładną wersję każdej rozwiązanej zależności, bezpośredniej i przechodniej, wraz z jej pochodzeniem i sumą kontrolną. Późniejsze instalacje odczytują go, aby odtworzyć to samo drzewo zamiast ponownie rozwiązywać zakresy wersji.

Czy należy commitować lockfile?

Tak, w przypadku aplikacji i wszystkiego, co Państwo wdrażają. Bez lockfile w repozytorium każda nowa instalacja ponownie rozwiązuje zakresy wersji i może pobrać nowe wersje przechodnie. Należy go commitować i instalować z niego w CI w trybie zamrożonym, na przykład przez npm ci.

Czy lockfile przypina zależności przechodnie?

Tak. To jego główne zadanie. Manifest wymienia tylko Państwa zależności bezpośrednie i ich dozwolone zakresy; lockfile zapisuje dokładną wersję wybraną dla każdego pakietu w drzewie.

Czy lockfile dotyczy publikowanych bibliotek?

Nie w przypadku Państwa użytkowników. Na przykład npm nigdy nie publikuje package-lock.json i ignoruje go wszędzie poza projektem głównym. Aplikacje instalujące Państwa bibliotekę same rozwiązują jej zależności w ramach zakresów dozwolonych przez Państwa package.json.

Do czego służy pole integrity w package-lock.json?

Zawiera hash Subresource Integrity, zwykle sha512, archiwum tarball pakietu. npm porównuje z nim pobrany pakiet, więc zmanipulowane archiwum przypiętej wersji nie zostanie zainstalowane. Chroni to pakiety z lockfile, ale nie to, co build pobiera poza nim.

Czy lockfile to to samo co SBOM?

Nie. Lockfile to dane wejściowe: plan, którego menedżer pakietów trzyma się w jednym projekcie. SBOM to inwentarz wydania. Narzędzia SCA często zamieniają lockfile w SBOM, co działa, gdy build zainstalował dokładnie to, co podaje lockfile, i nic więcej.

Proszę porównać lockfile z buildem

Proszę uruchomić jeden workflow na CRACI i zestawić zarejestrowany SBOM pobranych pakietów z tym, co podaje Państwa lockfile.

Umów demo