본문 바로가기

서버 개발

Express.js 4 -> 5로 마이그레이션 가이드

서론

Express.js는 Node.js를 기반으로 한 서버 개발 프레임워크 중 하나이다.

회사에서는 보통 Java진영의 Spring Boot를 주로 사용하지만, 간단한 개인 프로젝트를 진행할 때는 Express.js를 많이 선택하기도 하기 때문에 평소부터 관심이 많던 프레임워크이다.

그런데 최근 Express.js 5버전이 나왔다는 것을 알게 되었다. 바로 5버전을 이용하여 프로젝트를 새로 진행할 수도 있겠지만, 기존에 4버전을 사용하는 서버를 5버전으로 마이그레이션하는 경우도 발생할 것이라 생각되었다.

그래서 이번기회에 기존 4버전에서 5버전으로 마이그레이션하는 가이드를 번역 및 정리해보기로 하였다.

 

 

https://expressjs.com/en/guide/migrating-5.html

 

Express - Node.js web application framework

 

expressjs.com

공식 문서를 보고 번역 및 정리하였습니다.

 

 

Express 5 설치 및 준비

Express 5는 기본적으로 Node.js 18 이상의 버전에서 지원된다.

Expross를 최신 버전으로 설치하려면 아래 명령어 사용하면 된다.

$ npm install "express@>=5.0.0" --save
 

 

Express 5에서 제거된 메서드와 속성

업데이트 후 아래 메서드를 그대로 사용하면 애플리케이션이 에러가 발생한다. 따라서 아래 메서드들은 반드시 변경된 메서드로 마이그레이션해야 한다.

1. app.del() 제거

//변경 전:
app.del('/users/:id', (req, res) => { res.send('Deleted!'); });

//변경 후:
app.delete('/users/:id', (req, res) => { res.send('Deleted!'); });
  • 더 이상 app.del() 함수를 지원하지 않는다. 대신 HTTP DELETE 경로를 등록하려면 app.delete()를 사용해야 한다.
  • ECMAScript 6부터는 delete 같은 예약어를 속성 이름으로 사용할 수 있게 된다.

 

2. app.param(fn) 제거

  • app.param(fn)은 app.param(name, fn)의 동작을 수정하기 위해 사용되었으나, Express 5에서는 더 이상 지원되지 않는다.

 

3. 복수형 메서드 이름 수정

  • Express 4에서는 사용 시 경고를 발생시켰던 메서드들이 더 이상 지원되지 않게 되었으며 다음과 같이 수정해야 한다
    • req.acceptsCharset() → req.acceptsCharsets()
    • req.acceptsEncoding() → req.acceptsEncodings()
    • req.acceptsLanguage() → req.acceptsLanguages()

 

4. app.param(name, fn)의 이름 인자 앞의 콜론(:)

  • Express 5는 콜론(:)을 무시하고 이름 인자를 처리한다.

 

5. req.param(name) 제거

// 예전 방식
const userId = req.param('id');

// 직접 인자 찾는 방식
const userId = req.params.id || req.body.id || req.query.id;
  • 이 메서드는 혼란을 야기할 수 있어 제거되었으며, 이제 req.params, req.body, 또는 req.query에서 직접 인자를 찾아야 한다.

 

6. 상태 코드와 응답 메서드의 변경

  • res.json(obj, status) → res.status(status).json(obj)
  • res.jsonp(obj, status) → res.status(status).jsonp(obj)
  • res.redirect(url, status) → res.redirect(status, url)
  • res.redirect('back') → req.get('Referrer') || '/' 사용
  • res.send(body, status) → res.status(status).send(obj)
  • res.send(status) → res.sendStatus(statusCode)로 대체
  • res.sendfile() → res.sendFile()로 변경
 

경로 매칭 구문의 변경 사항

 

경로 매칭 구문은 app.all(), app.use(), app.METHOD(), router.all(), router.METHOD(), router.use() API의 첫 번째 매개변수로 문자열을 제공할 때 사용된다. Express 5에서는 이러한 경로 매칭 구문에 여러 변경 사항이 있다.

 

  1. 와일드카드(*)에 이름을 지정해야 함
    • /* 대신 /*splat와 같이 와일드카드에 이름을 지정해야 한다. 이는 매개변수 :와 동일한 동작을 하도록 일관성을 유지하기 위한 것이다.
  2. 선택적 문자(?)는 더 이상 지원되지 않음
    • 선택적 문자 ?는 더 이상 지원되지 않으며, 대신 {}를 사용하여 대체할 수 있다. 예를 들어, /:file{.:ext}와 같은 형식으로 변경해야 한다.
  3. 정규 표현식 사용 금지
    • 경로에 정규 표현식을 사용하는 것이 더 이상 지원되지 않는다.

      // 변경 전
      app.get('/[discussion|page]/:slug', async (req, res) => {
        res.status(200).send('ok');
      });
      
      // 변경 후
      app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
        res.status(200).send('ok');
      });
  4. 예약된 특수 문자 사용 제한
    • ()[]?+! 등의 문자는 혼란을 피하기 위해 예약된 상태로 사용된다. 이런 문자를 사용할 때는 백슬래시(\)를 사용해 이스케이프해야 한다.
  5. 매개변수 이름에 JavaScript 식별자 사용
    • 이제 매개변수 이름에는 유효한 JavaScript 식별자를 사용하거나 따옴표를 사용해 표시할 수 있다.
    • 예를 들어, :"this"처럼 매개변수 이름을 사용할 수 있다.

 


 

미들웨어 및 핸들러에서 거부된 Promise 처리

 

Express 5에서는 요청 미들웨어와 핸들러에서 반환된 거부된 Promise를 에러 핸들링 미들웨어로 전달하도록 변경되었다. 이는 비동기 함수를 미들웨어와 핸들러로 사용하는 것을 더 쉽게 만든다.

 

  • 비동기 함수에서 에러 처리
    비동기 함수 내에서 에러가 발생하거나 await한 Promise가 거부될 경우, 이러한 에러는 아래와 같이 next(err)를 호출하는 것과 동일하게 자동으로 에러 핸들러로 전달된다.

    app.get('/example', async (req, res, next) => {
      try {
        const result = await someAsyncFunction();
        res.json(result);
      } catch (error) {
        next(error); // 에러 핸들러로 자동 전달
      }
    });



 

추가된 개선 사항

1. res.render()의 비동기 처리 강화

  • 모든 뷰 엔진에 대해 비동기 처리가 강제되어 예상치 못한 버그를 방지한다.

2. 브로틀리(Brotli) 인코딩 지원

  • Express 5는 클라이언트가 지원할 경우 브로틀리 인코딩을 사용해 데이터 압축 성능을 향상시킨다.

 


Express 5 마이그레이션 요약

  1. 제거된 메서드 및 속성을 새로운 메서드로 대체한다.
  2. 경로 매칭 구문 변경 사항에 유의한다.
  3. Promise 기반 비동기 함수 내 에러 처리 방식이 개선되었다.
  4. res.render()는 이제 비동기 방식으로 동작하며, 브로틀리 인코딩이 추가 지원된다.

 

위 요약 내용과 덫붙여 디폴트값이였던 부분이(리턴값 등) 변한게 있는지 주의한다면 4 -> 5 버전으로 마이그레이션 하는데 큰 문제가 발생하지 않을 것이라고 생각한다.

 

 

Express.js 4 -> 5