Node.js, Package, dan Ekosistemnya · 5/7
Core module: fs, path, dan kawan-kawan
Membaca dan menulis file, menggabung path dengan aman, dan kenapa jangan pernah menyusun path pakai penggabungan string.
Baca 28 menit
Setelah pelajaran ini kamu bisa
- Membaca dan menulis file dengan API berbasis promise
- Menyusun path yang bekerja di setiap sistem operasi
- Menjelaskan kenapa jangan pernah menggabungkan string path
- Menyebutkan core module yang layak diketahui dan fungsinya masing-masing
Core module sudah termasuk di dalam Node — tidak perlu install, tidak ada di package.json. Itulah kemampuan yang dipinjamkan runtime kepadamu, dan segelintir di antaranya sudah mencakup sebagian besar pekerjaan server.
| Module | Untuk | Kamu akan memakainya |
|---|---|---|
node:fs | Membaca dan menulis file | Sering |
node:path | Menyusun dan membedah path file | Setiap kali kamu menyentuh fs |
node:crypto | Hashing, nilai acak, UUID | Untuk session dan password |
node:os | Platform, jumlah CPU, direktori temp | Sesekali |
node:url | Membedah URL | Sesekali |
node:http | Server mentah | Jarang — biasanya dibungkus framework |
node:sqlite | Database SQL bawaan | Proyek ini memakainya |
node:test | Test runner bawaan | Jarang — sebagian besar tim memilih vitest |
Membaca dan menulis file
import { readFile, writeFile, mkdir, readdir } from "node:fs/promises";
// Always the promise API. Always specify the encoding, or you get a Buffer.
const text = await readFile("data/notes.md", "utf8");
await writeFile("data/out.json", JSON.stringify({ ok: true }, null, 2), "utf8");
await mkdir("data/exports", { recursive: true }); // no error if it exists
const files = await readdir("data");
// Reading a file that is not there throws. Handle it deliberately.
try {
await readFile("data/maybe.json", "utf8");
} catch (error) {
if (error.code === "ENOENT") {
// ENOENT = "Error NO ENTry". The commonest fs error by a distance.
} else {
throw error; // anything else is not ours to swallow
}
}Object error Node punya property code, dan mencocokkan berdasarkan itu jauh lebih andal daripada mencocokkan teks pesannya. ENOENT (tidak ada), EACCES (tidak ada izin), dan EEXIST (sudah ada) adalah tiga yang layak dihafal.
Path
Pemisah path berbeda antar sistem operasi, .. harus diselesaikan, dan garis miring ganda harus disederhanakan. node:path melakukan semuanya. Menggabungkan string tidak melakukan apa pun dari itu.
import { join, resolve, dirname, basename, extname } from "node:path";
join("data", "exports", "file.json"); // data/exports/file.json
join("data/", "/exports"); // data/exports - duplicate slash fixed
join("data/a", "..", "b"); // data/b - .. resolved
resolve("data/file.json"); // absolute, from the current directory
dirname("/app/data/file.json"); // /app/data
basename("/app/data/file.json"); // file.json
basename("/app/data/file.json", ".json"); // file
extname("/app/data/file.json"); // .json
// NEVER do this:
const bad = "data" + "/" + userInput + "/file.json";`join` dan `normalize` yang berfungsi, supaya kamu bisa melihat persis apa yang dilakukan versi aslinya — termasuk kenapa traversal bisa terjadi.
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.
Tugas praktik
Tulis scratch.ts yang membaca kode sumbernya sendiri dengan readFile, menghitung jumlah barisnya, dan menulis hitungannya ke data/lines.txt memakai join(process.cwd(), "data", "lines.txt") — dengan membuat direktorinya dulu pakai mkdir({ recursive: true }). Jalankan dengan node scratch.ts. Lalu hapus baris mkdir-nya dan baca kode error yang kamu dapat.
Hasil yang diharapkan
Jumlah baris tertulis ke file-nya; lalu `ENOENT` begitu mkdir dihapus.