모듈 : 프로그램을 작은 기능 단위로 쪼개고 파일 형태로 저장해 놓은 것
모듈을 사용해 코딩을 하면 코드가 중복되지 않는다. 수정 필요시, 모듈만 수정하면 된다. 직접 만들어 사용할 수도 있고, node.js안의 모듈을 가져다 사용할 수도 있다.
모듈을 어떻게 가져다 사용할 것인지, 또는 이 함수를 어떻게 모듈로 만들 것인지에 관련된 것들을 모듈 시스템이라고 한다.
node.js에서 모듈 사용 시 2가지 방법이 있다.
CommonJS 모듈 시스템 : node.js 의 기본 모듈 시스템
ES 모듈 시스템 : ECMAScript의 표준 모델 시스템
CommonJS 모듈 시스템은 node.js가 처음 만들어질 때부터 사용해온 방법이다. 이후에 표준화 된 것이 ES 모듈 시스템이다. node.js에서는 CommonJS 가 기본이고, ES 또한 사용할 수 있도록 지원하고 있다.
두 가지는 사용하는 키워드가 조금 달라서 이번 학습은 CommonJS 기준으로 진행된다.
js파일을 생성하고 모듈로 사용하기 위해서는 생성한 변수를 외부로 내보내줘야 한다.
module.exports
이 때, 위와 같은 구문을 사용한다. 사용 예시를 보자.
const user = "홍길동";
module.exports = user;
const hello = (name) => {
console.log(`${name} 님, 안녕하세요?`);
};
module.exports = hello;
이렇게 생성한 모듈들을 어떻게 가져다 쓸까? 새 js파일을 또 생성하자.
require()
모듈을 가져올 때는 require문을 사용하고, 괄호 안에는 ""안에 모듈의 위치를 지정하면 된다.
const user = require("./user");
const hello = require("./hello");
hello(user);
js는 역시 생략이 가능하므로 user.js, hello.js 파일에 있는 내용을 가지고 와서 user, hello로 할당하라는 의미이다. 이렇게 모듈로 나타낸 이유는 뭘까? user와 hello를 따로 모듈로 관리하기 때문에 논리적인 구조를 한 눈에 확인할 수 있다. 코드를 기능별로 나누어 따로 관리할 수 있는 것이다. 변경되는 내용들은 이전에 모듈 만든 파일에서 수정하면 된다.
앞서 본 모듈 파일들은 내보내는 변수가 1개 뿐이었다. 2개 이상의 값을 내보낼 때는?
const user1 = "Kim";
const user2 = "Lee";
const user3 = "Choi";
module.exports = {user1, user2};
이렇게 중괄호를 통해 내보낼 값을 지정할 수 있다.
const {user1, user2} = require("./users-1");
이렇게 내보낸 값을 가져올때도 중괄호를 사용한다.
node.js의 홈페이지에 들어가서 Docs를 누르면 다양한 모듈들이 존재하는 것을 확인할 수 있다. 노드에서 기본적으로 제공하는 모듈을 코어 모듈이라고 한다. 몇 가지만 알아보자. 기능, 모듈명, 제공하는 기능 순으로 작성하겠다.
파일 시스템 fs : 파일, 폴더에 접근할 수 있는 기능
HTTP http : HTTP 서버 만들고 요청을 처리하는 기능
경로 path : 파일 경로와 관련된 작업을 하는 기능
스트림 streams : 데이터 스트림을 처리하는 기능
암호화 crypto : 암호화와 관련된 기능
운영체제 os : 운영체제와 상호 작용하는 기능
유틸리티 util : 다양한 유틸리티 함수 제공
이벤트 events : 이벤트 기반 프로그래밍을 지원하는 기능

이런 형태로 되어 있는데, 여기서 CJS는 CommunJS 모듈 시스템, ESM은 ES 모듈 시스템이다. 쓰고 싶은 형태로 바꿔서 쓰면 된다.
글로벌 모듈 : require 없이 사용할 수 있는 모듈
예로 console.log() 가 있다. 이를 우리는 여태 require 문 없이 사용했었다. 원래라면 다음과 같이 사용했어야 했을 것이다.
global.console.log()
이번에는 글로벌 모듈에 속한 변수 몇 개를 보자.
- __dirname : 현재 모듈이 있는 폴더명을 가져 옴
- __filename : 현재 모듈의 파일명을 가져 옴
다음과 같은 역할을 하는 속성이 있다.
console.log(`현재 모듈이 있는 폴더: ${__dirname}`);
console.log(`현재 모듈의 파일명 : ${__filename}`);
여기서 dirname은 here.js 파일이 있는 폴더를, filename은 현재 파일의 이름을 알려주는 변수이다.
현재 모듈이 있는 폴더: C:\Users\user\Desktop\doit-node\basics\02
현재 모듈의 파일명 : C:\Users\user\Desktop\doit-node\basics\02\here.js
결과는 절대 경로로 보여준다. 위 변수도 글로벌 모듈 소속이므로 require 문을 필요로 하지 않는다.
앞서 공부한 node.js의 코어 모듈 중 path 모듈과 파일 시스템 모듈의 사용법에 대해서 알아보자.
path 모듈은 왜 필요할까?
그 전에 절대 경로, 상대 경로에 대해 알아보자.
파일을 다룰 때, 경로를 어떻게 표현하느냐에 따라 달라진다.
- 절대 경로 : 루트(시작부분) 부터 파일까지 한꺼번에 보여주는 경로
(윈도우에서는 드라이브(ex C)까지, Mac에서는 표현되지 않는다.- 상대 경로 : 기준이 되는 파일이 있을 경우 사용하는 경로
같은 폴더에 있을 경우 표기 : ./
부모 폴더에 있을 경우 표기 : ../
하위 폴더에 있을 경우 표기 : /
node.js 홈페이지의 Docs에서 다양한 path 모듈들과 그 사용법 등을 확인할 수 있다. 우리는 자주 사용하는 함수 몇 가지만을 함께 볼 것이다..
시작에 앞서 path 모듈을 가져오는 방법에 대해 알아보고 가자.
const path = require("path");
위 코드를 꼭 포함시키도록 하자.
말 그대로 묶는다(join)는 뜻이다. 여러 조각으로 된 텍스트를 가져다가 하나의 경로로 만든다.
const path = require("path");
const fullpath = path.join('some', 'work', 'ex.txt');
console.log(fullpath);
위 코드는 some, work, ex.txt 세 텍스트를 하나의 경로로 만들겠다는 의미이다.
결과는 다음과 같다.
some\work\ex.txt
세 문자열이 묶여 하나의 경로가 되었다.
경로만 추출하는 함수이다.
const path = require("path");
const dir = path.dirname(fullpath);
console.log(dir);
이 코드는 fullpath라는 경로가 있는데 여기서서 파일 이름을 빼고 경로만 추출해 달라는 의미를 가진다.
결과는 다음과 같다.
some\work
파일명만 추출하는 함수이다. 이는 2가지 형태로 사용할 수 있다.
우선 첫번째 형태는 기본적인 방법이다.
const fn1 = path.basename(__filename);
__filename은 앞서 봤던 글로벌 모듈의 변수로, 현재 파일의 전체 경로를 담고 있다. 이 중에서 basename(파일명)만 추출해달라는 코드이다.
const path = require("path");
const fn1 = path.basename(__filename);
console.log(`전체 경로(__filename) : ${__filename}`);
console.log(fn1);
이 전체 코드를 실행해 보면
전체 경로(__filename) : C:\Users\user\Desktop\doit-node\basics\03\path.js
path.js
결과는 다음과 같게 나온다. 파일 이름을 알고 싶을 때 사용하면 편리하다.
두번째 형태는 확장자를 제외할 수 있는 기능을 사용하는 형태이다. basename에는 확장자를 제외하는 기능이 있다.
const fn2 = path.basename(__filename, '.js');
다음과 같이 작성하면, .js라는 확장자를 빼고 순수하게 파일명만 가져와달라는 의미이다.
const path = require("path");
console.log(`전체 경로(__filename) : ${__filename}`);
const fn2 = path.basename(__filename, '.js');
console.log(fn2);
위 전체 코드를 실행해보면
전체 경로(__filename) : C:\Users\user\Desktop\doit-node\basics\03\path.js
path
아래 결과처럼 .js가 빠진 path만 출력된 것을 확인할 수 있다.
이렇게 require("path")를 통해 path 모듈을 가져오면 위와 같은 다양한 함수들을 사용할 수 있다.