2 minute read

컨트롤러 title: “노드JS 메인 모듈화” excerpt: “노드JS 메인 모듈화 입니다.”

categories:

  • nodejs tags:
  • [node.js]

toc: true toc_sticky: true

last_modified_at: 2023-03-24T20:00:00-05:00

들어가기전에

앱을 구성할 때는 위에서부터 아래로 순서대로 실행되기 때문에

1) 공통 미들웨어: 모든 라우트에서 사용하는 2) 범위가 좁은 라우트: path variable을 사용하는 3) 범위가 넓은 라우트: query String을 사용하는 4) 에러 처리 미들웨어

순으로 작성해야한다.

엔트리 파일

모든 시작점이 되는 Main() 파일을 뜻한다.

Node.js 엔트리 파일 네이밍

Node.js에서 엔트리 파일명은 일반적으로 “index.js”로 작성한다.
이는 Node.js가 디렉토리를 읽을 때 해당 디렉토리의 index.js 파일을 자동으로 로드하기 때문이다. 따라서, 프로젝트의 메인 파일이라면 index.js로 작성하는 것이 일반적이다.

그러나 프로젝트가 복잡해질 경우, 서버 코드와 클라이언트 코드를 구분하기 위해 server.js와 client.js와 같은 파일명을 사용하기도 한다.

이 경우에는 package.json 파일의 main 항목에 엔트리 파일의 경로를 지정해주어야 한다.

/package.json

{
...
"main": "index.js",
...
}

그런데 가끔 “app.js” 라는 파일명이 보인다. 보통 Express.js와 같은 웹 프레임워크에서 엔트리 파일명으로 사용된다. Express.js는 애플리케이션 객체를 생성하는데 이를 “app” 객체라고 한다. 이 “app” 객체를 사용해 웹 서버를 만들고, 라우팅 등을 정의하는 등의 작업을 수행하기 때문에 붙여진 사용되기 시작한건가 싶다.

따라서, Express.js를 사용하는 프로젝트에서는 “app.js”가 엔트리 파일명으로 사용되는 경우가 많다. 하지만 이 역시도 규칙은 아니며, 프로젝트의 구조나 개발자의 개인 취향에 따라서 다른 파일명이 사용될 수 있다.

STEP1. 엔트리파일 생성 및 분리

.
├── app.js         # Express 관련 실행 모듈로 사용예정
├── server.js      # 실제 Main() 으로 사용예정
├── controllers
│   ├── main
│   │   └── main.controller.js
│   └── member
│        └── member.controller.js
└── routes
     ├── index.js         
     ├── main
     │    └── index.js   
     └── member
           ├── basic
           │   └── index.js
           └── index.js

요약하면 다음과 같다.

  1. Express 관련 내용은 app.js 모듈로 사용하고 (기존에는 main 역할을 했었다.)
  2. 이제부터 main을 server.js 으로 사용한다.

server.js (AS-IS: app.js)

touch server.js
touch app.js

STEP2. Express 파일의 클래스 모듈화

/server.js (메인역할)

// AS-IS
// const express = require('express');
// const app = express();

//TO-BE
const app = require('./app.js'); // Express 내용을 모듈화하여 코드가 간단해졌다. (생성자를 통한 모듈 실행)
const PORT = 3000;

app.listen(PORT, () => {
    console.log('서버가 실행됩니다.. http://127.0.0.1:' + `{PORT}` + '/');
});

/app.js (클래스 모듈화)

const express = require('express');
//const app = express();
const PORT = 3000;

class App {
    constructor() {
	    this.app = express();
	    this.setRouting();
    }
    
    setRouting() {
    	const routes = require('./routes'); 
        this.app.use('/', routes);
    }
}

// 클로저로 은닉화한 app 객체를 모듈화하여 익스포트
module.exports = new App().app;

앞으로 main 역할을 하는 server.js 안에 다양한 모듈을 붙였다 떼면 된다.

스코프와 은닉화 관련 내용

만약 app.js 다음과 같이 작성하면 어떻게 될까 예상해보자.

const express = require('express');
const app = express();

class App {
    constructor() {
        this.app = express();
    }
}

module.exports = new App().app;

매우 좋지않다. 요약하면 다음과 같다.

  1. express를 불러와 app 변수에 할당하고,
  2. App 클래스를 생성하면서 생성자를 통해 app 변수를 또 하나 생성한다.
  3. 그리고 그 생성한 app 변수를 다시 외부로 노출시키고 있다.

즉, 중복되는 app 변수가 생성되어 메모리 낭비를 초래한다.

따라서 앞서 구현했듯이 아래와 같이 코드를 수정했던 것이다.

const express = require('express');

class App {
    constructor() {
        this.app = express();
    }
}

module.exports = App;

Updated:

Leave a comment