Dependensi & rantai pasok
Kamu tidak menulis sebagian besar kode yang berjalan di produksimu. Ini cara membuat kenyataan itu tidak berakhir sebagai insiden.
Intisari
pnpm-lock.yamlyang di-commit adalah pertahanan pertama: build ulang menghasilkan pohon yang sama persis.- Matikan lifecycle script otomatis โ
postinstalladalah vektor serangan rantai pasok paling umum. pnpm auditdi CI, tapi jangan gagalkan build untuk kerentanan yang hanya ada didevDependencies.- Setiap dependensi baru butuh alasan. Paket 3 KB yang bisa kamu tulis dalam 20 baris tidak layak.
- Perbarui rutin dan sedikit-sedikit; menunda enam bulan menghasilkan lompatan yang tidak bisa direview.
Ukuran masalahnya
pnpm ls --depth Infinity 2>/dev/null | wc -l
pnpm ls --prod --depth Infinity 2>/dev/null | wc -l
Proyek Astro dengan Vue, Kysely, mysql2, dan Zod biasanya menarik beberapa ratus paket. Sebagian besar hanya dipakai saat build dan tidak ikut ke produksi โ tapi semuanya berjalan di mesin CI-mu, dengan akses ke variabel lingkungannya.
Matikan lifecycle script
# .npmrc
enable-pre-post-scripts=false
engine-strict=true
{
"pnpm": {
"onlyBuiltDependencies": ["esbuild", "sharp"]
}
}
postinstall adalah vektor serangan rantai pasok yang paling sering dipakai. Paket
yang dikompromikan menjalankan skrip saat dipasang โ di laptop tiap developer dan di runner CI-mu, yang
memegang kredensial deploy. pnpm memblokirnya secara bawaan dan meminta kamu menyebut paket mana yang
benar-benar butuh mengompilasi sesuatu. Daftar itu seharusnya pendek: esbuild,
sharp, dan sedikit lainnya.
Audit di CI
- name: Audit dependensi produksi
run: pnpm audit --prod --audit-level high
- name: Audit semua (peringatan saja)
run: pnpm audit --audit-level moderate || true
| Lingkup | Gagalkan build? | Kenapa |
|---|---|---|
dependencies, tingkat high/critical | Ya | Berjalan di produksi |
dependencies, moderate | Tinjau | Sering tidak berlaku untuk cara kamu memakainya |
devDependencies | Tidak | Tidak ikut ke produksi; menggagalkan build hanya menghasilkan kebiasaan mengabaikan |
Audit yang selalu merah adalah audit yang tidak dibaca siapa pun. Ini bukan sikap longgar โ ini pengakuan bahwa peringatan keamanan hanya berguna kalau jarang dan akurat. Gagalkan build hanya untuk yang benar-benar berjalan di produksi, dan tinjau sisanya secara berkala dengan sengaja.
Sebelum menambah dependensi
| Pertanyaan | Kalau jawabannya buruk |
|---|---|
| Bisakah pustaka standar Node melakukannya? | Node 22 punya fetch, crypto, AbortSignal.timeout, dan structuredClone |
| Berapa dependensi transitifnya? | Satu paket 3 KB yang menarik 40 paket lain bukan paket 3 KB |
| Kapan rilis terakhirnya? | Tidak ada rilis dua tahun = tidak ada perbaikan keamanan |
| Berapa pemeliharanya? | Satu orang = satu titik kegagalan, dan satu akun yang bisa dibajak |
| Bisakah ditulis dalam 30 baris? | Tulis 30 barisnya |
Contoh nyata dari roadmap ini: fungsi cache() di Fase 3, denganUlang() dan
buatBreaker() di Fase 3, dan Sparkline.astro di Fase 4 semuanya menggantikan
paket npm. Totalnya di bawah 150 baris kode yang kamu pahami sepenuhnya.
Perbarui rutin
pnpm outdated
pnpm update --interactive --latest
# Naikkan satu hal pada satu waktu
pnpm update astro
pnpm build && pnpm astro check && pnpm test
| Irama | Yang dilakukan |
|---|---|
| Mingguan | Perbaikan tambalan otomatis lewat Dependabot/Renovate |
| Bulanan | Rilis minor, ditinjau |
| Per kuartal | Rilis mayor, satu per satu, dengan waktu untuk membaca panduan migrasinya |
| Segera | Kerentanan high/critical di dependencies |
Yang benar-benar berjalan di produksi
# Astro membundel sebagian besar dependensi ke dist/.
# Yang tersisa di node_modules produksi jauh lebih sedikit dari yang kamu kira.
pnpm build
pnpm install --prod --frozen-lockfile
du -sh node_modules
pnpm ls --prod --depth 0
Angka ini penting untuk penilaian risikomu: paket yang hanya dipakai saat build tidak bisa dieksploitasi oleh pembaca portalmu. Ia tetap bisa menyerang pipeline-mu โ jadi tetap ditangani, tapi dengan prioritas yang berbeda.
Container juga rantai pasok
# Sematkan versi, jangan pakai tag bergerak
FROM node:22.14-alpine AS build
# Bukan:
FROM node:latest
FROM node:22
- name: Pindai image
run: |
docker build -t portal:${{ github.sha }} .
trivy image --severity HIGH,CRITICAL --exit-code 1 portal:${{ github.sha }}
Image dasar berisi ratusan paket sistem yang tidak pernah kamu pilih. Memindainya sama pentingnya dengan memindai dependensi npm โ dan lebih sering menghasilkan temuan, karena tidak ada yang memperhatikannya.
Latihan: tambahkan enable-pre-post-scripts=false ke .npmrc dan
jalankan pnpm install ulang dari nol โ catat paket mana yang mengeluh butuh membangun, dan
putuskan satu per satu apakah layak masuk onlyBuiltDependencies. Lalu jalankan
pnpm ls --prod --depth 0 dan bandingkan dengan daftar dependensi lengkapmu โ selisihnya
adalah kode yang tidak pernah menyentuh pembacamu.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.