kokoball의 devlog
article thumbnail
728x90

 

 

요즘 채용 공고를 보면 쓰지 않는 곳을 찾기 힘들 정도로 Next.js에 대한 인기가 대단합니다.


이번글은 왜 Next.js가 폴더 기반 라우팅을 선택한 이유를 파악해 보려고 합니다.

 

크게 세 가지 목차로 구성하여 살펴보겠습니다.

  1. 라우팅이란? + 라우팅 등장 배경
  2. 다양한 라우팅 방식과 그 활용법
  3. Next.js가 선택한 라우팅 방법과 선택의 이유 및 장점.

 

라우팅이란? + 라우팅 등장 배경

라우팅은 사용자가 애플리케이션 내에서 특정 URL을 요청할 때, 그 요청에 대응하는 적절한 콘텐츠나 페이지를 제공하는 방식입니다.

 

네트워크나 애플리케이션에서 경로(path)를 결정하고, 해당 경로에 따라 요청을 적절한 리소스나 처리기로 전달하는데,

여기서 주의 깊게 봐야하는 부분은 path를 결정하는 부분입니다.

 

CSR 방식은 div 태그 하나에 JS 번들을 응답하는 방식이며 일반적으로 싱글 페이지 애플리케이션인 경우가 많지만, 

SSR 같은 경우에는 보통 여러 페이지로 구성되어 있습니다.

 

이러한 차이가 발생하는 이유는 렌더링 하는 위치가 클라이언트일 경우에는 서버로 요청하는 엔드포인트(path)가 단 하나일 수밖에 없습니다. (물론 CSR 방식도 여러 방식을 통해 여러 개의 path를 만들 수 있습니다)

 

반면에 SSR 같은 경우 페이지가 여러개가 되면서 path가 여러 개로 나뉘어 있습니다.

그렇기에 여러개의 선택지 중에서 원하는 path를 선택하고 페이지에 접속했을 때 각각의 응답을 다르게 하는 라우팅이 등장하게 됩니다.

 

다양한 Routing 방식들

1. 명시적 라우팅

명시적 라우팅은 라우팅 테이블이나 라우팅 설정 파일에서 URL 경로와 해당 경로를 처리할 함수 또는 컴포넌트를 명시적으로 정의하는 라우팅 방식입니다. 이는 라우팅 규칙을 코드로 명확히 표현하여, 각 경로가 어떤 처리를 해야 하는지 명확히 알 수 있다는 장점이 있습니다.

 

대표적으로 CRA에서 많이 사용하는 React Router이 있습니다.

// React Router 예시

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/contact" component={Contact} />
    </Switch>
  </Router>
);

export default App;

 

2. 코드 기반 라우팅

코드 기반 라우팅은 애플리케이션 내에서 라우팅 규칙을 코드로 명식적으로 정의하는 라우팅 방식입니다.

이는 라우팅 규칙이 파일 시스템의 구조에 의해 결정되는 폴더 기반 라우팅과는 대조적이며, 코드 기반 라우팅에서는 URL 경로와 해당 경로를 처리할 함수나 컴포넌트를 코드로 명시적으로 정의합니다.

 

대표적으로 node.js 기반 Express가 있습니다.

path를 스트링 형태로 전달하고 말 그대로 app(서버) 에서 get(HTTP 메서드) 이런 식으로 처리한 다음에 path name을 직접 할당해서 코드를 기반으로 라우팅 해주는 방식입니다.

// 코드 기반 라우팅 예시
const express = require('express');
const app = express();

// 라우팅 설정
app.get('/', (req, res) => {
  res.send('Home Page');
});

app.get('/about', (req, res) => {
  res.send('About Page');
});

app.get('/contact', (req, res) => {
  res.send('Contact Page');
});

// 서버 실행
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

 

 

3. 데코레이터 기반 라우팅 방식

데코레이터 기반 라우팅은 데코레이터(또는 어노테이션)를 사용하여 클래스나 메서드에 라우팅 정보를 추가하는 방식입니다.

이 방식은 주로 TS나 Python과 같은 언어에서 사용되며, 데코레이터를 통해 라우팅 설정을 직관적으로 관리할 수 있습니다.

 

대표적으로 NextJS가 있습니다.

import { Controller, Get, Param } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get()
  findAll(): string {
    return 'This action returns all users';
  }

  @Get(':id')
  findOne(@Param('id') id: string): string {
    return `This action returns user with id ${id}`;
  }
}

 

NestJS는 MVC 패턴을 따르며, 특히 controller에서 데코레이터 기반 라우팅을 사용하여 라우팅 설정을 명확히 정의합니다.

컨트롤러는 요청을 처리하고 응답을 반환하는 역할을 하며, 예시에서 findAll 이라는 메서드가 문자열을 반환하고, 이 메서드에 데코레이터를 사용하여 라우팅 정보를 추가하는 방식입니다.

 

4. 파일 구조 기반 라우팅 (Next.js)

파일 구조 라우팅은 파일 시스템의 디렉토리 구조를 기반으로 라우트를 자동으로 설정하는 방식입니다.

 

지금의 app 폴더 방식 이전에는 pages 폴더 방식의 라우팅을 사용했었습니다.

이 방식은 'pages' 폴더 내의 파일이 URL 경로와 직접적으로 매핑되어 매우 직관적이라는 장점이 있었습니다.

예시) 'pages/about.tsx' 파일이 있을 때, 'localhost:3000/about'으로 요청하면 about.tsx 파일이 요청됩니다.

 

새로운 'app' 폴더 방식은 각 페이지마다 폴더를 만들고, 그 안에 'page.tsx' 파일을 두어 라우팅을 설정합니다

예시) 'app/about/page.tsx' 파일을 만들면, 'localhost:3000/about'으로 요청할 때 이 파일이 응답됩니다.

 

'pages' 폴더 방식은 URL 경로와 파일 시스템 구조가 일치하여 직관적이었지만, 확장성과 유지보수성 측면에서 한계가 있었습니다.

 

Next.js 가 폴더 기반 라우팅을 선택한 이유 및 장점

그렇기에 Next.js는 'app' 폴더 방식이라는 새로운 라우팅을 도입하게 됩니다.

이는 다양한 페이지 관련 파일을 함께 관리할 수 있어 더 구조적으로 확장성 있는 개발이 가능하다는 장점이 있습니다.

 

File Conventions

 

사진에서 확인할 수 있듯이 error, loading, layout 등 프런트엔드 개발자들이 많이 사용하는 것들을 좀 더 쉽게 사용하기 위해 Next.js에서 추상화해서 라우팅 기능에 포함시켰기 때문입니다. 

 

아래 내용으로 장점을 정리할 수 있습니다.

 

파일 구조의 라우팅 장점

 

1. 직관적

  • URL 경로와 파일 시스템 구조의 일치: 파일과 디렉토리의 구조가 곧 URL 경로가 되기 때문에, 직관적으로 라우트를 정의 이해 가능
  • 쉽게 파악 가능한 경로: 프로젝트의 디렉토리 구조를 보면 각 경로가 어떤 역할을 하는지 쉽게 파악 가능

2. 자동 코드 스플리팅

  • 효율적인 로딩: 파일 구조 라우팅은 각 경로마다 자동으로 코드 스플리팅을 수행. 이를 통해 사용자가 접근하는 경로에 해당하는 코드만 로드되어, 초기 로딩 속도가 빠르다.
  • 경로별 응답 최적화: 분리된 경로마다 필요한 코드만 응답하여, 리소스를 효율적으로 사용 가능
  • 자동 처리: 개발자가 직접 코드 스플리팅을 설정할 필요 없이, 파일 구조에 따라 자동으로 코드 스플리팅

3. 콜로케이션 원칙

  • 관련 코드의 모듈화: 같은 맥락에서 사용되는 코드들을 같은 위치에 두는 콜로케이션 원칙을 따른다. 페이지 컴포넌트와 해당 페이지에서 사용하는 스타일, 유틸리티 함수 등을 같은 폴더에 두어 관리 가능
  • 유지보수 용이성: 관련 코드가 함께 위치해 있으므로, 수정이 필요할 때 한 곳에서 모든 관련 파일을 쉽게 찾고 수정 가능
  • 명확한 프로젝트 구조: 프로젝트의 구조가 명확해지고, 개발자 간의 협업 시에도 코드베이스를 쉽게 이해하고 관리 가능

 

 

 

 

 

 

https://nextjs.org/docs/getting-started/project-structure#metadata-file-conventions

 

Getting Started: Project Structure | Next.js

A list of folders and files conventions in a Next.js project

nextjs.org

 

728x90
profile

kokoball의 devlog

@kokoball-dev

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!