Node.js, Package, dan Ekosistemnya · 4/7
Bagaimana sebuah import diselesaikan
Ikuti cara Node mencari module, supaya "Cannot find module" jadi masalah yang bisa diselesaikan.
Baca 22 menit
Setelah pelajaran ini kamu bisa
- Melacak bagaimana import biasa diubah jadi sebuah file di disk
- Menjelaskan kenapa folder `node_modules` bisa bersarang
- Mendiagnosis "Cannot find module" secara metodis
- Menjelaskan apa yang sebenarnya dilakukan alias import seperti `@/`
import { z } from "zod" tidak mengandung path. Ada sesuatu yang harus mengubah nama itu jadi file sungguhan. Memahami algoritmanya mengubah "Cannot find module" dari misteri jadi daftar periksa.
Tiga jenis import
| Bentuknya | Disebut | Diselesaikan dengan |
|---|---|---|
./format, ../lib/x | Relatif | Langsung dari folder file saat ini |
zod, react | Bare / package | Mencari node_modules ke atas |
node:fs, node:path | Bawaan | Node sendiri, tanpa pencarian di disk |
Pencarian ke atas
Untuk import bare, Node mencari di node_modules folder saat ini. Tidak ada? Naik satu tingkat lalu cari lagi. Ulangi sampai root filesystem, lalu gagal.
Importing "zod" from /home/you/app/features/booking/create.ts
Node checks, in this order:
/home/you/app/features/booking/node_modules/zod
/home/you/app/features/node_modules/zod
/home/you/app/node_modules/zod <- normally found here
/home/you/node_modules/zod
/home/node_modules/zod
/node_modules/zod
-> Error: Cannot find module 'zod'Algoritmanya sendiri, dalam dua belas baris, terhadap filesystem tiruan. Ubah `from` dan lihat jalur pencariannya berubah.
Hasil
Tekan Jalankan untuk melihat hasilnya.
Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.
Perhatikan kedua pemanggilan menemukan salinan React yang berbeda. Itu sebabnya penyarangan ada: kalau dua package butuh versi yang tidak kompatibel, masing-masing mendapat salinannya sendiri di dekatnya. Itu juga sebabnya kamu bisa berakhir dengan dua salinan React dan error "invalid hook call" yang terkenal membingungkan.
File mana di dalam package-nya?
Menemukan foldernya baru separuh pekerjaan. package.json milik package itu sendiri menyatakan file mana yang seharusnya didapat sebuah import.
{
"name": "some-library",
"main": "./dist/index.js", // the old field, still widely used
"types": "./dist/index.d.ts", // where TypeScript looks
"exports": { // the modern field, and it WINS
".": "./dist/index.js",
"./server": "./dist/server.js",
"./package.json": "./package.json"
}
}exports itu dinding sekaligus peta: kalau sebuah path tidak terdaftar, kamu tidak bisa mengimpornya, meski file-nya jelas ada di disk.Alias
@/features/i18n/locales bukan sebuah package. Ia alias yang dikonfigurasi di tsconfig.json, ditulis ulang jadi path sungguhan oleh alat build-mu. Ia menyelamatkanmu dari ../../../features/i18n/locales, yang rusak begitu kamu memindahkan sebuah file.
// tsconfig.json in this project
{
"compilerOptions": {
"paths": {
"@/*": ["./*"] // "@/features/x" -> "./features/x"
}
}
}vitest.config.mts di sini menyalakan resolve.tsconfigPaths — kalau tidak, test akan gagal pada import yang sebenarnya lolos compile.Mendiagnosis "Cannot find module"
- Apakah ejaannya benar, termasuk huruf besar-kecilnya? Di Linux,
Reactdanreactitu file berbeda; di macOS tidak, dan itu sebabnya bug ini hanya muncul di CI. - Apakah ada di
package.json? Kalau tidak,bun adddulu. - Apakah ada di
node_modules?ls node_modules/nama-nya. - Apakah proses install-nya benar-benar selesai? Jalankan ulang dan baca output-nya.
- Apakah itu alias yang tidak dikenali alat build-mu? Cek
pathsdan konfigurasi bundler-nya. - Apakah itu subpath yang tidak diizinkan peta
exportspackage-nya? - Pilihan terakhir:
rm -rf node_modules && bun install.
Tugas praktik
Di proyek ini, jalankan cat node_modules/next/package.json | head -40 dan temukan field exports-nya. Lalu coba bun run -e 'import("next/dist/server/lib/some-internal.js")' dan baca kegagalannya. Terakhir, buka tsconfig.json, ubah "@/*" jadi "~/*", jalankan bunx tsc --noEmit, dan lihat semua import rusak sekaligus — lalu kembalikan.
Hasil yang diharapkan
Puluhan error 'Cannot find module', semuanya beres dengan mengembalikan satu baris.