본문 바로가기
프로그래밍_

자바스크립트 ES6 , CommonJS 문법, 모듈시스템 차이

by Mocca_ 2023. 1. 26.

nodejs의 장점은 모듈시스템입니다. 모듈시스템을 구성하는 방법은 node에서는 단순하게 ES6식, CommonJS식 모듈시스템 2개가 있습니다. 오늘은 ES6, CommonJS 뭐가 다른지 어떨 때 무엇을 쓰는게 현명한지 알아보겠습니다.

 


[목차]

  1. ES6란? CommonJS란?
  2. ES6식, CommonJS식 모듈시스템
  3. Nodejs에서 어떻게 쓰는게 현명한가?

 

 

 

 

1. ES6란? CommonJS란?

 

ES6 는 React에서 모듈을 불러오기 위한 (import , export)를 포함합니다. Python과 Java와 비슷합니다. 

CommonJS는 NodeJs에서 모듈을 불러오기 위해 (require , exports) 키워드를 포함하니다. 

 

어떻게 보면 클라이언트단 프레임워크와 서버단 프레임워크에서의 모듈 불러오는 키워드가 다른 것인데 둘 다 언어를 자바스크립트를 사용하므로 혼란을 주며 동작은 미묘하게 다릅니다. 

 

CommonJS는 2009년에 만들어진 표준으로 자바스크립트 모듈을 만들기 위한 법칙입니다. 오로지 서버사이드 모듈을 만들고 불러오기 위해 개발되었습니다. 2010년에는 제대로 된 모듈시스템이 없어서 클라이언트에도 쓰이곤 했습니다. 그러면서 생겨난 것이 ECMA라는 국제 기구 표준문서 스펙입니다. 2016년에 나와서 ES6이라 부르고 2017년에 나온 것은 ES7입니다. 

 

ECMA가 등장한 이유는 워낙 많은 웹 브라우저가 있기에 그것에 대한 표준으로 만들어서 통일시키기 위함입니다. 하지만 클라이언트가 단순한 기능을 넘어서 ES6부터 클래스도 추가되었으며 모듈화를 지원하기 시작했으므로 앞서 말했던 CommonJS와 헷갈리기 시작했습니다. MS의 브라우저는 ES6을 지원해주지 않아 바벨이라는 트랜스파일러를 쓰기도 합니다.

 

 

2. ES6식 CommonJS식 모듈시스템

 

CommonJS에서는 require()로 모듈을 불러왔지만 ES6에서는 import()를 사용합니다. require는 어디든 사용할 수 있지만 import는 초기화할 때 사용합니다. 따라서 import는 동기 함수입니다. import 또한 CommonJS에서 비동기로 사용할 수는 있습니다. 

 

//CommonJS
module.export = 함수나 클래스, 변수

const module1 = require('./example.js')

//ES6
export default module

import module2 from './example.js';

 

동시에 이 문법을 사용하면 에러가 납니다. 단순하게 서버에서는 CommonJS, 클라이언트에서는 ES6를 쓰면 되지 않은가라고 의문을 가질 수 있습니다. 답은 다음 목차에서 하겠습니다.

 

 

 

3. NodeJS에서는 어떻게 쓰는게 현명한가?

 

결론부터 말하자면 ES6식 모듈을 쓰는 것이 좋습니다. ES6식 모듈은 기본적으로 "strict mode"로 되는데 strict mode란 첫째로 기존에 무시되던 에러를 throwing하고 ECMAScript의 차기 버전 정의 문법을 금지합니다. 

 

 ES6식 모듈 표기는 모듈이 전역변수에서 수정될 수 있는 위험성이 있는 상황을 막고 동적으로 생성되는 CommonJS와 달리 정적이라서 각 한 가지에 한 가지만 책임지는 SRP(Single Responsibilty Principal)을 지킬 수 있게 만들어줍니다.

 

ES식 모듈은 정적이며 import가 모든 모듈의 가장 상위 , 바깥 쪽에 기술되어 실행시 동적으로 생성되지 않고 상수 문자열만 허용됩니다. NodeJS에서 보통 CommonJS가 사용되지만 몽키패치(전역변수 수정)의 위험에 따라 ESM(ECMAScript 모듈)을 쓰길 권합니다.

 

CommonJS에서 가장 많이 사용되는 특성 중에 하나는 이름이 없는 개체를 모두 module.exports에 넣어서 쉽게 할당할 수 있다는 것인데 이를 default export로 바꾸고 

 

import { defaultName } from './example.js'; 와 같이 특정 클래스나 함수, 변수를 빼서 사용하는 것을 권합니다. 

 

그러면 비동기가 필요할 때는 어떻게 하는가? 에 대한 대답은 비동기 import를 사용하면 됩니다. 동적 임포트 기능을 자바스크립트에서는 예외적으로 적용하고 있습니다. 

const dynamicmodule = prompt("가져올 모듈이 무엇입니까?")
import(dynamicmodule)
	.then(obj => {
    	console.log(obj)
    })

 

결론은 CommonJS식 모듈 표현과 ES6식 모듈 표현 둘 다 이해가능해야하지만 우선 프로그램은 ES6식 모듈 표현을 우선으로 사용하다가 정적인 부분, 전역 모듈 수정의 부분에 대한 제약이 있거나 불편한 사항이 있을 때 CommonJS의 편의성과 장점을 이용하여 혼합해서 사용하면 됩니다. 

 

require에 익숙해서 바꾸는게 쉽지 않겠습니다. import도 골라서 적용해야된다는게 귀찮은 일이지만 말입니다.

 

 


[함께 읽으면 좋은 글]

2023.01.25 - [취미로 코딩하기] - Docker, 도커를 사용하는 이유와 도커 설치법

 

Docker, 도커를 사용하는 이유와 도커 설치법

도커를 사용하면 서버환경 구성하기 편하다는 말을 조금씩 들어왔지만 제대로 공부하고 설치해본 적은 없었습니다. 그래서 이번에는 도커를 활용해 AZURE나 AWS서버를 구축하는 과정을 해보려했

commnetall.tistory.com

 

2023.01.11 - [취미로 코딩하기] - React vs Flutter 무엇을 써야 할까 ? - 개발자 언어, 앱 언어, 개발 외주, 로드맵

 

React vs Flutter 무엇을 써야 할까 ? - 개발자 언어, 앱 언어, 개발 외주, 로드맵

요즘 스타트업에서 자주쓰는 언어는 React와 Flutter입니다. React는 페이스북이 개발한 사용자 인터페이스를 만들기 위한 라이브러리입니다. Flutter는 구글이 만든 원코드베이스 모바일, 웹, 데스크

commnetall.tistory.com

 

 


 

 

 

댓글