이번에는 모듈 이라는 주제에 대해서 알아보자.
모듈이라는 것에 대해 알아보기 전에, 우리는 부품이라는 단어의 의미에 대해 생각보아야 한다.
프로그램은 작고 단순한 것에서 크고 복잡한 것으로 진화한다.
그리고 크고 복잡한 프로그램에서는 유지보수의 용이성, 재활용 성이 꼭 필요하다.
어떤 프로그램을 구성하고 있는 수 많은 로직들을
재사용 될 수 있는 단위로 조각조각 나누고 구획화 시켜서
별도에 모듈이라는 형태로 떼어내고
이것을 또 다른 프로그램에 부품으로 사용하는 기법
그리고 그 부품들을 모듈이라 하고, 이러한 기법을 모듈화 라고 한다.
즉, 잘 만들어진 모듈은 아주많은 프로젝트에서 사용될 수 있는 아주 좋은 부품이 되는 것이다.
다시 말하면 모듈화는 어떤 프로그램이 동작하는 방식에 따라서
여러개의 파일로 분리하는 것이다.
이를 통해서 얻을 수 있는 효과는
1. 자주사용하는 코드를 별도의 파일로 만들어 필요할 때마다 재활용 할 수 있다.
앞서 함수를 공부할 때 함수를 정의하게 되면, 이 함수의 내용을 바꾸면, 함수를 사용하는 모든 곳에서 내용이 바뀐다.
이와 같이, 연관돼있는 변수들을 모아서 파일로 쪼갠다음에, 그 파일을 읽어오는 방법을 통해서
재사용성을 높이는 것이 모듈화이다.
2. 코드 수정시에 필요한 로직을 빠르게 찾을 수 있다.
파일로 모듈을 쪼개놓게 되면, 파일의 이름에 따라 관련된 로직들만 모여있기 때문에 필요한 파일을 빠르게 찾을 수 있다.
3. 필요한 로직만을 로드해서 메모리의 낭비를 줄일 수 있다.
필요한 것이 있다면, 필요한 파일만 읽어와서 메모리 낭비를 막을 수 있다.
4. 한번 다운로도된 모듈은 웹브라우저에 저장되기 때문에 동일한 로직을 로드 할 때 시간과 네트워크 트레픽을 절약할 수 있다(브라우저만 해당)
사용자 입장에서는 기다리는 시간, 네트웍 사용 비능이 줄어드는 것이고,(트래픽이 덜 걸리고)
자바스크립트에서는 다른 언어들처럼 모듈이라는 개념이 분명이 존재한다고 할 수는 없다.
그리고 자바스크립트 자체는 모듈이라는 기능 자체를 제공하진 않는다.
대신에 자바스크립트가 구동되는 환경,
브라우저 node.js 구글 앱스 스크립트를
환경을 호스트환경이라 부르는데, 이 호스트 환경에 따라서
자바스크립트 로직을 파일로 분리해서
마치 다른언어에서의 모듈처럼 사용할 수 있는 방법들을 제공한다.
사용하는 호스트 환경에 따라 모듈을 사용할 수 있는 방법이 다르기 때문에,
호스트 환경에 따른 모듈화 방법은 따로 알아야 한다.
여기서는 웹브라우저에서 파일을 모듈화 하는 방법을 중점적으로 배울 것이며,
다른 환경은 따로 배워야 할 것이다.
그렇다면 모듈의 효용을 알아보기 위해서
모듈이 없는 애플리케이션과 있는 애플리케이션을 비교해보자.
다음과 같은 코드를 작성하고 main.html로 저장해보자.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
function welcome(){
return 'hello world'
}
alert(welcome());
</script>
</body>
welcome이라는 함수가 있다. 현재 코드는 매우 간단해보이지만,
만약 함수 안에 있는 내용이 복잡해지면 어떨까?
또 이 함수가 하나의 페이지 안에서 20번 호출된다면?
그리고 현재 호출하고 있는 main.html말고 다른 html에서 호출하면 어떻게 될까?
약 100개, 200개, 300개의 html파일이 welcome이라는 함수를 호출하면?
이런 경우에 welcome이라는 함수를 별도의 파일로 빼고,
그 별도의 파일을 읽어오는 것을 통해서 welcome이라는 함수를 사용할 수 있다면
길고 복잡한 코드가 단 한줄로 바뀔 수 있을 것이다.
우선 html의 head라는 부분에
<script src='greeting.js"></script>
라는 코드를 입력해준다.
웹페이지가 화면에 출력될 때, 웹브라우저가 스크립트라는 태그를 만나게 되면
그 스크립트라는 태그에 src 속성이 있는지 없는지 우선 확인하고
그 속성에 어떠한 값이 있다면, 그 값에 해당하는 파일을 읽어온다.
즉, script라고 돼있는 부분에 gretting.js라는 파일의 코드를 집어넣는 것과 같은 효과를 낸다.
이 gretting.js에는 welcome이라는 함수를 넣어놓고,
function welcome(){
return 'hello world'
}
이것을 main.js에서는 하단의 코드만으로 출력할 수 있게 된다.
alert(welcome());
welcome이라는 함수가 아주 길고 복잡한 함수였다면, 그 함수를 별도의 파일로 분리하는 것을 통해서
main.html의 웹페이지 내용이 간결해졌다.
이 main.html이란 파일은 웹페이지를 표시하기 위한 파일이기 때문에, 웰컴이라는 함수가 어떻게 동작하느냐 하는 부분은
이 파일의 관심사가 아니고, 이 파일의 관심사가 아닌 것을 별도의 파일로 분류해서
이 파일에서 중요한 부분인 welcome이라는 함수를 호출한다는
정보만을 노출하는 것을 통해서 코드의 가독성을 획기적으로 올릴 수 있다.
또 main.html라는 파일에 용량을 줄여줘서
이 파일을 저장하는 쪽이나, 이 파일을 다운로드 받아서 보는 사용자 입장에서나 모두가 좋은 결과를 얻을 수 있다.
또 sub.html 파일을 만들어보자. 이는 main.html이라는 다른 취지의 페이지로
이 페이지에서도 welcome이라는 함수를 호출한다고 하면,
우리는 이 함수의 정의가 greeting.js에 있기 때문에
sub.html에서도 welcome이라는 함수를 이용할 수 있게 된다.
현재는 2개의 파일이 welcome이라는 파일을 쓰고 있는데, 만약 welcome함수를 100개의 파일, 1000개의 파일에서 사용한다면
모듈화를 통해 훨씬 큰 효과를 볼 수 있을 것이다.
지금까지 브라우저에서는 어떻게 모듈을 로드하는가에 대해서 살펴봤다.
이번에는 node.js(서버쪽 자바스크립트)에서는 어떻게 모듈을 로드하는가를 통해서
다른 환경에서는 모듈을 로드하는 방식이 다르다는 것을 이해해보자.
2개의 파일이 있다. node.circle.js(읽음을 당하는, 로드될 대상), 그리고 node.demo.js(로드할 주체, 읽을 주체)
[node.circle.js]
var PI = Math.PI;
exports.area = function (r) {
return PI * r * r;
};
exports.circumference = function (r) {
return 2 * PI * r;
};
[node.demo.js]
var circle = require('./node.circle.js');
console.log( 'The area of a circle of radius 4 is '
+ circle.area(4));
그렇다면, node.js에서는 어떻게 모듈화된 파일을 읽어올까?
node.js는 require라는, node.js가 제공하는 require함수를 통해서, 그 함수의 인자값으로
우리가 읽어오고자 하는 파일의 이름을 언급하면 그 파일을 가져와서 그것을
circle이라는 변수에 담게 된다.
그다음에 circle이라는 변수에, circle.area(4)라고 하면,
node.circle.js에서 exports.area라고 돼있는 함수를 사용할 수 있게 된다.
그래새 이것을 출력한 결과는 다음과 같다.
The area of a circle of radius 4 is 50.26548245743669
이렇게 node.circle.js를 만들어놓고
여러 파일에서 이를 로드함으로서
circle.js안에 들어있는 로직을 재활용 할 수 있게 되는 것이다.
근데 node.js에선 모듈 안에 export.circle / export.circumference 라고 돼있는 부분 때문에 좀 헷갈린데
나중에 node.js에서 다시 배워야 겠지만 찾아보니 모듈에는 저렇게 적어주는거 같다..^^;
'IT 인터넷 > javascript' 카테고리의 다른 글
[javascript 언어공부]UI와 API (1) | 2018.06.11 |
---|---|
[javascript 언어공부] 모듈(2) (0) | 2018.06.01 |
[javascript 언어공부] 객체(3) (0) | 2018.06.01 |
[javascript 언어공부] 객체(2) (0) | 2018.06.01 |
[javascript 언어공부] 객체(1) (0) | 2018.06.01 |