Filesystem — fs y path
fs es el módulo nativo de Node para el sistema de archivos, con tres APIs distintas para casi cada operación — elegir la correcta importa.
Las tres variantes
Sección titulada «Las tres variantes»import { readFileSync } from "node:fs"// síncrona: bloquea hasta terminarimport { readFile } from "node:fs"// callback: la más vieja, evitar en código nuevoimport { readFile as readFileAsync } from "node:fs/promises"
// promesas: la que se usa hoy
// Síncrona — bloquea todo el proceso hasta que terminaconst contenido = readFileSync("archivo.txt", "utf-8")
// Promesas — no bloquea, se puede awaitconst contenido2 = await readFileAsync("archivo.txt", "utf-8")La versión síncrona solo tiene sentido en scripts de un solo uso o en el arranque de la aplicación (por ejemplo, leer configuración antes de iniciar el servidor). Usarla durante una request bloquea el event loop completo y afecta a todas las solicitudes concurrentes, no solo a la actual.
Operaciones comunes (API de promesas)
Sección titulada «Operaciones comunes (API de promesas)»import { mkdir, readFile, readdir, stat, unlink, writeFile} from "node:fs/promises"
await readFile("archivo.txt", "utf-8") // leer como textoawait readFile("imagen.png") // sin encoding: devuelve un Buffer (binario)await writeFile("archivo.txt", "contenido nuevo") // sobrescribe si existe, crea si noawait mkdir("carpeta/anidada", { recursive: true }) // crea toda la ruta si hace faltaawait readdir("carpeta") // lista nombres de archivos/carpetasawait stat("archivo.txt") // metadata: tamaño, fechas, si es directorioawait unlink("archivo.txt") // borrar un archivo{ recursive: true } en mkdir es el equivalente a mkdir -p — sin eso, falla si algún directorio intermedio de la ruta no existe todavía.
path: armar rutas sin romper en otro sistema operativo
Sección titulada «path: armar rutas sin romper en otro sistema operativo»Concatenar rutas con / a mano rompe en Windows (usa \). path arma la ruta correcta según el sistema operativo donde corre el proceso.
import path from "node:path"
path.join("carpeta", "subcarpeta", "archivo.txt")// 'carpeta/subcarpeta/archivo.txt' en Linux/Mac, 'carpeta\subcarpeta\archivo.txt' en Windows
path.resolve("carpeta", "archivo.txt")// ruta absoluta, resuelta desde el directorio de trabajo actual
path.extname("archivo.txt") // '.txt'path.basename("/a/b/archivo.txt") // 'archivo.txt'path.dirname("/a/b/archivo.txt") // '/a/b'path.join es el que se usa casi siempre para armar una ruta a partir de partes; path.resolve cuando específicamente necesitas una ruta absoluta.
import.meta.url: saber dónde está el archivo actual (ESM)
Sección titulada «import.meta.url: saber dónde está el archivo actual (ESM)»En CommonJS existían __dirname/__filename automáticamente. En ES Modules no existen — el equivalente es:
import path from "node:path"import { fileURLToPath } from "node:url"
const __filename = fileURLToPath(import.meta.url)const __dirname = path.dirname(__filename)Referencia de filesystem
Sección titulada «Referencia de filesystem»| Función | Qué hace |
|---|---|
readFile / writeFile (promises) | Leer/escribir, la variante a usar en código de servidor |
readFileSync | Solo para scripts o arranque, bloquea el proceso |
mkdir(ruta, { recursive: true }) | Crear carpetas, incluyendo intermedias |
path.join(...) | Armar una ruta cross-platform |
path.resolve(...) | Ruta absoluta desde el directorio actual |
Rutas, tamaños y errores
Sección titulada «Rutas, tamaños y errores»readFilesin segundo argumento de encoding devuelve unBuffer, no un string — para texto, siempre pasar'utf-8'explícito.- Operaciones de archivo grande se benefician de streams en vez de
readFile/writeFilecompleto en memoria — ver Streams. - Rutas relativas en
fsse resuelven contraprocess.cwd()(desde dónde se ejecutó el comandonode ...), no contra la carpeta del archivo que las escribe — para eso hace faltaimport.meta.url+path.dirnamecomo arriba.