시작하기에 앞서 commonJS와 ESmodule이 무엇인지 부터 개념을 알고 가야할 것 같다.
CommonJS는 Node.js의 기본 모듈 시스템입니다. type 필드에 "commonjs"로 설정되면, 해당 프로젝트는 CommonJS 방식으로 모듈을 로드합니다. CommonJS 방식에서는 require 함수를 사용하여 모듈을 가져옵니다. 모듈은 동기적으로 로드
되며, module.exports를 사용하여 모듈의 내보낼 값을 정의합니다. CommonJS는 동적 로딩 및 트리 쉐이킹과 같은 최적화 기능을 제공하지 않습니다.
ES Modules는 ECMAScript 2015(ES6)에서 도입된 표준 모듈 시스템입니다. type 필드에 "module"로 설정되면, 해당 프로젝트는 ES Modules 방식으로 모듈을 로드합니다. ES Modules 방식에서는 import 문을 사용하여 모듈을 가져옵니다. 모듈은 비동기적으로 로드
되며, export 키워드를 사용하여 모듈의 내보낼 값을 정의합니다. ES Modules는 정적으로 로딩되므로, 브라우저에서는 동적으로 모듈을 로드하거나 트리 쉐이킹을 수행할 수 있습니다. ES Modules는 브라우저 및 최신 버전의 Node.js에서 사용할 수 있으나, 이전 버전의 Node.js에서는 실험적인 기능으로 제공됩니다.
두가지는 Node.js에서 사용하는 모듈시스템의 방식이다. 가장 큰 차이를 예시로 보자면
commonJS : 동기적 로드,const abc = require('abc')
, module.exports={createf}
ESmodule : 비동기적 로드, import express from 'exress'
,export default route
이런내용들이다.
시작은 ES5, ES6로 구분되어 나타나게 되는데 ES5 -> ES6로 업데이트 되면서 추가적인 기능들과 변화된 내용들이 있다.
🔗지인이 정리해놓은 ES5 vs ES6
참고에 참 좋은 자료다.
이제부터 이 두가지 차이점에 대해서 express
를 사용해서 초기셋팅을 하는데에 대한 차이점을 알아보자.
🔗언제까지 살아있을지 모르는 초기셋팅 레포링크
const express = require("express");
const cors = require("cors");
const morgan = require("morgan");
const { globalErrorHandler } = require("./utils/error");
const createApp = () => {
const app = express();
app.use(express.json());
app.use(cors());
app.use(morgan("dev"));
app.use(globalErrorHandler);
app.get("/ping", (req, res) => {
res.status(200).json({ message: "pong" });
});
return app;
};
module.exports = { createApp };
import { createConnection } from "typeorm";
let connection;
const initialize = async () => {
connection = await createConnection({
type: process.env.DB_TYPE,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
};
const destroy = async () => {
if (connection) await connection.close();
};
export default { initialize, destroy };
여기서 commonJS는 require과 module.exports , ESmodule은 import와 export를 사용하는 것을 볼 수 있다.
ESmodule 나중에 나온 모듈이기 때문에 개선점이나 유연성과 같은 이점에 대해서 나온것이기 때문에 ESmodule의 이점을 정리한 블로그가 있어 공유한다.
🔗ES6 module에 대한 이점과 추가적인 내용들
서론이 길었다...후아..그럼 이정도로 commonJS와 ESmodule에 대한 내용들을 알아봤으니 문제해결을 위한 단계로 넘어가보자.
새로운 작업들을 하기위해 초기셋팅은 필수.(가능하면 굳이 하나하나 코드를 다 칠 필요는 없다고 생각하지만.. 나는 했다..)
하지만 여기서 나에게 시련이 다가왔다.(기본기가 깊지 않은 자의 슬픔이란.......😇)
commonJS와 ESmodule은 작동의 방식이 다르긴 하지만 결국 모듈을 불러오고 보내주고 하는 본질적인 기능은 그대로 이다.
하여 그런생각으로 express와 typeorm을 사용하기 위해서 작업을 하는데......
이런 소스코드로 위 이미지와 같은 에러가 발생했다.
import * as DataSource from "typeorm";
const appDataSource = new DataSource({
type: process.env.DB_TYPE,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
export default appDataSource;
코드내용을 적어내려가면
1. import * as DataSource from "typeorm";
->typeorm 모듈의 모든내용을 DataSource라는 이름으로 사용할게.
2. const appDatasource(이하생략)
->appDataSource는 new DataSource라는 새로운 객체 클래스를 만들어서 사용할거야.
3. export default appDataSource
-> appDataSource라는 함수를 기본으로 모듈에 내보낼거야.
이다.
이런저런 시도 끝에 문제의 원인을 찾을 수 있었는데, appDataSource 안에 .env
에 문제가 있었다.
import { DataSource } from "typeorm";
const appDataSource = new DataSource({
type: process.env.DB_TYPE,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
export default appDataSource;
require
함수를 사용한 common JS
type에서는 .env
의 경우 server.js에서 연동되어 typeorm에 자동으로 연동되어 연결이 문제 없이 발생했었지만 import
를 사용한 module
type에서는 작동되지 않았다.
⬆️ .env를 직접적으로 사용하지 않았을때의 에러
import { DataSource } from "typeorm";
import dotenv from "dotenv";
dotenv.config();
const appDataSource = new DataSource({
type: process.env.DB_TYPE,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
export default appDataSource;
⬆️ .env를 명시한 후에 작동되는 모습
위 이미지 처럼 DB에 접근할 수 없다는내용을 확인할 수 있었다.
근본적인 문제에 대해서는 내가 지식적으로 부족한 점으로 아주 정확하게 확언할 수 있지는 못하지만 동기작동 타입인 commonJS와 비동기작동 타입인 module 타입의 차이에서 dotenv를 어떻게 활용해야하는지에 차이 이지 않을까 한다.
(물론 이외에도 babel이라는 모듈을 통해서 다른방식으로도 활용해볼 수 있을 것으로 생각한다.)
이번 스터디에서는 commonJS와 ESmodule의 차이를 공부로 시작되었지만 만약 예상이 적중되는 동기 작동 모듈(commonJS)
과 비동기 작동 모듈(ESmodule)
의 차이라면 동기/비동기에 대해서 추가적으로 공부를 확장해서 할 필요도 생긴다.
이번 내용은 이정도 쯤에서 마무리를 해야겠다.(늘 깊게 고민해서 매몰되어 지구 핵까지 빠져들어가 카오스가 온다...🌎)
이렇게 commonJS와 ESmodule에 대해 사용하는 방법의 일부분을 공부할 수 있었다.
하지만 Node.js는 commonJS 타입모듈을 기본으로 사용하는 런타임환경이기 때문에 ESmodule을 사용하는데에 연동이나 활용에 대해서 불편한부분들이 있다.
그리고 이부분을 좀 더 유연하게(?) 활용하기 위해서 나온 패키지가 있다.
바로 babael
.
다음은 babel에 대해서 알아보는 시간도 가져보자.
🔗babel에 대하여 공부해보는 링크