JavaScript 의 대표적인 모듈 시스템은 크게 두 가지가 있다.
1. CommonJS
2. ES6
CommonJS 는 초창기 Node.js 의 등장과 함께 나왔다면 , ES6 는 2015년에 등장하였다.
위 두 방식 모두 모듈을 다루는 방식이지만, 문법적 차이가 있다.
현재는 ES6 방식이 많이 이용되지만, Node.js 를 다루다 보면 CommonJS 방식도 심심치 않게 보인다.
따라서, 두 방식 모두 이해할 필요가 있고 이 글을 통해 정리해보겠다.
1️⃣ CommonJS
CommonJS 는 모듈로 내보낼 때 exports와 module.exports 를 사용한다.
그리고 내보낸 모듈을 받아올 때는 require 함수를 사용한다.
그렇다면, 각각 언제 사용하는지 알아보자.
✅ module.exports
module.exports 방식은 단 하나의 객체만 내보낼 때 사용된다.
또한, 모듈 내에서 한 번만 사용해야 된다.
아래 예시를 확인하자.
calculator.js 에서 sum 함수를 선언하고 module.exports 변수에 sum 함수를 할당해주었다.
그리고, main.js 에서 require 함수로 calculator.js 에서 내보낸 sum 함수를 sum 변수에 할당해주었다.
그렇다면, module.exports 변수는 단 하나의 기능만 내보낼 수 있는 것인가 ?
정답은 그렇지 않다.
여러 기능을 하나의 객체로 담아 내보내주면 된다.
아래 예시를 살펴보자.
지금처럼 math 객체 안에 PI 상수, sum, substract 메소드를 정의하고 내보내주면
main.js 안에서 해당 객체를 math 변수로 받고 사용이 가능하다.
그런데 지금처럼 아주 단순한 상황일 때는 하나의 객체로 내보내면 되지만,
프로젝트가 복잡해지면 여러 객체를 내보내야 되는 상황이 발생한다.
또한, 모듈 안에서만 사용되어 내보낼 필요가 없는 객체가 존재할 수도 있다.
✅ exports
여러 객체를 내보낼 때 즉, 내 입맛대로 내보내고 싶은 것을 내보내려면 exports 키워드를 사용하면 된다.
아래 예시를 확인해보자
지금 보면 calulator.js 안에 PI 상수는 내보내지 않았다.
따라서 main.js 에서 math.PI 를 실행시키면 main.js 안에서는 정의되어 있지 않으므로 undefined 가 출력된다.
실제로 main.js에서 math 를 출력해보면 calculator.js 에서 내보냈던 함수만 들어있는 것을 확인할 수 있다.
따라서 다음과 같이, 구조분해할당(destructuring)을 이용하면 변수명으로만 사용할 수 있다.
지금까지 CommonJS 방식으로 모듈을 다루는 법을 알아보았다.
이제 위의 예제들을 그대로 이용하여 ES6 방식으로 알아보자.
2️⃣ ES6
ES6 에서는 내보낼 때 export, 받아올 때 import 를 사용한다. 매우 직관적이다.
그리고, CommonJS 처럼 단일 객체를 내보낼 때와, 다중 객체를 내보낼 때 문법적 차이가 조금 있다.
단일 객체를 내보낼 때는 export dafault , 다중 객체를 내보낼 때는 export 를 사용한다.
예제를 살펴보기 전에, 가장 중요한 한 가지가 있다.
바로, 다음과 같이 package.json 파일을 조작해야 된다.
이와 같은 이유는, Node.js 는 기본적으로 CommonJS 로 동작하기 때문이다.
따라서, Node.js 에게 이제부터 ES6 문법으로 모듈을 사용할 것이라 알려주어야 하고,
그 방식이 위와 같은 것이다.
이제 위의 CommonJS 예제들을 하나씩 ES6 문법으로 바꿔보자.
✅ export default
위에서 서술했듯이, export default는 단일 객체를 내보낸다.
그리고 CommonJS의 module.exports 와 마찬가지로 모듈 내에서 한 번만 사용해야 된다.
아래 예시를 살펴보자.
import 다음에는 받아올 객체(JS에서는 함수도 객체임)와 from 뒤에는 파일 주소를 적는다.
CommonJS 처럼 export default 도 여러 기능들을 하나의 객체로 묶어서 내보낼 수 있다.
위와 같이 main.js 에서 math 로 받으면 math 객체 안에는 export 한 변수와 메서드가 내장되어 있다.
✅ export
이번에는 CommonJS 에서 exports 방식과 같은 export 에 대해 알아보자.
ES6에서 export 는 다중 객체를 내보낼 때 사용된다.
내가 내보내고 싶은 객체의 선언 앞에 export를 달아주면 끝이다.
ES6 는 CommonJS 와 달리 반드시 다중 객체를 내보낼 때 구조분해할당을 통해 받아와야 한다.
또한, CommonJS에서는 PI를 내보내지 않더라도, main.js에서 undefined가 출력되어 에러가 발생하지 않았지만,
ES6는 이것을 엄격하게 잡아주어 에러가 발생한다.
3️⃣ 모듈 시스템을 사용하는 이유
그렇다면 왜 이렇게 파일들을 여러 개로 분류하여 모듈로 관리하는 것일까 ?
프로젝트가 복잡해질수록, 모듈 관리의 중요성을 몸소 체감할 수 있다.
모듈을 사용하는 가장 큰 이유는 유지보수 용이성 때문이다.
파일 크기가 커질수록, 코드가 장황해지므로 이것을 분리하여 관리할 필요가 있다.
또한, 모듈을 사용하면 변수와 함수가 해당 모듈 내에서만 유효하다.
즉, export 하지 않는 이상 다른 모듈에서 사용이 불가능하다.
따라서 변수, 함수, 클래스 등을 조직적으로 관리하여 전역 변수가 혼동되는 네임스페이스의 오염을 방지할 수 있다.
'JavaScript' 카테고리의 다른 글
[JavaScript] drag (드래그) 관련 이벤트 전격 분석 (0) | 2024.09.10 |
---|---|
[JavaScript] Element.closest 메소드 분석 (0) | 2024.08.31 |
[JavaScript] 이벤트 버블링(Bubbling), 이벤트 위임(Delegation) (2) | 2024.08.31 |
[JavaScript] 콜백 함수와(Callback) 비동기(Asyncronous) 처리 (0) | 2024.08.11 |
[JavaScript] 싱글 쓰레드와 비동기(Asyncronous) (0) | 2024.07.27 |