모듈화

김동현·2021년 4월 13일

Morden JavaScript

목록 보기
3/5

브라우저와 node.js에서의 모듈 사용의 차이

브라우저와 다르게 node.js의 특징 중 하나는 다양한 내장 모듈이 존재한다는 것이다.

기본적인 사용법

npm install을 이용하면 우리는 필요한 모듈을 npm 저장소에서 다운 받아 사용할 수 있다.
이러한 모듈이 node_modules에 저장되어 있다면, 다음과 같이 불러오면 된다.

const 모듈이_담긴_변수 = require('모듈이름')
// 예를 들어, 파일 시스템과 관련된 모듈을 사용하려면
const fs = require('fs') // 변수 fs에는 파일 시스템 모듈이 담겨있다.

다른 스크립트를 불러올 때

다른 스크립트를 불러오기 위해 require 구문을 사용할 수 있다.
결국 모듈이라는 것도 다른 스크립트
여기서 서로 다른 스크립트를 우리가 직접 만들었다고 가정한다.
예를 들어, 동일한 디렉토리에 다른 두 개의 파일이 있는 경우

// script1.js
const module2 = require('./script2.js') // ./는 현재 디렉토리

// script2.js
console.log('this is module2');

코드를 살펴보면, script1.js 에서 require 구문을 이용해 불러올 때에, script2.js의 내용이 실행되리라고 추측 할 수 있다.
그런데, 변수 module2 에는 어떤 값이 들어가게 되는 걸까?
script2.js에서 무언가 반환해야 하지 않을까?

==>

모듈로 노출시킬때

이때는, module.exports라는 것을 이용
다른 스크립트 파일에서 내가 만든 모듈을 사용할 수 있도록 노출시키는 방법

// script1.js
const module2 = require('./script2.js')
console.log(module2) // 'this is module2'

// script2.js
module.exports = 'this is module2'

module.exports 대신 exports를 사용할 수 있다.
exports는 일종의 축약형(shortcut)이다.
exports는 module.exports를 참조한다.
이러한 모듈 노출 방법과 불러오는 방법을 CommonJS 모듈 시스템이라고 부른다.

CommonJS

모든 모듈은 자신만의 독립적인 실행 영역이 있어야 한다.
모듈 정의는 전역 객체인 exports 객체를 이용한다.
모듈 사용은 require 함수를 이용한다.

exports vs module.exports

exports는 module.exports 사용을 도와주는 helper
exports는 module.exports를 참조할 뿐
module.exports에 뭔가가 이미 붙어있다면, exports는 무시된다
=> 섞어쓰지 말아야 한다.

모듈화

모듈화는 아래와 같이 세 부분으로 이루어진다.

  • 스코프(Scope): 모든 모듈은 자신만의 독립적인 실행 영역이 있어야한다.
  • 정의(Definition): 모듈 정의는 exports 객체를 이용한다.
  • 사용(Usage): 모듈 사용은 require 함수를 이용한다.

먼저 모듈은 자신만의 독립적인 실행 영역이 있어야 한다.
따라사 전역 변수와 지역 변수를 분리하는 것이 매우 중요하다.
서버사이드 JavaScript의 경우에는 파일마다 독립적인 파일 스코프가 있기 때문에 파일 하나에 모듈 하나를 작성하면 간단히 해결된다.
즉, 서버사이드 JavaScript는 아래와 같이 작성하더라도 전역 변수가 겹치지 않는다.

// fileA.js
let a = 3;
let b = 4;

// fileB.js
let a = 5;
let b = 6;

그리고, 두 모듈(파일)사이에 정보 교환이 필요하다면, exports라는 전역 객체를 통해 공유하게 된다.
아래 예제에서는 fileA.js 파일의 sum 함수가 외부로 공개된다.

// fileA.js
let a = 3;
let b = 4;
exports.sum = function(c, d) {
  return a + b + c + d;
}

// fileB.js
let a = 5;
let b = 6;

이렇게 공개된 함수를 다른 모듈에서 사용하려면, 다음과 같이 require 함수를 이용한다.

// fileA
let a = 3;
let b = 4;
exports.sum = function(c, d) {
  return a + b + c + d;
}

// fileB
let a = 5;
let b = 6;
let moduleA = require('fileA');
module.sum(a, b); // 3 + 4 + 5 + 6 = 18

위에 예에서 CommonJS의 모듈 명세는 모든 파일이 로컬 디스크에 있어 필요할 때 바로 불러올 수 있는 상황을 전제로 한다.
다시 말해 서버사이드 JavaScipt 환경을 전제로 한다.

하지만 이런 방식은 브라우저에서 결정적인 단점이 있다.
필요한 모듈을 모두 내여받을 때까지 아무것도 할 수 없게 되는 것이다.
이 단점을 극복하려는 여러방법이 CommonJS에서 논의 되었지만, 결국 동적으로

profile
개발자로서의 첫걸음

0개의 댓글