코어 자바스크립트 - 모듈 내보내고 가져오기
export와 import 지시자는 다양한 방식으로 활용된다.
이전 챕터에서는 export와 import의 다양한 사용법을 배워보자.
선언부 앞에 export 붙이기
변수나 함수, 클래스를 선언할 때 맨 앞에 export를 붙이면 내보내기가 가능하다.
선언부와 떨어진 곳에 export 붙이기
선언부와 export가 떨어져 있어도 내보내기가 가능하다.
import *
무언갈 가져오고 싶다면 아래와 같이 이에 대한 목록을 만들어 import {...} 안에 적어주면 된다.
가져올 것이 많으면 import * as <obj> 처럼 객체 형태로 원하는 것들을 가지고 올 수 있다.
이렇게 한꺼번에 모든 걸 가져오는 방식을 사용하면 코드가 짧아진다.
하지만 어떤 걸 가져올 땐 그 대상을 구체적으로 명시하는 것이 좋다.
그 이유는
1. 웹팩(Webpack)과 같은 모던 빌드 툴은 로딩 속도를 높이기 위해 모듈들을 한데 모으는 번들링과 최적화를 수행한다.
이 과정에서 사용하지 않는 리소스가 삭제되기도 한다.
2. 어떤 걸 가져올 지 명시하면 이름을 간결하게 써줄 수 있다. say.sayHi() 보다 sayHi()가 더 간결하다.
3. 어디서 어떤 게 쓰이는지 명확하기 때무에 코드 구조를 파악하기 쉬워 리팩토링이나 유지보수에 도움이 된다.
import 'as'
as를 사용하면 이름을 바꿔서 모듈을 가져올 수 있다.
sayHi를 hi로, sayBye를 bye로 이름을 바꿔서 가져와보자.
export 'as'
export에도 as를 사용할 수 있다.
sayHi와 sayBye를 각각 hi와 bye로 이름을 바꿔 내보내보자.
이제 다른 모듈에서 이 함수들을 가져올 때 이름은 hi와 bye가 된다.
export default
모듈은 크게 두 종류로 나뉜다.
1. 여러 개의 함수가 있는 라이브러리 형태의 모듈(위 예시의 say.js)
2. 개체 하나만 선언되어 있는 모듈(아래의 user.js. class User 하나만 내보내기 함)
대개는 두 번째 방식으로 모듈을 만드는 걸 선호하기 때문에 함수, 클래스, 변수 등의 개체는 전용 모듈 안에 구현된다.
그런데 이렇게 모듈을 만들다 보면 자연스레 파일 개수가 많아질 수 밖에 없다.
그렇더라도 모듈 이름을 잘 지어주고,
폴더에 파일을 잘 나눠 프로젝트를 구성하면 코드 탐색이 어렵지 않으므로 이는 전혀 문제가 되지 않는다.
모듈은 export default라는 특별한 문법을 지원한다.
export default를 사용하면 '해당 모듈엔 개체가 하나만 있다'는 사실을 명확히 나타낼 수 있다.
내보내고자 하는 개체 앞에 export default를 붙여 모듈을 내보내면 중괄호 {} 없이 모듈을 가져올 수 있다.
모듈을 막 배우기 시작한 사람은 중괄호를 빼먹는 실수를 자주 한다.
named export한 모듈을 가져오려면 중괄호가 필요하고,
default한 모듈을 가져오려면 중괄호가 필요하지 않다는 걸 기억해 실수를 방지하자.
named export와 default export를 같은 모듈에서 동시에 사용해도 문제는 없다.
하지만 실무에선 이렇게 쓰지 않는다.
named export나 default dexport 둘 중 하나만 사용한다.
파일당 최대 하나의 default export가 있을 수 있으므로 내보낼 개체엔 이름이 없어도 괜찮다.
아래 예시에선 개체에 이름이 없지만 모두 에러 없이 잘 동작한다.
export default는 파일당 하나만 있으므로 중괄호 없이도 어떤 개체를 가지고 올지 정확히 알 수 있다.
그래서 이름이 없어도 괜찮다.
default를 붙이지 않는다면 개체에 이름이 없는 경우 에러가 발생한다.
'default' name
default 키워드는 기본 내보내기를 참조하는 용도로 종종 사용된다.
함수를 내보낼 때 아래와 같이 함수 선언부와 떨어진 곳에서 default 키워드를 사용하면
해당 함수를 기본 내보내기 할 수 있다.
흔치 않지만 user.js 라는 모듈에 default export 하나와 다수의 named export 가 있다고 해보자.
아래와 같은 방식을 사용하면 default export와 named export를 동시에 가져올 수 있다.
*를 사용해 모든 것을 객체 형태로 가져오는 방법도 있는데,
이 경우엔 default 프로퍼티는 정확히 default export를 가리킨다.
default export의 이름에 관한 규칙
named export는 내보냈을 때 사용한 이름 그대로 가져오므로 관련 정보를 파악하기 쉽다.
그런데 아래와 같이 내보내기할 때 쓴 이름과 가져오기 할 때 쓸 이름이 동일해야 한다는 제약이 있다.
named export와는 다르게 default export는 가져오기할 때 개발자가 원하는 대로 이름을 지정해줄 수 있다.
그런데 이렇게 자유롭게 이름을 짓다보면 같은 걸 가져오는데도 이름이 달라 혼란의 여지가 생길 수 있다.
이런 문제를 예방하고 코드의 일관성을 유지하기 위해 default export한 것을 가져올 땐
아래와 같이 파일 이름과 동일한 이름을 사용하도록 팀원끼리 내부 규칙을 정할 수 있다.
그런데 규칙이 있어도 이를 지키지 않는 사람이 있을 수 있기 때문에
어떤 팀은 named export만 사용할 것을 강제하는 경우도 있다.
모듈 하나에서 단 하나의 개체만 내보내는 경우에도 default없이 이름을 붙여 내보내면 혼란을 방지할 수 있기 때문이다.
이런 규칙은 모듈 다시 내보내기를 쉽게 해준다는 장점도 있다.
모듈 다시 내보내기
export ... from ... 문법을 사용하면 가져온 개체를 즉시 '다시 내보내기(re-export)'할 수 있습니다.
이름을 바꿔서 다시 내보낼 수 있는 것이다.
다시 내보내기가 왜 필요한 건지 의문이 들 것이다.
유스 케이스를 통해 다시 내보내기가 실무에서 언제 사용되는지 알아보자.
NPM을 통해 외부에 공개할 '패키지(package)'를 만들고 있다고 가정하자.
이 패키지는 수많은 모듈로 구성되어있는데, 몇몇 모듈은 외부에 공개할 기능을,
몇몇 모듈은 도와주는 헬퍼 역할을 담당하고 있다고 하자.
패키지 구조는 아래와 같다.
진입점 역할을 하는 '주요 파일'인 auth/index.js를 통해 기능을 외부에 노출시키면
이 패키지를 사용하는 개발자들은 아래와 같은 코드로 해당 기능을 사용할 것이다.
이 때 우리가 만든 패키지를 사용하는 외부 개발자가 패키지 안의 파일들을 뒤져 내부 구조를 건드리게 하면 안된다.
그러려면 공개할 것만 auth/index.js에 넣어 내보내기 하고 나머지는 숨겨야 한다.
이 때 내보낼 기능을 패키지 전반에 분산하여 구현한 후, auth/index.js에서 이 기능을 가져오고
이를 다시 내보내면 원하는 바를 어느 정도 달성할 수 있다.
이제 외부개발자들은 import {login} from "auth/index.js"로 우리가 만든 패키지를 이용할 수 있다.
export ... from ... 는 위와 같이 개체를 가지고 온 후 바로 내보낼 때 쓸 수 있는 문법이다.
아래 예시는 위 예시와 동일하게 동작한다.
default export 다시 내보내기
기본 내보내기를 다시 내보낼 때는 주의해야 할 점들이 있다.
user.js 내의 클래스 User를 다시 내보내기 한다고 가정해보자.
1. User를 export User from './user.js'로 다시 내보내기할 때 문법 에러가 발생한다.
어디가 잘못된걸까?
default export를 다시 내보내려면 위 예시처럼 export {default as User}를 사용해야 한다.
2. export * from './user.js'를 사용해 모든 걸 한 번에 다시 내보내면
default export는 무시되고, named export만 다시 내보내집니다.
두 가지를 동시에 다시 내보내고 싶다면 두 문을 동시에 사용해야 한다.
default export 를 다시 내보낼 땐 이런 특이한 상황도 인지하고 있다가 처리해줘야 하므로
몇몇 개발자들은 default export를 다시 내보내는 것을 선호하지 않는다.
요약
지금까지 배운 export 타입을 다시 한 번 살펴보자
클래스, 함수 등의 선언부 앞에 export 붙여서 내보내기
- export [default] class/function/variable ...
이름 없는 개체 내보내기
- export {x [as y], ...}
다시 내보내기
- export {x [as y], ...} from "module"
- export * from "module" (default export는 다시 내보내지지 않음)
- export {defaut [as y]} from "module"
import 타입도 정리해보자
named export 가져오기
- import {x [as y], ...} from "mod"
default export 가져오기
- import x from "mod"
- import {default as x} from "mod"
한 번에 가져오기
- import * as obj from "mod"
모듀을 가져오긴 하지만(코드는 실행됨), 변수에 할당하지 않기
- import "mod"
import/export 문은 스크립트의 맨 위나 맨 아래에 올 수 있는데 이 둘엔 차이가 없다.
하지만 대개는 편의상 스크립트 맨 위에 import 문을 위치시킨다.
import/export 문은 블록 {...} 안에선 동작하지 않는다는 점에 유의하길 바란다.
조건을 충족하면 모듈을 가져오려는 의도로 작성된 아래 코드는 동작하지 않는다.
그런데 애플리케이션을 작성하다보면 조건에 따라 모듈을 가져와야 하거나 어떤 특정 시점에 모듈을 불러와야 하는 경우가 생긴다.
그것을 동적으로 모듈을 가져온다고 한다. (dynamic import)
그것은 동적으로 모듈 가져오기에서 알아보도록 하겠다.
'언어 > JavaScript' 카테고리의 다른 글
[React] Effect Hook 사용하기 (0) | 2021.03.31 |
---|---|
[React] State Hook 사용하기 (0) | 2021.03.30 |
[React] Hook 개요 (0) | 2021.03.30 |
[React] Hook 소개 (0) | 2021.03.30 |
코어 자바스크립트 - 모듈(module) (0) | 2020.12.07 |