모듈과 모듈화의 이해 및 구현

meek·2024년 2월 25일
3

JavaScript

목록 보기
1/2

모듈화(Modularization)

💡 소프트웨어 설계에서 기능단위로 분해하고 추상화되어 재사용 및 공유가능한 수준으로 만들어진 단위모듈이라고 하고, 소프트웨어의 성능을 향상시키거나 시스템의 디버깅, 시험, 통합 및 수정을 용이하도록 하는 소프트웨어 설계 기법모듈화라고 한다.
통상적으로 구조가, 여러 기능들을 하나로 모으고, 이들이 공유하는 데이터들로써 구성되어 있다.
패키지, 모듈 등은 파일 단위로 정의되어 import 방식이 대부분이다.

모듈은 계층적인 소프트웨어 구조를 설계할 때, 한 계층의 부분을 차지하는 단위가 된다. 즉, 계층화를 통해 제공해야할 인터페이스와 자신이 의존하고 있는 인터페이스를 명확히 분리해 내야한다. 모듈은 상위 계층에 제공하는 인터페이스, 실제 자신이 담당하고 있는 역할을 처리하는 부분, 제공되는 인터페이스를 사용하기 위한 의존성을 가지는 부분 등 3개의 작은 계층으로 나누어질 수 있으며, 이렇게 만들어진 모듈은 이식성(Portability)과 호환성(Compatibility)이 높다. 분리된 계층을 가지지 못한 모듈들은 내부 구조의 변경이 상위 모듈에 영향을 줄 수 있으며, 이러한 형식의 구현은 구체적인 부분을 외부로 노출하게 된다.

모듈도 함수와 마찬가지로 하나의 역할만 해야한다. 즉, 하나의 책임을 가지고 있다. 그 책임의 폭이 달라질지는 몰라도, 정확히 정의되는 하나의 역할을 맡고 있어야 하며, 그것 외에 다른 일을 해서는 안된다. 역할이 많아지면 해야하는 일이 많아지며, 다양한 역할은 제대로 하나의 역할도 수행하지 못하도록 만든다.

모듈의 내부 자료구조가 외부로 드러나는 것은 모듈에 대한 통제 권한을 다른 모듈에 넘기는 것과 같은 일이다. 그 말은 즉슨, 모듈의 책임이 약화되는 결과를 낳게 되며, 내부의 변경에 대해서 외부의 코드 변경을 유발할 가능성이 높다. 따라서, 모듈전역적인 자료구조에 대한 사용을 가능한 줄여야 하며, 그러한 자료구조에 대한 접근 방법도 모듈에서 제공하는 인터페이스만을 사용해야 한다. 모듈이 외부에 공개하는 인터페이스들은 구조를 표현하는 것이 아니라, 요청을 받아들이는 창구 역할을 해야한다. 즉, 창구에서 받은 요청을 내부의 자료구조와 함수들을 이용해서 처리한 후, 결과를 알려주는 것이어야 한다. 만약, 구체적인 자료구조의 필드에 대한 접근을 허가한다면, 그것을 이용해서 처리해야할 일이 모듈 이외의 부분으로 전파될 가능성이 높다. 이러한 부분들은 모듈의 역할을 외부를 빼내는 결과가 될 것이다.

모듈 만들기

모듈 만들기 export

간단한 덧셈 뺄셈 모듈을 만들어보았다.
다음은 html문서인데, 여태까지 자바스크립트를 삽입하기 위해서는 <script>태그의 type속성에 text/javascript를 지정해주었던 것과 다르게, module이라고 명시를 해준다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>ModuleTest</title>
  </head>
  <body>
    <script type="module" src='../js/index.js'></script>
  </body>
</html>

html문서의 준비가 끝나면 자바스크립트 모듈을 만들어볼 차례다. 함수나 변수 앞에 export 키워드를 붙이면 해당 함수, 변수를 모듈로 내보낼 준비가 완료된다.

// ./src/lib/arithmeticOperation.js
export const add = (num1, num2) => {
    return num1 + num2;
}

모듈로 내보내고 싶은 함수, 변수 앞에는 반드시 export키워드를 붙여야지만, 외부에서 해당 함수, 변수에 접근할 수 있다.

모듈 접근하기 import

외부에서 모듈에 접근하기 위해서는 import를 이용한다. 다시 한 번 강조하지만 export키워드가 붙은 함수, 변수에 대해서만 접근이 가능한다.

import를 통해 다음과 같이 모듈에 접근한다. 이때, 쉼표,로 여러개의 함수/변수를 가져올 수 있다.

import { 모듈 함수/변수 } from '모듈 경로';

그러면, 조금 전에 만들었던 모듈에 접근한다면 아래와 같다.

// ./src/index.js
import {add} from '../lib/arithmeticOperation.js';

const num1 = 10;
const num2 = 4;

console.log(add(10, 4));


모듈에 빼기 기능까지 추가해서 작성해보았다.

//모듈 파일
export const add = (num1, num2) => num1 + num2;

export const sub = (num1, num2) => num1 - num2;
// js파일
import {add, sub} from '../lib/arithmeticOperation.js';

const num1 = 10;
const num2 = 4;

console.log(add(10, 4));
console.log(sub(10, 4));

import ~ as

기본 용법

import에는 as를 통해 별칭(alias)을 부여해서 사용할 수 있는 용법도 있다. 별칭을 부여한다는 것은 모듈을 가져올 때 이름 중복을 피하거나, 편하게 사용하기 위해서 모듈의 이름을 변경하는 것이다. as를 통한 별칭 지정은 다음과 같다.

import {원래이름 as 별칭} from '경로';

방금 전의 모듈 코드에 별칭을 붙여서 사용해본다.

import {add as a, sub as s} from '../lib/arithmeticOperation.js';

const num1 = 10;
const num2 = 4;

console.log(a(10, 4));
console.log(s(10, 4));

모듈에서 별칭 지정하고 내보내기

as를 통해 모듈에서 내보낼 때 별칭을 지정할 수도 있다.

// 모듈파일
export const add = (num1, num2) => {
    return num1 + num2;
}

export const sub = (num1, num2) => {
    return num1 - num2;
}

export {add as a, sub as s};

마지막에 exportas를 이용해서 별칭으로 내보내고 있다. 접근은 일반 모듈 접근하듯이 한다. 다만 import시 내보낸 별칭을 사용해야 별칭을 이용할 수 있다.

//js 파일
import {a, s} from '../lib/arithmeticOperation.js';

const num1 = 10;
const num2 = 4;

console.log(a(10, 4));
console.log(s(10, 4));

import * as

모듈 내에서 가져와야할 것이 많은 경우(혹은 모두 가져와야할 경우) *를 사용해서 모듈 내의 모든 함수, 변수를 가져온다.

*를 사용해서 전체 모듈을 가져오면, 모듈은 객체 형태로 가져와지기 때문에 모듈의 함수나 변수를 객체 프로퍼티, 메소드 접근하듯이 사용할 수 있다.

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

const num1 = 10;
const num2 = 4;

console.log(Op.add(10, 4));
console.log(Op.sub(10, 4));

참고자료

https://vincentgeranium.github.io/study/2019/08/26/module.html
https://codedragon.tistory.com/6139
https://m.blog.naver.com/cybervictor008/220698639553
https://xionwcfm.tistory.com/185

추후에 읽어보면 좋을 자료

https://velog.io/@bami/Javascript-%EB%AA%A8%EB%93%88-Module

profile
hello, world!

0개의 댓글