February 08, 2020
앞선 포스트에서 브라우저가 자바스크립트엔진을 통하여 자바스크립트를 실행하고 더나아가 브라우저 객체 혹은 DOM (html을 비롯한 태그요소들의 객체형태) 에 접근하는 방식에 대해 다뤘다.
브라우저 프로그램은 자체 자바스크립트엔진을 내장해서 브라우저를 컴퓨터에 설치하면 자동으로 자바스크립트엔진이 설치되고 브라우저 내에서 자바스크립트를 실행할 수 있다.
이렇게 개발자도구 콘솔을 이용하면 된다.
하지만, 브라우저 없이 자바스크립트의 실행환경을 구성할 수 없을까?
이 때, 브라우저 없이 내 컴퓨터에서 자바스크립트를 실행할 수 있는 프로그램이 바로 nodeJS 이다.
즉, 내 자바스크립트 프로그램을 프로세스로 만들어 주는 것이 바로 nodeJS !
nodeJS는 크롬과 같은 v8 자바스크립트 엔진을 사용한다.
그리고 html에서는 <script></script> 태그로 자바스크립트파일을 불러와 실행 시켰다면 nodeJS 에서는 node 파일이름.js 처럼 명령어를 통해 자바스크립트를 실행한다.
nodeJS는 실행컨텍스트 내에서 대표적으로 싱글스레드, 비동기 방식으로 자바스크립트를 실행한다.
그럼 구체적으로 nodeJS로 무엇을 할 수 있을까?
웹의 작동원리는 브라우저에서 다른 컴퓨터(서버)의 프로세스에 포트를 통해 접근해서 필요한 소스를 받아오는 식이다.
만약 다른 사용자가 웹을 통하여 내 프로그램에 접근하고 싶을 때, 내 프로그램은 컴퓨터 어디선가 프로세스 형태로 돌아가고 있어야 하고 nodeJS는 내 컴퓨터의 리소스를 사용해 프로그램을 돌려준다. (즉 nodeJS 내장 자바스크립트 엔진을 이용해 자바스크립트를 실행시켜준다.)
모듈 : 특정한 기능을 하는 함수나 변수들이 캡슐화된 집합
방대한 프로그램의 덩치를 관리가 용이하게 쪼개거나 외부 잘 만들어진 프로그램을 쉽게 내 프로그램에도 쓸 수 있게 해주는 것이 모듈!
모듈은 자체로도 하나의 프로그램이면서 전체 프로그램의 부품으로 사용된다.
의존성 : 모듈 간의 연결 혹은 관계
프로그램이 커짐에 따라, 사용하는 모듈의 수가 많아지면 모듈들에 있는 변수, 함수 객체들이 충돌할 가능성이 높아지기 때문에 모듈들이 충돌하지 않게 의존성을 부여해 주어야한다.
의존성 부여는 자바스크립트 실행 컨텍스트의 scope chain과 관련이 있다.
자바스크립트는 실행 컨텍스트 내에서 현재 스코프의 변수와 함수를 우선적으로 스캔하고 없을 시, scope chain 을 참조해 다음 스코프로 넘어간다.
근데 scope chain을 참조하는 과정에서 다른 기능을 하지만 똑같은 변수명의 변수나 함수를 만나버리면 프로그램이 치명적인 에러를 발생할 가능성을 낳는다.
그렇게 자바스크립트 파일 내에서 이것은 모듈이니까 나 외에는 참조하지마! 하고 Dependency Injection을 해줘야한다.
html script 태그 내에서 type 속성에 module 속성값을 넣어줌으로써 직접 모듈임을 정의 해줄 수 있다.
<script src="app.js"></script>
<script type="module" src="module1.js"></script>script태그에 넣어주는 방식은 브라우저에 국한되므로 많은 제약이 있다. 그렇게 브라우저뿐만 아니라 내 컴퓨터에 있는 javascript 파일을 모듈로서 정의하고 사용하기 위해(서버사이드 자바스크립트) CommonJS 라는 단체가 나오게 된다.
현재 CommonJS도 ECMAScript 와 마찬가지로 자바스크립트의 모듈화를 위한 하나의 명세(문법)을 정의했으며 nodeJS에서 이를 받아들여 모듈화를 위한 언어를 사용할 수 있게 되었다.
// 부분 모듈화
exports.function functionA() {}
exports.function functionB() {}
// 전체 모듈화
// moduleName1 객체에 모든 내용 담기!
module.exports = moduleName1// 경로로 사용
const module1 = require('./moduleName1')
// node_modules or 내장모듈 사용
const express = require('express')nodeJS에서는 일반적으로 CommonJS 방식을 사용하나 점차적으로 ECMAScript 모듈 방식도 도입 중이다.
// 부분 모듈화
export function functionA() {}
export function functionB() {}
// ⭐ 전체 모듈화 (default export)
// 보통 파일 안에 하나의 모듈을 모듈화 할 때 사용!
export default moduleName2// 전체 모듈 사용
import * from './moduleName2'
// ⭐ 전체 모듈 사용 (default import)
// 보통 파일 안에 하나의 모듈을 모듈화 할 때 사용!
import whatever from './moduleName2'
// 부분 모듈 사용
import { moduleFunc } from './moduleName2'
// node_modules or 내장모듈 사용
import os from 'os'export vs default export
export는 모듈을 import 할 때, {}를 꼭 써줘야 한다. {}는 사용 모듈의 제한성 표시이며 해당 모듈명과 동일하게 써줘야 한다. 바꾸고 싶으면 {moduleFuc as myModuleFuc } 이르케 써줘야함.
default export는 모듈 내에 하나의 모듈화를 위해 사용되는데 모듈을 import 할 때, {}를 붙이지 않으며, 자신이 원하는 모듈명으로 모듈을 사용할 수 있다.