예시)
import {user} from './user.js';
user.name = 'sangyeon';
import {user} from './user.js';
console.log(user.name) // sangyeon
그래서 매번 새로운(신선한) 값을 얻기 위해서는 함수를 export 해 줘야 하는 것이다. 귀찮다면 귀찮은 특성이지만, 좋게 생각하면 내가 한번 실행 뭔가를 기억해준다는 것이기도 하다. 예를들어 어플리케이션의 시작과 함께 configuration을 설정하면 이후 어디에서나 이 설정이 적용된다.
일반 스크립트에서 가장 바깥의 this는 window 또는 globalThis를 뜻한다. 하지만 모듈에서는 undefined를 뱉을 뿐이다.
예시를 먼저 보자.
<script type="module">
console.log(typeof button); // object
</script>
<script>
console.log(typeof button); // button is undefined
</script>
<button id="button">Button</button>
모듈의 사이즈가 작아서 설령 먼저 다운로드 완료 되더라도, html과 regular script가 완전히 로딩 된 이후에야 module이 evaluated 된다. 바꿔 말하면 module 안에서는 언제나 완전히 로딩 된 html 및 regular script를 기대 할 수 있는 것이다.
다만 유저의 상화작용 없이 module에서 즉시 어떤 값을 보여주거나 수정 해야한다면, 로딩중이라는 표시 정도는 모듈 바깥에서 해 주는것이 좋겠다.
다른 모듈에서 import 받은 것을 곧바로 export 해 주는 것이다.
예시)
export {sayHi} from './say.js'; // re-export sayHi
export {default as User} from './user.js'; // re-export default
이런게 왜 필요할까? 모듈간에도 계층구조가 존재 할 수 있기 때문이다. nested모듈을 말하는 것이다. 예를들어 bundled 모듈의 경우 여러가지 자식(?) 모듈을 가지고 있을 것이다. 그 모든 것들을 최상위 모듈에서 한번에 export 해 주면, 이 모듈을 갖다 쓰기에 좋을 것이다.
import 키워드는 {} 코드블럭 안에서는 작동하지 않고, 에러를 이르킨다. 반드시 top-level에서 사용해야 하는 것이다.
예시)
if(...) {
import ...; // Error, not allowed!
}
{
import ...; // Error, we can't put import in any block
}
그렇다면 조건에 상응하거나 정확한 타이밍에 모듈을 import하고싶다면 어떻게 해야할까?
아래와 같은 문법을 사용 할 수 있다.
import(module path)예시) const modulePath = prompt("어떤 모듈을 사용하시겠습니까?"); import(modulePath) .then(obj => { // do something with obj... // obj has all exported elements }) .catch(err => { // err occured in case of no module, no finding such exported props.. })
import(module path)가 promise객체를 리턴하기 때문에 then, catch, await 따위의 키워드를 활용할 수 있다. 그러나 import가 함수는 아니다. 그저 소괄호를 사용하는 특별한 문법일 뿐이다. class 상속에 super() 같은 문법이 있듯이 말이다.