js를 공부하면서 상당히 헷갈렸던 부분 중 하나가 이 모듈 파트이다. 나는 파이썬을 주로 사용했는데, 파이썬은 가상환경 설정만 잘 해주면 이 모듈 부분에서 어려울 일이 많이 없다. 처음에 commonjs 방식으로 배워서 사용하는데, 클라이언트 코드와 서버 코드가 한 레포에 있는 플젝을 하면서, 한참을 해맸었다. 우선 클라이언트쪽에선 commonjs 방식으로 모듈들을 불러올 수 없다고 한다... js에서의 모듈에 대해 공부해보자.
모듈은 파일이며, 각자 개별적인 요소로서 조직화되어 있으며 재사용이 가능한 코드조각들을 말한다. 보통 프로그래밍에서는 코드의 유지보수성과 재사용성을 향상시키기 위해 사용되며, 프로그램을 작은 부분으로 나누고, 각 부분을 독립적으로 관리하고 구성할 수 있도록 도와준다.
모듈의 특징은 다음과 같다.
javascript에는 크게 두가지 모듈 시스템이 있다. CommonJS와 ES Modules이 그것이다.
CommonJS 모듈 시스템은 2009년 Node.js 프로젝트에서 시작되었다고 한다. Node.js는 서버 사이드 JavaScript 개발을 위해 만들어진 플랫폼으로, CommonJS를 자체 모듈 시스템으로 도입되었다. 서버 측에서 모듈화된 코드를 구조화하고 재사용성을 높이기 위한 목적으로 개발되었다.
동기적으로 모듈을 로드하며, require 함수를 사용하여 모듈을 가져오고 module.exports 객체를 사용하여 내보내기를 정의한다. Node.js에서 주로 사용되며, 브라우저 환경에서는 동작하지 않는다.
ES Modules는 ECMAScript 6(ES6)의 일부로 2015년에 도입되었다. ES6는 JavaScript 언어의 표준 사양 업데이트로, 모듈 시스템을 포함한 여러 개선 사항을 제공했다. JavaScript 언어 자체에 네이티브 모듈 시스템을 도입하여, 브라우저와 Node.js를 포함한 모든 JavaScript 환경에서 일관된 모듈 시스템을 사용하도록 하려는 목적으로 개발되었다.
비동기적으로 모듈을 로드하며, import 문을 사용하여 모듈을 가져오고 export 문을 사용하여 내보내기를 정의한다. ES6에서 도입되었지만, 브라우저와 Node.js 환경에서 모두 지원되는 모듈 시스템으로 사용할 수 있다.
현재, 대부분의 모던 브라우저와 Node.js는 ES Modules를 지원하고 있으며, 브라우저에서도 널리 사용되고 있다. CommonJS는 여전히 서버 사이드 환경에서는 유용하지만, 브라우저 환경에서는 ES Modules를 사용하는 것이 권장된다.
CommonJS의 특징
1. 동기적 로딩: CommonJS 모듈은 동기적으로 로딩된다.
2. require와 module.exports: require 함수를 사용하여 다른 모듈을 가져오고, module.exports 객체를 통해 모듈의 내보내기를 정의한다.
3. 서버 환경에서 주로 사용: CommonJS는 주로 서버 사이드 개발 환경에서 사용되며, Node.js에서 표준 모듈 시스템으로 사용된다.
// 모듈 내보내기
module.exports = {
greet: function (name) {
return `Hello, ${name}!`;
},
};
// 모듈 가져오기
const greeter = require("./greeter");
console.log(greeter.greet("John"));
1. 비동기적 로딩: ES Modules는 비동기적으로 로드된다.
2. import와 export: import 문을 사용하여 다른 모듈을 가져오고, export 문을 사용하여 모듈의 내보내기를 정의한다. export default와 같은 다양한 내보내기 형식을 지원한다.
3. 브라우저와 Node.js에서 모두 사용 가능: ES Modules는 브라우저와 Node.js에서 모두 사용할 수 있으므로, 클라이언트 사이드 및 서버 사이드 개발 모두에서 사용할 수 있다.
// 모듈 내보내기
export function greet(name) {
return `Hello, ${name}!`;
}
// 모듈 가져오기
import { greet } from "./greeter";
console.log(greet("John"));
그러니까 이제는 ES Modules을 사용하면 되는 것 같다. esm을 사용하기 위해선 package.json에 "type": "module",
을 꼭 추가해줘야 한다. 그리고 또 한가지 실수했던 경험을 공유하자면, 클라이언트 코드와 서버 코드를 한 레포에서 작업할 때, 클라이언트로 넘어가는 정적코드에 서버쪽 모듈을 임포트하면 안된다.... 그러면 놀랍게도 서버쪽으로 get요청이 들어온다. 예를들어 클라이언트 쪽에서 서버쪽 코드를 참조하기 위해 import test from "./test/wow.js"
를 작성하면 우선 브라우저가 해당 파일이 있는지 확인해보고 없으니까 서버쪽으로 http://~~~~/test/wow.js 주소로 get요청을 보내더라... 처음 이걸보고 당황해서 한참을 디버깅했는데... 실수를 확인하고 다소 황당했다 ㅠ