20.3 코어 모듈, 파일 모듈, npm 모듈
모듈은 코어 모듈, 파일 모듈, npm 모듈 세 가지로 나뉩니다.
코어 모듈
코어 모듈은fs나os처럼 노드 자체에서 제공하는 모듈이며, 이들은 모두 예약어입니다(fs와os는 이 장에서 다시 설명합니다).파일 모듈
파일 모듈은 이미 봤습니다.
우리는module.exports에 할당되는 파일을 만들고 그 파일을 불러왔습니다.npm 모듈
npm 모듈은 특별한 디렉터리node_modules에 저장되는 모듈 파일입니다.
require 함수 - 모듈 타입 판단
require 함수를 사용하면 노드는 함수의 매개변수를 보고 어떤 타입인지 판단합니다.
[표 20-1]에 모듈 타입을 정리했습니다.
표 20-1 모듈 타입
| 타입 | 매개변수 | 예제 | 
|---|---|---|
| 코어 | /../.../ 등으로 시작하지 않습니다. | require(‘fs’)  require(‘os’) require(‘http’) require(‘child_process’)  | 
| 파일 | /../.../ 등으로 시작합니다. | require(‘./debug.js’)  require(‘/full/path/to/module.js’) require(‘../a.js’) / require(‘../../a.js’)  | 
| npm | 코어 모듈이 아니며 /../.../로 시작하지도 않습니다. | require(‘debug’)  require(‘express’) require(‘chalk’) require(‘koa’) require(‘q’)  | 
코어 모듈
process와 buffer 같은 일부 코어 모듈은 전역이고 명시적인 require 문 없이 사용할 수 있습니다.
 [표 20-2]에 코어 모듈을 정리했습니다.
표 20-2 코어 모듈
| 모듈 | 전역 여부 | 설명 | 
|---|---|---|
| assert | 아님 | 테스트 목적으로 사용합니다. | 
| buffer | 전역 | 입출력 I/O 작업에 사용합니다(주로 파일과 네트워크). | 
| child_process | 아님 | 외부 프로그램(노드 프로그램이 아니어도 됩니다)을 실행할 때 필요한 함수입니다. | 
| cluster | 아님 | 다중 프로세스를 이용해 성능을 올릴 수 있게 합니다. | 
| crypto | 아님 | 내장된 암호화 라이브러리입니다. | 
| dns | 아님 | 네트워크 이름 해석에 쓰이는 도메인 이름 시스템(DNS) 함수입니다. | 
| domain | 아님 | 에러를 고립시키기 위해 I/O 작업이나 기타 비동기적 작업을 그룹으로 묶을 수 있습니다. | 
| events | 아님 | 비동기적 이벤트를 지원합니다. | 
| fs | 아님 | 파일시스템 작업에 쓰입니다. | 
| http | 아님 | HTTP 서버 및 관련된 유틸리티입니다. | 
| https | 아님 | HTTPS 서버 및 관련된 유틸리티입니다. | 
| net | 아님 | 비동기적 소켓 기반 네트워크 API입니다. | 
| os | 아님 | 운영체제 유틸리티입니다. | 
| path | 아님 | 파일시스템에서 사용하는 경로(path) 관련 유틸리티입니다. | 
| punycode | 아님 | 유니코드 인코딩을 지원하며 ASCII 부분집합을 일부 사용합니다. | 
| querystring | 아님 | URL 쿼리스트링을 해석하고 만드는 데 쓰입니다. | 
| readline | 아님 | 대화형 I/O 유틸리티, 주로 명령줄 프로그램에서 사용합니다. | 
| smalloc | 아님 | 버퍼에 메모리를 명시적으로 할당할 때 사용합니다. | 
| stream | 전역 | 스트림 기반 데이터 전송에 사용합니다. | 
| string_decoder | 아님 | 버퍼를 문자열로 변환합니다. | 
| tls | 아님 | 보안 전송 계층(TLS) 통신 유틸리티입니다. | 
| tty | 아님 | 저수준 TTY(TeleTYpewriter) 함수입니다. | 
| dgram | 아님 | 사용자 데이터그램 프로토콜(UDP) 네트워크 유틸리티입니다. | 
| url | 전역 | URL 파싱 유틸리티입니다. | 
| util | 아님 | 내부 노드 유틸리티입니다. | 
| vm | 아님 | 자바스크립트 가상 머신입니다. 메타프로그래밍이나 컨텍스트 생성에 쓰입니다. | 
| zlib | 아님 | 압축 유틸리티입니다. | 
코어 모듈 중 가장 중요한 것들은 이 장에서 설명하겠지만, 이들 모듈 전체를 설명하는 것은 이 책의 범위를 벗어납니다.
 하지만 이렇게 정리해 두면 스스로 정보를 찾아볼 때 도움이 될 겁니다.
 이들 모듈에 대한 상세 정보는 노드 API 문서(https://nodejs.org/api/)를 참고하십시오.
npm 모듈
마지막으로 npm 모듈입니다.
 npm 모듈은 특수한 이름 표기법을 사용하는 파일 모듈입니다.
 모듈 x를 가져올 때, x가 코어 모듈 이름이 아니라면 노드는 먼저 현재 디렉터리에 node_modules 서브디렉터리가 있는지 확인합니다.
 node_modules 서브디렉터리가 있으면 그 안에서 x를 찾습니다.
 찾지 못하면 부모 디렉터리로 올라가서 node_modules 서브디렉터리가 있는지, 있다면 모듈 x가 있는지 확인합니다.
 모듈을 찾거나 루트 디렉터리에 도달할 때까지 이 과정을 반복합니다.
 예를 들어 프로젝트가 home/jdoe/test_project에 있고 애플리케이션 파일에서 require('x')를 호출한다면, 노드는 다음과 같은 순서로 모듈 x를 찾습니다.
- home/jdoe/test_project/node_modules/x
 - home/jdoe/node_modules/x
 - home/node_modules/x
 - /node_modules/x
 
대부분의 프로젝트에서는 애플리케이션 루트에 node_modules 디렉터리가 하나 있기 마련입니다.
 이때 node_modules 디렉터리에 직접 뭔가 추가하거나 제거해서는 안됩니다.
 모듈 파일 관련 작업은 모두 npm에서 하도록 해야 합니다.
 그렇긴 해도, 노드가 모듈을 가져올 때 어떤 순서로 찾는지 알아두면 도움이 될 때가 있습니다.
 특히 모듈에서 어떤 문제가 생겨서 디버그할 때 이런 지식이 도움이 될 수 있습니다.
직접 작성하는 모듈을 node_modules에 저장해서는 안 됩니다.
 그렇게 해도 모듈이 동작하기는 하지만, node_modules 디렉터리는 언제든 부담 없이 삭제하더라도 package.json 파일에 기록된 의존성 리스트를 통해 npm으로 다시 설치할 수 있다는 장점이 있습니다.
 직접 만든 모듈을 node_modules 디렉터리에 저장하면 삭제했을 때 되살릴 수 없습니다.
 물론 npm 모듈을 직접 만들고 그 모듈을 npm으로 관리할 수 있지만, node_modules 안에 있는 내용을 직접 수정해서는 안 됩니다.