PracticeEveryday

JavaScript 본문

JavaScript

JavaScript

kimddakki 2022. 6. 7. 11:56
import User from "./user.js";

console.log(new User("kim"));
// User { name: 'kim' }​
모듈 ( Module 모듈, 교과목 단위 )

 - 개발하는 어플리케이션의 크기가 커지면 언젠가 파일을 여러 개로 분리해야 하는 시점이 오게 됩니다

   이 때 분리된 각각의 파일을 ' 모듈 ( Module ) ' 이라고 부르는 데 모듈은 대개 클래스 하나 혹은 특정한 목적을 가진 

   복수의 함수로 구성된 라이브러리 하나로 구성됩니다.

 

 - 자바스크립트가 만들어 진지 얼마 안 되었을 때는 표준 문법이 필요하지 않았지만 규모와 기능이 점점 커지고 

   복잡해짐에 따라 자바스크립트 커뮤니티는 특별한 라이브러리를 만들어 필요한 모듀을 언제든지 불러올 수 있게 

   해준다거나 코드를 모듈 단위로 구성해 주는 방법을 만드는 등 많은 시도를 하게 됩니다.

 

AMD – 가장 오래된 모듈 시스템 중 하나로 require.js라는 라이브러리를 통해 처음 개발되었습니다.
CommonJS – Node.js 서버를 위해 만들어진 모듈 시스템입니다.
UMD – AMD와 CommonJS와 같은 다양한 모듈 시스템을 함께 사용하기 위해 만들어졌습니다.

 - 이런 모듈 시스템은 오래된 스크립트에서 볼 수 있는데 거의 사용하지 않는다.

   모듈 시스템은 2015년에 표준으로 등재되었고 이 이후로 관련 문법은 진화를 거듭해 대부분 주요 브라우저와

   Node.js가 모듈 시스템을 지원하고 있다.

 

모듈이란

 - 모듈은 단지 파일 하나에 불과합니다. 스크립트 하나는 모듈 하나 입니다.

   모듈에 특수한 지시자 export 와 import 를 적용하면 다른 모듈을 불러와 불러온 모듈에 있는 함수를 호출하는 것과

   같은 기능 공유가 가능합니다.

 

1. export 지시자를 변수나 함수 앞에 붙이면 외부 모듈에서 해당 변수나 함수에 접근 할 수 있습니다. ( 모듈 내보내기 )

2. import 지시자를 사용하면 외부 모듈의 기능을 가져올 수 있습니다 ( 모듈 가져오기 )

 

모듈 내보내고 가져오기

 - import 와 export 지시자는 다양한 방식으로 활용됩니다.

 

1. 선언부 앞에 export 붙이기 

 - 변수나 함수 클래스를 선언할 때 앞에 export를 붙이면 내보내기가 가능합니다.

   아래의 내보내기는 모두 유효합니다.

// 배열 내보내기
export let months = ["Jan", "Feb", "Mar", "Apr", "May"];

// 상수 내보내기
export const basic = "Hello World";

// 클래스 내보내기
export class User {
  constructor(name) {
    this.name = name;
  }
}

※ 클래스나 함수를 내보낼 땐 세미콜론을 붙이지 마세요

 - 클래스나 함수 선언 시, 선언부 앞에 export 를 붙인다고 해서 함수 선언 방식이 함수 선언문에서 함수 표현식으로

   바뀌지 않습니다. 내보내 지긴 했지만 여전히 함수 선언문입니다.

 - 대부분의 자바스크립트 스타일 가이드는 함수나 클래스 선언 끝에 세미콜론을 붙이지 말라고 권유합니다.

   같은 이유로 export class 나 export function 끝에 세미콜론을 붙이지 않습니다.

// 함수 내보내기
export function sayHi(user) {
  console.log(`Hello, ${user}!`);
}

 

2. 선언부와 떨어진 곳에 export 붙이기

 - 선언부와 export 가 떨어져 있어도 내보내기가 가능합니다.

function sayHello(user) {
  console.log(`Hello, ${user}!`);
}

function sayBye(user) {
  console.log(`Bye, ${user}!`);
}

export { sayHello, sayHello, sayBye };

 - 함수를 먼저 선언하고, 마지막 줄에서 내보냈습니다.

   export 문을 함수 선언부 위에 적어주는 것도 동일하게 작동합니다!!

 

3. import *

 - 무언갈 가져오고 싶다면 아래와 같이 이에 대한 목록을 만들어 import { ... } 안에 적어주면 됩니다.

 

import { sayHello, sayBye } from "./export.js";

sayHello("kim"); // Hello Kim
sayBye("kim"); // Bye Kim

 - 가져올 것이 많으면 import * as <obj> 처럼 객체 형태로 원하는 것을 가지고 올 수 있습니다.

 

import * as say from "./export.js";

say.sayHello("kim"); // Hello Kim
say.sayBye("kim"); // Bye Kim

 - 이렇게 한꺼번에 모든 걸 가져오는 방식을 사용하면 코드가 짧아지지만 어떤 걸 가져올 땐 그 대상을 구체적으로

   명시하는 것이 좋습니다.

 

3 - 1. 웹팩 ( Webpack )과 같은 모던 빌드 툴은 로딩 속도를 높이기 위해 모듈들을 한 데 모으는 번들링과 최적화를 

   수행합니다.

   아래와 같이 프로젝트에 서드 파티 라이브러리인 say.js를 도입했다 가정하면 이 라이브러리 내엔 수많은 함수가 

   존재하게 됩니다.

// say.js
export function sayHi() { ... }
export function sayBye() { ... }
export function becomeSilent() { ... }

 - say.js 의 수 많은 함수 중 단 하나만 필요한 경우 빌드 툴은 사용되는 함수가 무엇인지 파악해 필요하지 않는 함수는

   최초 번들링 결과물에 포함하지 않아 코드가 제거 되기에 빌드 결과물의 크기가 작아지게 됩니다.

   이 과정을 가지치기 ( tree - shaking ) 이라고 불립니다.

3 - 2. 어떤 걸 가지고 올지 명시하면 이름을 간결하게 사용할 수 있습니다. say.sayHi() 보다 sayHi()가 더 간결하다.

3 - 3. 어디서 어떤 걸 쓰이는 지 명확하기 때문에 코드 구조를 파악하기가 쉬워 리팩토링이나 유지 보수에 도움이 됩니다.

 

4. import ' as '

 - as를 사용하면 이름을 바꿔서 모듀을 가져올 수 있습니다.

   sayHi()를 hi로 say Bye를 bye로 이름을 바꿔 가져올 수 있습니다.

import { sayHello as hi, sayBye as bye } from "./export.js";

hi("kim"); // Hello, kim!
bye("kim"); // Bye, kim!

 

5. export ' as '

 - export 에도 as를 사용할 수 있습니다.

   sayHi와 sayBye를 hi, bye로 바꿔 내보낼 수 있습니다.

function sayHello(user) {
  console.log(`Hello, ${user}!`);
}

function sayBye(user) {
  console.log(`Bye, ${user}!`);
}

export { sayHello as hi, sayBye as bye };

 

 - 이제 이 모듈을 가져올 때 이름은 hi, bye가 됩니다.

import { hi, bye } from "./export.js";

// hi("kim"); // Hello, kim!
// bye("kim"); // Bye, kim!

 

6. export default

 - 모듈은 크게 두 종류로 나뉩니다.

1. 복수의 함수가 있는 라이브러리 형태의 모듈 ( say.js )

2. 개체 하나만 선언되어 있는 모듈 ( 아래의 user.js => class User 하나만 내보내기 함 )

 

 - 대개는 두 번째 방식으로 모듈을 만드는 걸 선호하기 때문에 함수, 클래스 ,변수 등의 개체는 전용 모듈 안에서 

   구현 됩니다.

 - 하지만 이렇게 모듈을 만들어 작성하다 보면 자연스럽게 파일의 개수가 많아지게 되는 데 모듈의 이름을 잘 지어주고

   폴더에 파일을 잘 나눠 프로젝트를 구성하면 탐색이 어렵지 않게 가능하므로 전혀 문제가 되지 않습니다.

 

 - 모듈은 export default라는 특별한 문법을 지원합니다. export default를 사용하면 '해당 모듈엔 개체가 하나만 있다'

   는 사실을 명확히 나타낼 수 있습니다.

 

   내보내고자 하는 개체 앞에 export default를 붙여 봅시다.

export default class User {
  constructor(name) {
    this.name = name;
  }
}

 - 파일 하나엔 대개 export default 하나만 있습니다.

   이렇게 default를 붙여서 모듈을 내보내면 중괄호 { }를 사용하지 않고 가져올 수 있습니다.

 - named export와 default export를 같은 모듈에서 동시에 사용해도 문제가 되지 않지만 실무에선 이렇게 섞어 쓰지 않고

   둘 중 하나만 사용하게 됩니다.

 

 - 파일당 최대 하나의 default export가 있을 수 있으므로 내보낼 개체엔 이름이 없어도 괜찮습니다.

   아래 예시의 개체인 이름이 없지만 모두 에러 없이 작동합니다.

export default class { // 클래스 이름이 없음
  constructor() { ... }
}

export default function(user) { // 함수 이름이 없음
  console.log(`Hello, ${user}!`);
}

// 이름 없이 배열 형태의 값을 내보냄
export default ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

 - export default는 파일 하나당 하나만 있으므로 모듈에선 중괄호 없이도 어떤 개체를 가지고 있을 지 정확히 알 수 있다.

 - default를 붙이지 않았다면 개체에 이름이 없는 경우 에러가 발생하게 됩니다.

export class { // 에러! (default export가 아닌 경우엔 이름이 꼭 필요합니다.)
  constructor() {}
}

 

 

모듈 내보내고 가져오기

 

ko.javascript.info

 

'JavaScript' 카테고리의 다른 글

JavaScript  (0) 2022.06.03
JavaScript  (0) 2022.06.02
JavaScript  (0) 2022.05.25
JavaScript  (0) 2022.05.19
JavaScript  (0) 2022.05.18
Comments