과거의 내가 미래의 나에게
모듈 시스템 정리 본문
모듈 시스템
기존에는 html 파일에서 script 태그를 사용하여 js 파일들을 실행했다. 그러나 js의 활용성이 커지면서 js 파일을 분리해서 사용해야 할 필요성이 생기고 이에 따라 한 html 파일에 여러 js 스크립트를 넣었더니 한 파일에서 쓴 것 마냥 내용이 전역으로 공유되어지고, 또 이에 따라 스크립트 load 순서에 힘을 쏟아야했다.
이러한 문제점에 따라 나온 것이 모듈 시스템이다. 모듈은 코드를 캡슐화하여 기능에 따라 파일 별로 분리한 코드 조각으로 재사용이 가능하며 사용 시 파일 별로 서로 영향이 없어야 하는 것이다.
ES6 이전까지는 공식적인 모듈 지원이 없었지만 ES6부터는 공식적인 모듈도 지원하게 되었고 또 그 이전에 모듈을 정의하기 위해 다양한 포맷이 등장했다.
이 곳에서는 대표적으로 사용되는 ES6의 모듈 포맷과 CommonJS의 모듈 포맷을 살펴볼 것이다.
CommonJS
CommonJS는 JS의 모듈화의 대표격 중 하나이다. 이는 현재 node.js의 표준이기도 하다.
불러오기는 require()을 통해서, 내보내기는 module.exports 혹은 exports를 사용한다.
exports는 module.exports를 참조하고 있는 객체이기에 주로 module.exports는 한 번에 내보낼 때 사용하고 exports는 여러개의 객체를 따로 내보낼 때 사용한다.
둘은 혼합해서 사용해서는 안되고 특별한 상황이 아니라면 module.exports를 사용하는 것이 권장된단다.
1. module.exports
// 내보내기
function test(){
//...
}
function test2(){
//...
}
// 단일 객체 내보낼수도
module.exports = test
// 여러 객체 내보낼수도 있다.
module.exports = {
test = test,
test2 = test2
}
// 불러오기
const obj = require('./test')
obj.test
obj.test2
2. exports.함수명 = 함수;
// 내보내기
exports.test = function() {
//..
}
exports.test2 = function() {
//..
}
// 불러오기
const obj = require('./test')
obj.test
obj.test2
ES6의 모듈 시스템
ES6에서 새로 도입된 모듈 시스템이다. 하지만 아직 브라우저들이 ES6를 완벽히 지원하지 못하는 상황이므로 webpack이나 babel같은 번들러들이 필요하다.
1. 내보내기
// 여러 객체 내보내기
export function test() {
//...
}
const test2 = function () {
//...
}
const test3 = function () {
//...
}
export { test2, test3 }
// 한꺼번에 내보내기. 하나의 모듈에 하나의 객체만 내보낸다.
const obj = {
test3: function () {
//...
}
test4: function () {
//...
}
}
export default obj
2. 불러오기
// export를 통해 내보냈을 때
// 원하는 것만 가져오기
import {test} from './test'
// 모든 객체 가져오기. 이름을 별도로 붙여서 사용할 수 있다.
import * as name from './test'
// export.default를 통해 내보냈을 때. 내보낸 쪽의 명칭을 그대로 사용하지 않아도 된다.
import obj from './test'
obj.test3
obj.test4
* 동적 import
CommonJS에서는 require로 정적으로도 동적으로도 모두 가능한 반면 위의 ES6의 모듈 시스템 방법으로는 정적으로만 import 가능하고 동적으로는 불가하다.
//import문에는 문자열로 이루어진 경로만 들어갈 수 있을 뿐, 함수나 기타 다른 것은 들어갈 수 없다.
// x
import Test from callLink()
// o
import Test from '../src"
// 조건부로 모듈을 불러올 수 없다
// x
if(n){
import Test from '../src"
}else{//..}
그럼 동적으로 import 하고 싶을 떄는 어떻게 해야 하나? 바로 import() 함수를 이용하면 된다.
import() 함수는 Promise를 반환하며, 모듈이 성공적으로 load 되면 해당 모듈을 나타내는 객체를 제공하게 된다.
const dynamicModulePath = './dynamicModule';
import(dynamicModulePath)
.then((dynamicModule) => {
// 동적 모듈 사용
dynamicModule.someFunction();
})
.catch((error) => {
console.error('모듈 로드 실패:', error);
});
동적 import는 코드 실행 중에 모듈을 로드 할 수 있기에 특정 조건이나 이벤트에 따라 모듈을 동적으로 삽입할 수 있게 하며, 모든 모듈을 미리 import하는 것이 아닌 필요한 시점에 따라 import 할 수 있기에 메모리 효율성 측면에서도 좋다.
CommonJS와 ES6의 모듈 시스템
commonJS와 ES6 모듈 시스템은 공존할 수 없음을 주의하자. 그 상세한 이유를 설명하는 대신 한 블로그 주소를 남길테니 파고들고 싶으면 참고하자
* CommonJS와 ES Modules은 왜 함께 할 수 없는가? - https://yceffort.kr/2020/08/commonjs-esmodules
참고 문서
- CommonJS와 ES6의 모듈시스템 - https://jh-7.tistory.com/9
- 자바스크립트 ES6 모듈 내보내기/불러오기 - https://www.daleseo.com/js-module-import/
'js 이론' 카테고리의 다른 글
옵셔널 체이닝 (0) | 2024.05.26 |
---|---|
JS 배열 함수 정리 (0) | 2023.11.26 |
구조 분해 할당 구문 (0) | 2023.08.31 |
js 시간 (0) | 2023.08.21 |
딥다이브 :: 생성자 함수에 의한 객체 생성 (0) | 2023.02.02 |