자바스크립트를 서버에서 사용할 수 있는 큰 이유 중 하나는 모듈화가 가능하기 때문이다. 자바스크립트의 모듈화 명세를 만든 대표적인 그룹 중 'CommonJS'가 있고, 이 CommonJS의 명세가 현재 node의 표준이 되어있다.
node 표준(=CommonJS의 명세)이 require
와 module.exports
이다.
그런데 ES6로 넘어오면서 자바스크립트 자체에서 ES6 Module이라는 이름으로 모듈화를 지원하기 시작했고 이것이 바로 import
와 export
이다.
먼저 CommonJS의 모듈화가 무엇인지 사용법은 어떤지 알고, ES6 에서 어떤식으로 이뤄지는지 알아보자.
원래는 module.exports 인데 숏컷으로 exports가 만들어졌다.
그러나 섞어서 쓰면 안된다.
exports는 module.exports를 가리키는 변수로써 그 사용을 도와주는 'helper' 역할로 참조만 한다.
무슨 소리냐면, exports와 module.exports 가 동일한 하나의 객체를 바라보고 있다는 소리다. 그래서 최종적으로 return 되는 것은 무조건 module.exports의 값이 된고, exports는 자연스레 무시된다. 기본적으로 아래와 같은 2가지 규칙이 있지만 특별한 상황이 아니라면 module.exports를 사용하는 것이 권장된다
// A.js
let x = 10
let mod = require('./B.js')
let result = mod.x
//B.js
let x = 20
exports.x = 30
위의 예제에서 result에 담기는 x의 값은 무엇인지 생각해보자.
먼저 A.js에서 B.js 모듈을 사용(require
)하고자 한다. 그렇다면 mod
에는 어떤 값이 들어가있을까?
console.log(mod)
를 찍어보면 { x : 30 }
이 찍히는 것을 확인할 수 있다. 객체가 들어왔으니 자연스레 result는 mod의 x 값인 30
이라는 것을 알 수 있다.
그렇다면 왜 mod
에는 객체 값이 들어갔을까?
여기서 B.js의 exports.x = 30
을 주시해보자. exports는 앞서 설명한 것처럼 '전역객체' 이다. 고로 객체의 형태로 require로 넘어오는 모습을 확인할 수 있다. 아래와 같이 사용해도 값은 30
이 동일하게 출력된다.
// A.js
let x = 10
let mod = require("./B").x;
console.log(mod) // 30
//B.js
let x = 20
exports.x = 30
CommonJS의 간단한 소개와 역사
Modules: CommonJS modules - Nodejs 공식문서
CommonJS와 마찬가지로 기본적으로 원하는 모듈을 내보내고 가져오는 것은 동일하나, 현재 브라우저들이 ES6를 완벽하게 지원을 하지 못해서 webpack이나 Babel 등의 컴파일러가 필요한 것이 단점이다. 더불어 이 모듈시스템은 strict 모드(use strict)로 동작한다.
export
또는 export default
improt ... from 위치
// 내보내기
export { something }
// 가져오기
import { something } from './파일명'
// 모든 객체를 가져오되 원하는 이름을 붙여서 사용가능
import * as obj from './파일명'
// default 키워드
export default 내보낼 변수명
// default 키워드를 이용한 경우, 내보낸 쪽에서 사용한 명칭을 그대로 사용하지 않아도 된다.
import 바꿀변수명 from './파일명'
참고사이트
module.exports VS export default
JavaScript modules
ES2015(ES6) 모듈 시스템 - 제로초
★You don't know JS module
Node.js에서 ES 모듈(import/export) 사용하기
추가 용어정리
- 서버사이드(server-side) : 네트워크의 한 방식인 클라이언트-서버 구조의 서버 쪽에서 행해지는 처리 ↔ 반대개념 : 클라이언트사이드
ES6 브라우저 지원현황 보니 몇몇 런타임환경 빼고는 거의 100% 지원되네요. 확인해보시면 좋을듯합니다.
https://kangax.github.io/compat-table/es6/