티스토리 뷰

Frontend/JavaScript

[JavaScript | ES6] ES6 Modules

blueprint-12 2022. 11. 6. 23:59

ES6에서는 클라이언트 사이드 자바스크립트(브라우저)에서도 동작하는 모듈 기능을 추가했습니다. 

2019년 11월 기준으로 모던 브라우저 (크롬 61, 파이어폭스 60, 사파리 10.1 엣지 16이상)에서 ES6모듈을 사용할 수 있습니다.

ES6 모듈 기능을 사용하지 않으면 분리된 자바스크립트 파일에 독자적인 스코프를 갖지 않고 하나의 전역을 공유하게 된다. 이렇게되면 원치않는 오류나 오버라이딩, 충돌 등이 날 것입니다.  ES6 모듈은 파일 자체의 스코프를 제공합니다. 즉, 모듈은 독자적인 모듈 스코프를 가지게 되는 것입니다. 

 

ES6 모듈 상세

export import 문은 파일 단위의 영역을 기준으로 Top-level 영역에서만 사용할 수 있습니다.

-> 파일 단위 최상단을 말하는 것이 아니라 depth 가 들어가면 안된다는 소리입니다. 예를 들어, if문 안에 실행문으로 넣어준다거나..  

 

export 

export {name1, name2 ..., nameN}
export const foo = Math.sqrt(2);

export default [값 or 식]
export default (x , y) => x + y; //이런 식만 내보내도 ok 애는 익명함수임

export default class {}

export * from "modlue1.js";

const milk ="i am milk";
export {milk as drink};
  • export default 키워드로는 하나만 내보낼 수 있다.
  • export 하는 것은 수 제한 X 
  • 값이나 식을 내보내는 것도 가능하다. 
  • 별칭을 as 키워드를 통해 내보낼 수 있지만 default로 내보내진 아이는 설정 불가 
  • *(아스테리스크, 별 표시)로 export된 모든 아이들을 내보낼 수 있다. 

import

import {dafault as m1, member2 as m2} from "module-name";

import member1, {memeber2 as m2, member3} from "moudle-name"

import "module-name" //파일 내부에서 쓰진 않지만 불러와야 하는 경우가 바로 이렇게 쓴다.

//export default인 함수 hotdog 가 있다고 치면 별칭을 붙일 때
import hotdog as colddog ~ from " ~"; //는 안된다.(X)
import colddog from "~ "; // 이렇게 내가 원하는 이름을 바로 써주면 hotdog로 인식된다. (O)
  • default로 export된 값이나 식은 이름을 별칭을 as로 붙여줄 수 없지만 대신 as 키워드 없이 원하는 이름(as 키워드 없이 그냥 내멋대로 작명해서 그걸로 사용가능)으로 쓸 수 있다.
  • default 로 내보내진 아이는 그냥 이름 갖다쓰면 되지만 default 가 아닌 export키워드로만 내보내진 변수들은 중괄호로 불러와야 한다. 
  • 해당 파일을 불러오긴 해야하는데 이 파일내부에서 쓸 일이 없다면 굳이 변수명을 써주지 않아도된다. (Non- binding Object 예를 들어 CSS 모듈 같은 경우, Babel에서 폴리필 불러올 때 ) 
  • * 로 모듈 전부를 불러와서 사용할 때는 항상 as 키워드와 함께 별칭을 붙여 가져와야 한다.

실제 예시

우선 win + r  -> cmd 를 통해 커멘드라인에서 mkdir 폴더명 으로 모듈테스트를 할 폴더를 만들어줍니다.(윈도우 기준입니다.)

npm -g lite-server 명령어로 라이트 서버를 설치해주고 lite-server 스크립트 명령어를 실행시키면 서버가 작동합니다.

 

해당 폴더를 vscode로 열어주고 내부에 index.html 과 테스트를 위한 js파일 3개 가지를 만들어줍니다.(main, sub1, sub2)

 

index.js  (모듈 시스템을 확인해보는 것이기 때문에 굳이 html형식을 전부 작성해줄 필요가 없습니다.)

<script src="main.js" type="module"></script>

main.js

import sub1, { a } from "./sub1.js";
import sub2 from "./sub2.js";
console.log(sub1(2));
console.log(sub2(3, 5));
console.log(a);

sub1.js

const sub1 = (x) => x * x;

export default sub1;
export const a = 10;

sub2.js

export default (x, y) => x + y;

 

 

sub2에 코드를 export할 아이들을 추가로 넣어주고 모든 요소를 별칭을 붙여 main.js에서 불러와봅시다. 

🤸‍♀️참고로 lite-server 를 사용할 때 파일에 업데이트된 사항이 있다면 새로고침을 해주셔야 반영됩니다.

main.js

import sub1, { a } from "./sub1.js";
import * as sub2 from "./sub2.js";
console.log(sub1(2));
console.dir(sub2);
console.log(a);

dir을 통해 sub2를 확인한 결과&nbsp; Module이라고 찍힙니다.

추가로 작성한 함수들과 변수가 제대로 나오는 것을 확인해 볼 수 있습니다. 

 

 

 

이슈발생: 콘솔에 main.js의 결과 값이 찍히지않고 아래와 같은 에러 메세지가 발생했습니다. 

GET http://localhost:3000/sub2 net::ERR_ABORTED 404 (Not Found)

"주어진 식별자를 가진 데이터를 찾을 수가 없구나"

평소에 create-react-app으로 파일을 임포트 해올 때 자바스크립트 파일 뒤에 .js라는 확장자를 붙이지 않아도 정상적으로 구동했었고 직접 써놓지 않더라도 IDE에서 자동으로 수정해주기 때문에 사용할 모듈을 가져올 때에 .js라는 확장자를 붙이지 않았습니다. 하지만 해당 프로젝트는 아무런 세팅이되어있지 않은 상태이기 때문에 .js라는 확장자를 붙이지 않고 main.js에서 sub2와 sub1을 import해와 사용하려하니 제대로 읽어오지 못한 거 같습니다. 

빠르게 네트워크 탭을 확인하여 원인을 찾을 수 있었습니다만 너무 안일하게 사용했던 것은 아닌가 생각이 듭니다. 😓

 

 

댓글