Search
Duplicate

[JavaScript] 모듈이란?

간단소개
모듈이 개념과 다양한 모듈의 형태, 간단한 사용법과 특징에 대해서 알아보았습니다.
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
Javascript
Node.js
Scrap
태그
javascript
9 more properties

1. 모듈의 개념, 등장 이유

모듈은 프로그램을 구성하는 구성요소의 일부를 말한다.
쉽게 말하자면 큰 애플리케이션을 작게 파일로 분리해서 관리할때 이 파일 각각을 말한다.
보통 클래스 하나 + 특정한 목적을 가지는 복수의 함수로 구성된 라이브러리 하나 정도로 구성.

JS에서 모듈의 등장

스크립트의 크기가 점차 커지고 기능이 복잡해지자 자바스크립트 커뮤니티는 라이브러리를 만들어서 필요한 모듈을 언제든지 불러올 수 있도록 하거나 모듈로 쉽게 분리 할 수 있는 방법들을 제시했다.
대표적으로 AMD, CommonJS, UMD 와 같은 모듈 시스템이 있다.
AMD : 가장 오래된 모듈 시스템 중 하나. require.js라는 라이브러리를 통해 처음 개발.
CommonJS : Node.js 서버를 위해 만들어짐
UMD : AMD와 CommonJS와 같은 모듈 시스템을 함께 사용하기 위해 등장
위의 모든 모듈 시스템은 2015의 JS 표준으로 등재가 되었고, 대부분의 브라우저와 Node.js가 모듈 시스템을 지원한다.

CommonJS

서버사이드 및 데스크탑 어플리케이션에서 JS를 지원하기 위해서 탄생함.
다른 모듈을 사용할때 require을, 모듈을 해당 스코프 밖으로 보낼 때에는 module.exports를 사용한다.
→ node.js에서 사용한다.
a.js 파일
const printHelloWorld = () => { console.log('Hello Wolrd'); }; module.exports = { printHelloWorld };
JavaScript
복사
b.js
const func = require('./a.js'); // 같은 디렉토리에 있다고 가정 func.printHelloWorld();
JavaScript
복사
여기서 module.exports는 현재 모듈에 대한 정보를 갖고 있는 객체이다.
id, path, parent 등의 속성이 있고 exports 객체를 가짐.
module.exports 대신에 exports를 사용할 수도 있음
exports.printHelloWorld = printHelloWorld;
JavaScript
복사
→ exports 의 속성으로 넣는 방법은 module.exports를 참조해서 사용하므로 직접 module.exports를 수정하지 않고 객체의 멤버를 만들어서 수정하는 방식을 사용한다.

두가지 방법의 차이점

코드를 살펴볼때 두가지 방법의 차이가 드러난다.
module.exports={} 사용하는 방법
function add(a, b) { return a + b; } function substract(a, b) { return a - b; } function multiply(a, b) { return a * b; } function divide(a, b) { return a / b; } module.exports = { add: add, substract: substract, multiply: multiply, divide: divide, };
JavaScript
복사
→ 여러개의 함수를 한번에 넣기에 용이하다.
exports 의 속성을 사용하는 방법
exports.add = function(a, b) { return a + b; }; exports.substract = function(a, b) { return a - b; }; exports.multiply = function(a, b) { return a * b; }; exports.divide = function(a, b) { return a / b; };
JavaScript
복사
→ 하나하나씩 따로 추가하는 느낌이 강하다.
주의!!! exports = divide;이렇게 넣지 않도록 주의하자
exports 가 module.exports를 참조하고 있기 때문이다.
→ 여러개의 객체를 따로 export 할때 사용한다.

AMD(Asynchoronous Module Definition)

비동기 모듈에 대한 표준안을 다룬다.
CommonJS가 서버쪽에서 장점이 많은 반면 AMD는 브라우저 쪽에서 더 장점이 많다.

UMD (Universal Module Definition)

위 두개의 모듈을 통합하기 위한 하나의 패턴

ES6 방식

import와 export 구문을 사용하는 방식이다.
EXPORT시에 named export를 사용하는 경우와 default export 를 사용하는 경우로 나뉘어진다.
named export
→ {} 로 묶어서 가져와야 한다.
export const B = () => {}; import {B} from 'moduleB';
JavaScript
복사
default export
→ 그대로 사용가능
export A = () => {}; export default A; import A from 'moduleA';
JavaScript
복사

2. 모듈의 사용과 특징

그래서 모듈을 어떻게 사용한다고?

모듈은 export 와 import 와 같은 지시자를 통해서 다를 모듈을 불러와서 불러온 모듈에 있는 함수들을 호출할 수 있는 등의 기능 공유가 가능하게 된다.
export : 외부 모듈 에서 해당 변수나 함수에 접근할 수 있게!
import : 외부 모듈의 기능을 가져와서 쓸 수 있음

모듈의 특징

모듈은 특수한 키워드나 기능과 함께 사용이 되므로 우선 <script type=”module”> 과 같은 속성을 설정해서 해당 스크립트가 모듈인것을 알 수 있도록 해줘야 한다.
모듈은 로컬 파일에서 동작하지 않고, http 또는 https 프로토콜을 통해서만 동작한다.

스크립트와 다른점

스크립트와 다르게 ‘use strict’ 엄격한 모드로 실행이 된다.
모듈 내부에서 정의한 변수나 함수는 다른 스크립트에서 접근할 수 없다.
export 와 import를 꼭 사용해야 한다.
동일한 모듈이 여러곳에서 사용되더라도 모듈은 최초 호출시 단 한번만 실행된다.
→ 앞서 특정 모듈에서 불러온 모듈을 수정하게 되면 다른 모듈에서 특정 모듈의 수정된 결과가 적용된다.
// 📁 1.js import {admin} from './admin.js'; admin.name = "Pete"; //John -> Pete // 📁 2.js import {admin} from './admin.js'; alert(admin.name); // Pete
JavaScript
복사

이를 이용하면 모듈 설정을 쉽게 할 수 있음

다음과 같은 모듈이 있다고 해보자.
// 📁 admin.js export let admin = { }; export function sayHi() { alert(`${admin.name}님, 안녕하세요!`); }
JavaScript
복사
최초 사용 위치에서 다음과 같이 설정한 경우
// 📁 init.js import {admin} from './admin.js'; admin.name = "유림";
JavaScript
복사
다른곳에서 호출시 사용이 가능하다.
// 📁 other.js import {admin, sayHi} from './admin.js'; alert(admin.name); // 유림 sayHi(); // 유림님, 안녕하세요!
JavaScript
복사
import.meta 객체를 통해 현재 모듈에 대한 정보를 가져올 수 있다.
ex) import.meta.url : 현재 모듈이 위치한 html 페이지의 url
this 는 undefined 이다.
<script> alert(this); // window </script> <script type="module"> alert(this); // undefined </script>
JavaScript
복사

브라우저 환경에서 모듈이 스크립트와 다른점

항상 지연 실행된다.
→ html 처리와 외부 모듈 스크립트는 병렬적으로 불러와진다.
모듈은 html 문서가 준비될 때까지 대기 상태였다가 HTML 문서가 만들어진 이후에 실행된다.
→ 따라서 항상 모듈 스크립트는 완전한 html 페이지를 보고 요소에 접근할 수 있다.
인라인 스크립트에서도 ‘async’ 속성을 사용할 수 있다
async : 로딩이 끝나면 다른 스크립트나 html 문서가 처리되길 기다리지 않고 실행되도록 함.
 그냥 스크립트는 인라인 스크립트로 작성시 async 로 진행할 수 없다.
다른 오리진에서 모듈 스크립트를 불러오려면 CORS 헤더가 필요하다. 자세히 CORS란?
경로가 없는 모듈은 금지된다(브라우저가 읽을 수 없다)
import {sayHi} from 'sayHi'; // Error! import {sayHi} from './sayHi.js'; // Correct!
JavaScript
복사

3. 참고 및 출처