JS Module에 대해서(import 순서 관련)

김 주현·2024년 1월 25일
1
post-custom-banner

코드 리뷰하다가 문득 궁금해져서 테스트 해본 코드. 다음 코드를 실행했을 때 콘솔 로그의 순서는 어떻게 될까? moduleC 코드 다음에 바로 정답이 있으니 궁금한 사람은 스크롤을 멈춰보세요!

App.js

console.log('App 1');
import { moduleA } from './moduleA.js';
console.log('App 2');
import { moduleB } from './moduleB.js';

moduleA.js

console.log('ModuleA 1');
export const moduleA = '하이';
console.log('ModuleA 2');
import { moduleC } from './moduleC.js';

moduleB.js

console.log('ModuleB 1');
export const moduleB = '음음';
console.log('ModuleB 2');

moduleC.js

console.log('ModuleC 1');
export const moduleC = '그래';
console.log('ModuleC 2');

정답은 아래와 같다. 왜요?

$ node app.js
ModuleC 1
ModuleC 2
ModuleA 1
ModuleA 2
ModuleB 1
ModuleB 2
App 1    
App 2

참고로 나는 틀렸다. 내가 헷갈린 부분은 다음과 같다.

헷갈린 부분

(1) import 전의 코드가 먼저 실행되는가?
(2) export 후의 코드도 같이 실행되는가?

이에 대해 관련된 Javascript의 특성은 Import HoistingModule Evaluation이다. 요 특성에 대해서 요약을 하자면 다음과 같이 할 수 있겠다.

  1. import문은 호이스팅이 된다.
  2. Module은 평가되기 전에 모든 종속 모듈이 먼저 평가되어야 한다.

import문이 호이스팅이 되냐 안 되냐에 대한 이야기가 생각보다 많이 없어서 관련 자료를 많이 찾아봤는데, 어쨌든, import문은 호이스팅이 되는 게 맞다!

이때 내가 헷갈린 것은, import는 최상위에 선언되어야 한다. 라는 부분이었는데, '최상위' 라는 단어가 '코드 상 순서로 맨 위'가 아니라, '스코프의 최상위'임을 알고 나선 명료해졌다. 즉, 당연히 block 스코프, 예를 들어 if문 안에서는 선언할 수 없다. (import()는 가능하지만서도, 이건 다른 개념이니까!

그러므로,, 결국 1번과 2번은 서로 연관이 되어 있다. 모든 종속 모듈이 먼저 평가가 되려면 import문이 호이스팅이 되어 종속 모듈을 먼저 불러올 수 있게끔 해야 하므로.

재밌다...


profile
FE개발자 가보자고🥳
post-custom-banner

0개의 댓글