개발자공부일기

Next.js에서 Node.js와 Edge환경 본문

Language/Javascript

Next.js에서 Node.js와 Edge환경

JavaCPP 2025. 8. 1. 22:47

최근 프로젝트에서 Middleware를 통해 인증 로직을 추가하던 중,  문제가 발생했다.
JWT 토큰을 검증하기 위해 jsonwebtoken 라이브러리를 사용했는데, 실행 시 "Edge 환경에서는 지원되지 않는다"는 에러가 나온 것이다.

분명히 환경을 바꾼 적이 없는데, 왜 Edge 환경에서 실행되는 걸까?
이번 글에서는 Next.js에서 Node.js와 Edge 환경이 각각 어디서 실행되고, 어떤 차이가 있는지를 정리해본다.


Next.js 안의 실행 영역

Next.js 프로젝트는 단순히 서버에서만 돌아가는 게 아니다. 내부적으로 여러 실행 영역이 나뉘어 있고, 각각의 영역이 다른 런타임을 사용한다. 크게 네 가지로 나눌 수 있다.

  1. 브라우저(Client)
    • 사용자의 PC나 스마트폰에서 실행되는 부분
    • React 클라이언트 컴포넌트
    • Node.js나 Edge와 직접적인 관련은 없음
  2. 빌드 타임(Build Time)
    • next build 시 실행되는 코드
    • 항상 Node.js 환경에서 실행됨
  3. 서버(Server Components & API Routes)
    • 서버 컴포넌트 렌더링, API Routes 실행
    • 기본적으로 Node.js 런타임에서 실행되지만, Edge 런타임을 명시적으로 선택할 수 있음
  4. 미들웨어(Middleware)
    • 요청(Request)이 들어오자마자 실행되는 전처리 단계
    • 기본적으로 Edge 런타임에서 실행됨

Node.js Runtime

Node.js 런타임은 우리가 익숙한 서버 환경이다. Next.js의 API Route나 서버 컴포넌트는 기본적으로 Node.js 런타임에서 실행된다.

특징

  • Node.js API 지원
    fs, path, crypto 같은 Node.js 모듈 사용 가능
  • 라이브러리 호환성 높음
    Prisma, bcrypt, jsonwebtoken 등 대부분의 라이브러리 사용 가능
  • 파일 시스템 접근 가능
    파일 업로드/다운로드 처리 가능
  • 긴 실행 시간 허용
    복잡한 DB 쿼리나 무거운 연산 처리에 적합

한계

  • 서버가 배포된 리전에 따라 지연(latency)이 생김
  • Edge에 비해 초기 응답 속도가 다소 느림

Edge Runtime

Edge 런타임은 V8 Isolate 기반으로 동작하며, Cloudflare Workers와 유사한 구조를 갖고 있다.
Next.js에서 export const runtime = "edge";라고 선언하거나, middleware.ts / middleware.js 를 작성하면 Edge 환경에서 실행된다.

특징

  • 전 세계 엣지 서버에서 실행
    사용자와 가까운 지역에서 실행되어 지연을 최소화
  • 빠른 응답
    인증, 리다이렉트 같은 가벼운 작업에 적합
  • Cold Start 거의 없음
    서버리스 환경에서 즉시 응답 가능

제약

  • Node.js API 사용 불가
    fs, path, net 등 불가능
  • 라이브러리 제약
    Prisma, bcrypt, jsonwebtoken 등 Node 전용 라이브러리 사용 불가
  • Web API만 사용 가능
    예: JWT 검증은 crypto.subtle 같은 Web Crypto API 활용 필요
  • 파일 시스템 접근 불가
    업로드/다운로드는 외부 스토리지(S3 등)에 의존해야 함

Node.js와 Edge 비교

 

구분  Node.js Runtime Edge Runtime
실행 위치 서버 (리전 단위) 전 세계 엣지 서버
속도 상대적으로 느림 빠름 (저지연)
라이브러리 호환성 거의 모든 Node 패키지 사용 가능 Web API 기반만 가능
파일 접근 가능 (fs) 불가
DB 접근 (Prisma 등) 가능 불가
JWT 검증 jsonwebtoken 가능 Web Crypto API 필요
권장 작업 DB 연동, 파일 업로드, 무거운 연산 인증, 리다이렉트, 캐싱

왜 Middleware는 Edge 환경일까?

Next.js의 middleware.ts는 Edge Runtime이 기본이다.
이는 미들웨어가 요청 초기에 빠르게 실행되어야 하기 때문이다.

  • 로그인 여부 확인
  • 특정 페이지 접근 제한
  • 리다이렉트 처리

이런 작업은 무거운 DB 쿼리보다는 빠른 응답이 우선이므로 Edge 환경이 적합하다.

따라서 jsonwebtoken처럼 Node.js 전용 라이브러리는 사용할 수 없고, jose 패키지 같은 Edge 호환 라이브러리를 선택해야 한다.


결론

처음에는 환경을 따로 바꾼 적이 없는데 Edge 에러가 난 이유는, Next.js의 Middleware는 기본적으로 Edge Runtime에서 실행되기 때문이다.
Node.js와 Edge는 각각의 장단점이 있으므로, 작업 특성에 맞게 선택해야 한다.

  • DB 쿼리, 파일 업로드, 무거운 연산 → Node.js Runtime
  • JWT 검증, 인증, 리다이렉트, 글로벌 캐싱 → Edge Runtime

 

처음엔 그저 빠르게 오류를 지우고 싶어서 진행중인 프로젝트의 미들웨어를 node환경으로 명시할까 했지만 알아보니까 그렇게

해버리면 미들웨어의 장점이 다 사라져서 그냥 단순히 토큰의 유무만 검사하고 토큰이 없다면 로그인이 되어있지 않았음을 의미한다. 로그인이 되어있지 않았다면 로그인 페이지로 리다이렉트 하고 돌아올 경로를 저장했다가 로그인 할때 꺼내쓰도록 했다.

 

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

const PROTECTED_PATHS = [
  "/dashboard",
  "/community/boards",
  "/profile",
  "/settings",
];

export function middleware(req: NextRequest) {
  const token = req.cookies.get("token")?.value; // 쿠키에서 로그인 토큰 확인
  const { pathname, search } = req.nextUrl;

  const isProtected = PROTECTED_PATHS.some((path) => pathname.startsWith(path));

  if (isProtected && !token) {
    // 로그인 안 했으면 로그인 페이지로
    const loginUrl = new URL("/signin", req.url);
    console.log("미들웨어를 들어옴");
    // 로그인 후 돌아올 경로를 쿼리에 저장
    loginUrl.searchParams.set("redirect", pathname + search);

    return NextResponse.redirect(loginUrl);
  }

  return NextResponse.next();
}

export const config = {
  matcher: [
    "/dashboard/:path*",
    "/community/boards/:path*",
    "/profile/:path*",
    "/settings/:path*",
  ],
};

 

로그인을 안한채로 로그인이 필요한 페이지에 들어갔더니 "미들웨어를 들어옴"이란 로그가 정상적으로 출력되었다.

'Language > Javascript' 카테고리의 다른 글

Node.js의 Libuv 라이브러리  (0) 2025.02.26
Node.js의 이벤트 루프  (0) 2025.02.20
JWT  (0) 2025.02.11
깊은 복사와 얕은 복사  (0) 2025.02.10
Express  (0) 2025.02.07