빠른 흐름
javascript
import { watch } from "node:fs";
let timer;
watch("./src", { recursive: true }, (eventType, filename) => {
clearTimeout(timer);
timer = setTimeout(() => {
console.log(`[changed] ${eventType}: ${filename}`);
rebuildIndex();
}, 100);
});파일 감시
먼저 머릿속에 들어와야 하는 기본형은 아래입니다.
- 프로세스 재시작 루프:
node --watch - 앱 내부 감시 로직:
fs.watch() - 중복 이벤트 완화: debounce
- 감시 범위 줄이기: 경로 필터 또는
--watch-path - 크로스 플랫폼 안정성: 상위 라이브러리 검토
개발 서버 자동 재시작이면 node --watch
프로세스 자체를 다시 띄우는 개발 루프가 목적이면 node --watch가 맞습니다. 앱 안에 감시 로직을 넣을 필요가 없습니다.
앱 로직 안에서 반응하려면 fs.watch()
인덱스 재생성, 파일 목록 갱신, 특정 디렉터리 동기화처럼 "변경을 감지해서 코드 한 조각을 실행"해야 하면 fs.watch()가 맞습니다.
watch 이벤트는 중복된다고 가정한다
에디터 저장 방식과 OS 파일 이벤트 차이 때문에 같은 파일 저장이 여러 이벤트로 들어오는 건 정상입니다. debounce가 기본 패턴입니다.
환경이 복잡하면 라이브러리도 고려한다
Docker 볼륨, 네트워크 파일 시스템, 여러 OS를 같이 상대하면 fs.watch() 차이가 더 드러납니다. 이때는 chokidar 같은 상위 추상화가 더 실용적일 수 있습니다.
감시 범위를 좁히는 것이 품질에 직접 영향을 준다
프로젝트 전체를 넓게 감시하면 저장 한 번에도 너무 많은 이벤트가 몰릴 수 있습니다. 실전에서는 "어디를 감시할 것인가"를 먼저 줄이는 편이 debounce보다 더 큰 효과를 줄 때가 많습니다.
언제 watch를 쓸까
체크포인트
- 개발 중 재시작:
node --watch - 앱 안 감시 로직:
fs.watch() - 중복 이벤트 억제: debounce
- 감시 범위 좁히기:
--watch-path또는 경로 필터 - 크로스 플랫폼 안정성:
chokidar검토 - 전체를 넓게 보기보다 필요한 디렉터리만 감시
주의할 점
fs.watch()는 저장 한 번에 여러 번 울릴 수 있다. debounce 없이 바로 빌드나 sync를 걸면 같은 작업이 겹쳐서 오히려 더 불안정해진다.
참고 링크
2 sources