JavaScript Module

JavaScript 모듈 시스템은 코드의 모듈화를 통해 재사용성, 유지보수성, 가독성을 향상시키는 데 도움을 줍니다. ES6(ECMAScript 2015)부터 도입된 importexport를 사용한 모듈 시스템은 표준화된 방법으로 JavaScript 모듈을 정의하고 사용하는 기능을 제공합니다. 이 문서에서는 JavaScript의 모듈 시스템을 매우 상세히 설명합니다.

1. 모듈 기본 개념

JavaScript 모듈은 코드의 재사용성과 캡슐화를 위한 독립적인 단위입니다. 각 모듈은 별도의 파일에 정의되며, 다른 모듈에서 importexport를 통해 서로 상호작용할 수 있습니다.

2. export – 모듈 내보내기

모듈 내보내기(export)는 모듈이 다른 모듈에서 사용할 수 있는 변수, 함수, 클래스 등을 공개하는 방법입니다.

2.1 내보내기 방식

명명된 내보내기(Named Exports)

명명된 내보내기를 사용하면 모듈에서 여러 개의 변수를, 함수, 클래스를 내보낼 수 있습니다.

// lib.js

export const pi = 3.14;

export function add(x, y) {
  return x + y;
}

export class Person {
  constructor(name) {
    this.name = name;
  }
  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

기본 내보내기(Default Export)

기본 내보내기는 모듈에서 하나의 기본값만 내보낼 수 있습니다. 일반적으로 객체, 함수, 클래스 등을 내보낼 때 사용합니다.

// lib.js

const defaultValue = "Default Export";

export default defaultValue;

혼합 내보내기

명명된 내보내기와 기본 내보내기를 함께 사용할 수 있습니다.

// lib.js

export const pi = 3.14;

export function add(x, y) {
  return x + y;
}

const defaultValue = "Default Export";
export default defaultValue;

3. import – 모듈 가져오기

import는 다른 모듈에서 내보낸 기능을 가져오는 방법입니다.

3.1 명명된 가져오기

모듈에서 명명된 내보내기를 가져오는 방법입니다.

// main.js

import { pi, add, Person } from './lib.js';

console.log(pi); // 3.14
console.log(add(2, 3)); // 5

const person = new Person('Alice');
person.greet(); // Hello, my name is Alice

3.2 기본 가져오기

모듈에서 기본 내보내기를 가져오는 방법입니다.

// main.js

import defaultValue from './lib.js';

console.log(defaultValue); // Default Export

3.3 명명된 가져오기와 기본 가져오기 함께 사용

명명된 내보내기와 기본 내보내기를 함께 가져올 수 있습니다.

// lib.js

const defaultValue = "Default Export";

export default defaultValue;
export const pi = 3.14;
export function add(x, y) {
  return x + y;
}
// main.js

import defaultValue, { pi, add } from './lib.js';

console.log(defaultValue); // Default Export
console.log(pi); // 3.14
console.log(add(2, 3)); // 5

3.4 전체 모듈 가져오기

모듈 전체를 하나의 객체로 가져올 수 있습니다.

// main.js

import * as lib from './lib.js';

console.log(lib.pi); // 3.14
console.log(lib.add(2, 3)); // 5
console.log(lib.default); // Default Export

4. 모듈 로딩 시점

모듈은 기본적으로 동기적으로 로드됩니다. 즉, 모듈이 로드되기 전까지 코드 실행이 멈추며, 로드된 후에야 코드가 실행됩니다.

5. 모듈화된 코드의 장점

  1. 코드의 캡슐화: 모듈은 외부와 내부를 명확히 구분하여 코드의 가독성을 높입니다.
  2. 재사용성: 모듈화된 코드는 다른 프로젝트나 파일에서도 재사용할 수 있습니다.
  3. 의존성 관리: 모듈은 명확하게 의존성을 정의하므로, 코드 관리가 용이합니다.
  4. 테스트 용이성: 모듈 단위로 코드를 테스트하기 쉬워집니다.

6. 모듈의 동작 방식

모듈은 JavaScript의 실행 환경에 따라 다르게 동작할 수 있습니다. 브라우저와 Node.js의 모듈 처리 방식은 다음과 같습니다.

6.1 브라우저에서의 모듈

브라우저에서는 type="module"을 사용하여 <script> 태그를 통해 모듈을 로드합니다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Module Example</title>
</head>
<body>
  <script type="module">
    import { pi, add } from './lib.js';
    console.log(pi); // 3.14
    console.log(add(2, 3)); // 5
  </script>
</body>
</html>

6.2 Node.js에서의 모듈

Node.js는 CommonJS 모듈 시스템을 사용하지만, 최근에는 ES 모듈을 지원합니다. ES 모듈을 사용하려면 파일 확장자를 .mjs로 설정하거나 package.json에서 "type": "module"을 설정합니다.

// lib.mjs
export const pi = 3.14;
export function add(x, y) {
  return x + y;
}
// main.mjs
import { pi, add } from './lib.mjs';

console.log(pi); // 3.14
console.log(add(2, 3)); // 5
// package.json
{
  "type": "module"
}

7. 모듈의 동적 import

ES6 모듈에서는 import() 함수를 사용하여 모듈을 동적으로 로드할 수 있습니다. 이는 코드 분할 및 지연 로딩을 가능하게 합니다.

// main.js

async function loadModule() {
  const module = await import('./lib.js');
  console.log(module.pi); // 3.14
  console.log(module.add(2, 3)); // 5
}

loadModule();

8. 사이드 이펙트와 모듈

모듈을 임포트할 때, 사이드 이펙트(즉, 모듈이 실행되는 시점에 발생하는 코드 실행)를 방지하거나 관리하기 위해 의도적으로 import할 수 있습니다.

// lib.js

console.log('This will execute when the module is imported');

export const pi = 3.14;
// main.js

import './lib.js'; // 사이드 이펙트 발생

결론

JavaScript의 모듈 시스템은 코드의 구조화와 관리에 많은 이점을 제공합니다. importexport를 통해 모듈을 정의하고, 재사용 가능한 코드로 분리할 수 있습니다. ES6부터 도입된 표준 모듈 시스템은 다양한 상황에서 코드의 가독성과 유지보수성을 높이는 데 큰 도움을 줍니다. 모듈을 효과적으로 사용하면 더 깔끔하고 관리하기 쉬운 코드를 작성할 수 있습니다.

Leave a Reply

Your email address will not be published. Required fields are marked *