Node 1
개인 프로젝트를 진행하면서 자주사용했던 Node.js 모듈을 한 번에 정리해보고자 한다.🙌
📌Node.js
Node.js는 개발자가 웹 브라우저 외부에서 JavaScript 코드를 실행할 수 있는 오픈 소스 크로스 플랫폼 JavaScript 런타임 환경이다.
우리가 Javascript를 실행하기 위해서는 웹 브라우저가 반드시 필요했으나, Node.js의 등장으로 서버, 데스크톱 환경에서도 Javascript 코드를 실행할 수 있게 되었다.
기본적으로 Node.js도 JS로 만들어져 있으며, 개발자 또한 JS를 활용해 프로그램을 작성할 수 있다.
React, Next.js 처럼 FE에서 사용하는 많은 프레임워크나 라이브러리를 실행하기 위해서는 npm install
, npm init
과 같은 명령어를 사용하는데 이 명령어는 Node.js 런타임(프로그램이 실행되는 시간 또는 환경)과 npm(Node Package Manager)를 기반으로 동작하게 된다.
즉 우리도 알게 모르게 대부분의 프로젝트가 Node.js 생태계에서 실행되는 것이다!
✍CommonJS VS ESModules
처음 npm init -y
으로 node.js 환경을 만들고 아래와 같이 import 구문을 사용했더니 오류가 발생했다.
1
import puppeteer from "puppeteer"
이는 Node.js는 기본적으로 CommonJS를 사용하기 때문이다. 즉 오류를 해결하기 위해선 아래와 같이 작성해주어야 한다.
1
const puppeteer = require("puppeteer")
다만 나는 ESModule방식이 익숙해서, 아래와 같이 package.json
에 type을 작성해 import
구문을 사용할 수 있도록 수정해주었다.
1
2
3
4
5
6
7
{
"name": "today-news",
"version": "1.0.0",
"type": "module", //🌟
"main": "index.js",
//생략...
}
❗그렇다면 두 방식의 차이점은 무엇이 있을까?
항목 | CommonJS (require ) | ECMAScript Modules (import ) |
---|---|---|
로딩 방식 | 동기적 (synchronous) | 비동기적 (asynchronous) |
주요 문법 | require() / module.exports | import / export |
폴더 모듈 지원 | O (폴더 내 index.js 등 자동 인식) | X (명시적 경로 필요: ./folder/index.js ) |
JSON 파일 로딩 | .json 자동 파싱 | import 시 assert { type: "json" } 필요 |
기본 해석 방식 | 확장자 없으면 JavaScript로 해석 | .js , .mjs , .cjs 만 허용 |
Top-level await 지원 | ❌ (CommonJS는 top-level await 미지원) | ✅ (ESM은 기본 지원) |
🙌Next.js에서 만났던 Node.js의 모듈
Node 모듈은 기본적으로 client에서는 사용할 수 없기 때문에 대부분 api 작성을 위한 route.ts
파일에서 Node.js 모듈을 사용했었다.
아래는 내가 자주 사용했던 모듈을 위주로 정리한 내용이다.
path
파일 경로나 디렉토리 경로 조작용 유틸리티를 제공한다.
1
2
3
import path from "path"
const fullPath = path.join(__dirname, "uploads", "file.jpg")
__dirname
은 현재 실행 중인 파일이 위치한 디렉토리 경로를 나타내는 Node.js 내장 변수uploads
는 하위 폴더 이름file.jpg
는 그 폴더 안에 있는 파일 이름
path.join
이 이 세 가지를 합쳐서, 다음과 같은 결과를 만들어 낸다. 📌 Windows 기준 : C:\Users\YourName\project\uploads\file.jpg
fs (File System)
Node.js에서 파일을 읽고, 쓰고, 수정하고, 삭제할 수 있는 모듈이다. 기본적으로는 콜백 방식으로 작동해서, import { mkdir } from 'fs'
처럼 불러와 사용하였으나 node.js 10.0 이상 부터 fs/promise
로 호출하여 Promise 기반 비동기 처리가 가능하도록 모듈을 불러올 수 있게 되었다.
1
2
3
4
5
6
7
8
9
import {
writeFile,
mkdir,
unlink,
readdir,
copyFile,
rm,
readFile,
} from "fs/promises"
writeFile(filePath, data)
파일을 생성하거나 덮어쓰기 할 때 사용
1
2
3
import { writeFile } from "fs/promises"
await writeFile("output.txt", "Hello, world!")
- output.txt 파일이 생성되고 “Hello, world!”가 들어감
mkdir(dirPath, { recursive: true })
디렉토리 생성. {recursive: true}
는 만약 지정한 경로에 해당하는 부모 디렉터리가 없다면, 자동으로 생성하는 명령어다.
1
2
3
import { mkdir } from "fs/promises"
await mkdir("public/images", { recursive: true })
- public과 public/images 폴더가 없으면 모두 생성됨
unlink(filePath)
특정 파일을 삭제한다.
1
2
3
import { unlink } from "fs/promises"
await unlink("output.txt")
- output.txt 파일이 삭제된다.
- 존재하지 않으면 에러가 발생하므로 이 경우에는 try/catch문을 활용해 에러를 방지한다.
unlink
는 특정 파일 1개만 삭제함에 주의한다. (폴더 삭제 명령어는rm
이다.)
readdir(dirPath)
폴더 안에 있는 파일/디렉터리 이름 목록을 배열로 반환한다.
1
2
3
4
import { readdir } from "fs/promises"
const files = await readdir("./logs")
console.log(files) // 예: ['log1.txt', 'log2.txt']
copyFile(src, dest)
파일을 복사 한다.
1
2
3
import { copyFile } from "fs/promises"
await copyFile("original.jpg", "copy.jpg")
예시를 좀 더 살펴보자.
1
2
3
4
5
documents/
├── my1/
│ └── origin.txt
└── my2/
└── (여기에 copy.txt로 복사하고 싶음!)
다음과 같은 상황이 있을 때 명령어를 어떻게 작성해야 할까?
1
2
3
import { copyFile } from "fs/promises"
await copyFile("documents/my1/origin.txt", "documents/my2/copy.txt")
다음과 같이 어떤 파일을 어디에 보낼 것인지 정확히 입력만 해주면 된다.
rm(path, { recursive: true, force: true })
파일이나 폴더를 재귀적으로 삭제한다.
1
2
3
import { rm } from "fs/promises"
await rm("tmp/frames", { recursive: true, force: true })
- tmp/frames 폴더 및 하위 파일/폴더 모두 삭제됨
force: true
는 경로가 잘못되는 등의 문제로 삭제할 폴더가 없는 경우에도 에러를 발생시키지 않는다.
이때 재귀적으로 삭제한다는 것이 어떤 의미인지 살펴보자면
1
2
3
4
5
documents/
├── my1/
│ └── first.txt
└── my2/
└── second.txt
1
await rm("documents", { recursive: true, force: true })
다음과 같은 폴더 구조를 삭제하고자 이런 명령을 내렸다고 가정해보자. 이때 recursive: true
옵션을 사용해 documents 안의 하위 폴더와 그 안의 모든 txt 파일까지 전부 삭제된다!
http
os
운영체제 관련 정보와 기능을 제공한다.
tmpdir
운영 체제의 임시 파일 기본 디렉터리 경로를 가져오는 데 사용된다.
1
2
3
import { tmpdir } from "os"
const tempPath = tmpdir()
crypto
암호학 적으로 안전한 기능을 제공한다.
randomUUID
1
2
3
import { randomUUID } from "crypto"
const id = randomUUID()