React 배우기 전에 Javascript 복습
01. ES6 Modules 기본
모듈은 재사용 가능한 코드 조각을 캡슐화, 여러 자바스크립트 파일에서 재사용 가능
자바스크립트 모듈은 함수, 변수, 객체, 클래스등을 하나의 파일로 그룹
캡슐화란 내부를 보여주지 않고 간결하게 어떤 곳에서든 사용 가능
(1) 모듈의 기본 및 사용방법
ES6에서는 export 키워드를 사용하여 모듈을 만들고, import 키워드를 사용해 다른 파일에서 사용 가능
자바스크립트의 실행 환경은 브라우저 환경과 Node 환경 존재
Node 환경에서의 모듈 import 방식은 CommonJS 방식과 ES6 방식
React 개발 환경에서는 대부분 ES6 방식
CommonJS 방식은 주로 서버 사이드에서 사용
사용 방법
// math.js
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;
export const ONE = 1;
export const sample = {
one: 1,
two: 2
}
외부로 보낼 함수, 변수, 객체에 export 구문 사용
// 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
import 구문을 사용해서 다른 파일에서 함수를 불러와 사용
모듈을 사용해야 하는 이유
명확한 종속성 관리
원래 외부의 코드를 내부로 들여오기 위해서는 html에서는 script태그를 사용해 로드
<!-- 전통적인 스크립트 로딩 방식 -->
<script src="jquery.js"></script>
<script src="plugin.js"></script> <!-- 이 스크립트는 jquery.js에 의존 -->
<script src="app.js"></script> <!-- 이 스크립트는 plugin.js와 jquery.js에 의존 -->
=> 로딩 순서를 수동으로 관리
=> 소스 코드가 거대해질 경우 관리하기 어려워지고, 버그 발생 가능성 증가
=> 모듈 시스템을 사용하면 export 구문과 import구문을 사용해 쓰면 끝
// ES6 모듈 사용 예시
import $ from 'jquery';
import plugin from 'plugin'; // 자동으로 jQuery에 대한 의존성을 처리
import app from 'app'; // 모든 의존성이 충족되면 실행
캡슐화와 충돌 방지
복잡하고 보안, API키 같은 중요한 정보를 노출시키지 않기 위해 캡슐안에 넣어 노출 방지
전역 변수의 오염 방지, 이름이 서로 충돌하는 것도 방지
여러 스크립트에서 동일한 함수 이름을 사용하더라도 모듈을 사용하면
각 스크립트에서 정의된 함수는 해당 모듈 내에서만 유효
// module1.js
export function conflictFunction() {
console.log('Module 1의 함수');
}
// module2.js
export function conflictFunction() {
console.log('Module 2의 함수');
}
// app.js
import { conflictFunction as function1 } from './module1';
import { conflictFunction as function2 } from './module2';
function1(); // "Module 1의 함수"
function2(); // "Module 2의 함수"
효율적인 코드 로딩
기존의 방식은 필요하지 않은 기능까지 모두 가져왔지만
모듈 시스템을 이용하면 필요한 기능만 선택적으로 로드 가능
코드 스플리팅을 사용하면 사용자의 현재 요구에 따라 필요한 코드만 동적으로 로드 가능(지연 로딩, lazy-loading)
지연 로딩은 대규모 애플리케이션에서 성능과 자원 사용 최적화에 매우 효율적
// 동적으로 모듈 로드하기 (예: 사용자가 특정 기능을 활성화했을 때)
button.addEventListener('click', event => {
import('./heavyModule.js')
.then(module => {
module.heavyFunction();
})
.catch(err => {
console.error("모듈 로딩에 실패했습니다.", err);
});
});
02. 고급 모듈 기능
모듈의 각종 옵션을 적용해 고급 기능 이해
(1) 이름 바꾸기와 기본 내보내기
별칭 사용
import시 특정 요소에 as키워드를 이용해 별칭을 지정해 충돌 방지 및 명확성 증가
import { square as sqr } from './utils.js';
console.log(sqr(4)); // 16
기본 내보내기 (export default)
하나의 모듈에서 하나의 기본 값을 내보내고 이를 쉽게 가져오는 것을 의미
모듈당 하나의 주요 기능을 내보낼 때 유용
export dafault를 통해 내보내진 모듈은 import시 이름변경이 가능
(특정 경로에서 가져온(import) 값은 하나밖에 존재하지 않기 때문에 이름을 명시하지 안하도 특정 가능)
// math.js
export default function multiply(x, y) {
return x * y;
}
// export default를 통해 내보낼 수 있는 건 한 파일에 하나 뿐
// math.js에서는 export default가 무조건 한 개
// app.js
import multiply from './math.js';
console.log(multiply(6, 7)); // 42
// 모듈을 사용하는 app.js 입장에서는
// math.js로부터 가져오는 것은 무조건 multiply 뿐
// ./math.js 경로만 가지고서 모듈 특정 가능
// 따라서 이름을 multiply로 설정하지 않아도 상관없음
// 원래 import는 모듈 이름에 중괄호가 필요하나
// export default로 내보낸 값을 import할 때는 중괄호 필요없음
// export default 시 모듈이름 변경은 자유!
// utils.js
export default function square(x) {
return x * x;
}
// main.js
import mySquare from './utils.js';
console.log(mySquare(4)); // 출력: 16
(2) 전체 모듈 내용 가져오기
전체 내용 가져오기
모듈의 모든 내보내기를 한 번에 가져올 때 사용
// app.js
import * as MathFunctions from './math.js';
// math.js에 함수가 많을 때 일일이 쓰고 있을 수 없음
// *를 사용해 모든 것을 가져옴
// 객체 형태로써 사용가능
console.log(MathFunctions.add(10, 5)); // 15
console.log(MathFunctions.multiply(10, 5)); // 50