firebase 등을 사용할 때 import { ... } from "./..../file.js"
과 같은 내용을 본 적일 있을 것이다. 혹은 html에서 script 태그를 사용할 때 type='module'이라고 지정하는 경우가 있다. 느낌적으로 해당 파일에서 함수를 불러오는 것을 알 수 있다.
(ES6 기준에서 작성합니다.)
Module 기본 사용법
ES6에서는 `export` 키워드를 사용해 모듈을 만들고, 다른 파일에서 사용할 수 있게 한다. 모듈은 재사용할 수 있는 함수, 객체 또는 원시값을 의미한다.
// math.js
export const add = (a,b) => a + b;
export const multiply = (a,b) => a*b;
export const ONE = 1;
export const numbers = {
one : 1,
two : 2,
three : 3,
};
위와 같이 math.js 파일에서 모듈화된 것을 가져와 사용하려면 다음과 같이 하면 된다.
// app.js
import { add, multiply, ONE, sample } from './math.js';
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
console.log(ONE); // 1
console.log(sample.two); // 2
모듈을 사용하는 이유
1. 종속성 관리가 쉬움
html에서 <script>를 사용해 js 파일을 로드합니다. 이와 같은 방식은 파일 간의 종속성과 로딩 순서를 수동으로 관리해야합니다. 이러한 방식은 규모가 커질수록 종속성을 추적하고 관리하기 어려워지며, 실수로 인해 버그가 발생할 수 있습니다.
<!-- 전통적인 스크립트 로딩 방식 -->
<script src="file.js"></script>
<script src="file2.js"></script> <!-- 이 스크립트는 file.js에 의존 -->
<script src="file3.js"></script> <!-- 이 스크립트는 file.js와 file2.js에 의존 -->
모듈 시스템을 사용하면 파일 간 종속성을 내부적으로 선언하므로, 파일 로드하는 순서에 신경 쓰지 않아도 된다. (모듈 로더가 종속성을 해석하고 올바른 순서로 스크립트를 묶어줌)
// ES6 사용 예시
import func1 from './file.js'
import func2 from './file1.js' // 자동으로 file.js에 대한 의존성 처리
import options from './file2.js' // 모든 의존성이 충족되면 실행
2. 코드 캡슐화, 충돌 방지
모듈은 자체적인 스코프를 가져 모듈 외부에서 모듈 내부 변수에 직접 접근할 수 없다. 따라서 전역 변수의 오염을 방지할 수 있고, 변수 이름이 충돌하는 것도 막아준다.
// module1.js
export function conflict() {
console.log('Module 1의 함수');
}
// module2.js
export function conflict() {
console.log('Module 2의 함수');
}
// app.js
import { conflict as func1 } from './module1.js';
import { conflict as func2 } from './module2.js';
func1(); // "Module 1의 함수"
func2(); // "Module 2의 함수"
3. 효율적인 코드 로딩
앞서 이야기했듯이 모듈 시스템을 통해 필요한 기능만 선택적으로 불러올 수 있고, 초기 로딩 시간을 단축할 수 있다. 코드 스플리팅을 사용하면 사용자의 현태 요구에 따라 필요한 코드만 동적으로 로드할 수 있다. 이러한 지연 로딩(lazy-loading)은 대규모 어플리케이션에서 성능과 자원 사용 최적화에 효과적이다.
// 동적으로 모듈 로드하기 (예: 사용자가 특정 기능을 활성화했을 때)
button.addEventListener('click', event => {
import('./heavyModule.js')
.then(module => {
module.heavyFunction();
})
.catch(err => {
console.error("모듈 로딩에 실패했습니다.", err);
});
});
내보내기와 가져오기
내보내기
시작할 때 한 것처럼 그때 그때 export할 수도 있지만, 파일 맨 끝에 `{}`사용해 한번에 필요한 것들을 export할 수 있다.
// math.js
export const add = (a,b) => a + b;
const multiply = (a,b) => a*b;
const ONE = 1;
const numbers = {
one : 1,
two : 2,
three : 3,
};
export {muliply, ONE, numbers};
위와 같은 export 방법은 named export라고 하며, 이와 다른 export로 default export로 단 한번 지정할 수 있다.
// utils.js
export default function square(x) {
return x * x;
}
불러오기
named export는 import할 때 `{}`로 감싸야 하지만, default export는 `{}`로 감싸지 않아도 된다. default export는 새로운 이름을 지정해 바로 불러올 수 있다. 단, 이름을 as를 이용해 바꿀 때는 `{}`로 감싸줘야 한다.
// named export
import { add, multiply, ONE, sample } from './math.js';
// default export
import sqr from './util.js'
import {default as sqr} from './util.js'
위에서 잠깐 봤듯이 import를 사용해 불러올 때 `as`를 `{}` 안에 사용해 원하는대로 이름을 변경할 수 있다.
import { multiply as mul } from './math.js';
console.log(mul(3, 4)); // 12
전체 모듈 내용 가져오기
아래와 같이 `*`을 사용해 한번에 모든 모듈을 가져올 수 있다.
// app.js
import * as MathFunctions from './math.js';
console.log(MathFunctions.add(10, 5)); // 15
console.log(MathFunctions.multiply(10, 5)); // 50
덤. 파이썬 import와의 비교
파이썬에서도 다른 파일에 정의한 함수를 import를 통해 불러올 수 있는데, 아래 두 코드는 같은 뜻을 가진다.
// javascript
import { multiply as mul } from './math.js';
// python
from math import multiply as mul
'Frontend > Today I Learned' 카테고리의 다른 글
[JS] 이벤트 겹쳤을 때 막는 방법 (+ 이벤트 캡처링, 버블링) (0) | 2024.08.23 |
---|---|
[JS, redux] Redux 소개 및 기본 사용법 (0) | 2024.08.19 |
[React] Hooks - useState, useEffect, useRef (0) | 2024.08.16 |
[CSS] 스크롤 바 스타일 (0) | 2024.08.13 |
[git] 자주 사용하는 기초적인 git 명령어 정리 (0) | 2024.08.07 |