티스토리 뷰

 
 
 
 
고급 프로젝트를 앞두고 팀원들과 기술 스터디를 진행 중인데, 이번 주제는 Plain React App이 아닌 Next.js를 프로젝트에서 사용해야하는 이유였다.
 
그 과정에서 프레임워크와 라이브러리의 차이를 공부하게 되어서 정리해보려 한다.
 
 
 

라이브러리와 프레임워크 쉽게 이해하기


나는 헷갈리는 개념은 비유를 통해서 이해하는 것을 좋아하는데, 프레임워크와 라이브러리의 차이 또한 집이라는 비유를 통해 알아보고자 한다.
 
먼저 라이브러리는 집을 설계부터 건축까지 모든 것을 도맡아 하는 것과 비슷하다. 따라서 내가 원하는 대로 집을 설계할 수 있고 어디를 안방으로 할 지 어디를 거실로 할 지와 같이 각 방을 원하는 대로 배치할 수 있다.
 
반면 프레임워크는 새 집을 구입하는 것과 같다. 따라서 집을 직접 설계하지 못하는 것은 물론이고 안방, 거실 등 방의 배치가 이미 고정되어 있어 원하는대로 변경할 수 없다.
 
이 비유를 좀 더 확장해서 설명해보자면, 라이브러리를 사용할 때 우리는 건축가 역할을 맡게되고, 적절한 도구를 모아 집을 직접 설계하고 지어야 한다. 따라서 이 과정은 집을 마음대로 지을 수 있는 자유가 있지만 동시에 모든 설계와 건축의 책임도 따른다고 볼 수 있다.

 
 
 
 

제어의 역전(Inversion of Control)


그렇다면 둘의 기술적인 차이는 무엇일까?
이를 알기 위해서는 제어의 역전(Inversion Of Control) 이라는 개념을 알아야한다.

In software engineering, inversion of control (IoC) is a design principle in which custom-written portions of a computer program receive the flow of control from external source. - wikipedia
소프트웨어에서 제어의 역전이란 개발자가 작성한 객체나 메서드의 제어를 개발자가 아니라 외부에 위임하는 설계 원칙을 말한다.

 
 
 

제어 역전은 이미 우리가 흔하게 쓰고 있는 개념이며 JS Arraymap, forEach, filter, reduce가 대표적인 예이다.

// 일반 filter
const dogs = filterDogs(animals)

// 제어역전 filter
const dogs = animals.filter(animal => animal.species === 'dog')

 
위 코드를 보면 일반적인 filter 함수는 강아지를 필터링한다는 것을 명시적으로 나타내며 선언적인 코드의 장점을 갖게 된다. 하지만 필터링 로직이 조금이라도 변경될 경우 함수에 option 객체를 추가하는 등 기존 로직을 수정해야 한다.
 
반면 제어 역전이 적용된 filter 메서드는 필터링 기능만 제공하고, 구체적인 필터링 방법은 사용자에게 위임한다. 따라서 필터링 로직에 변화가 생겨도 기존 filter 메서드는 수정 없이 그대로 사용할 수 있다.

React에서 자주 사용되는  합성 컴포넌트 패턴(Compound Components Pattern)이나 Render Props 역시 제어 역전의 원리를 적용한 디자인 패턴이다. 이 패턴들은 컴포넌트의 렌더링 로직을 사용자에게 위임함으로써 유연성과 재사용성을 높여주는 장점이 있다.

 
 
 
 
 

프레임워크와 라이브러리

 
 

이제 React.js(라이브러리)와 Next.js(프레임워크)를 사용한 예시를 살펴보자.
 
먼저 라이브러리는 단순하게 활용할 수 있는 도구들의 집합이기 때문에 프로그램 실행 흐름의 주도권을 라이브러리가 가지고 있다. React.js 의 라우트 기능을 예시로 들자면, 개발자가 모든 라우팅 로직을 원하는 위치파일명으로 자유롭게 정의할 수 있다.

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/users/:id" element={<User />} />
      </Routes>
    </BrowserRouter>
  );
}

 
 
 
하지만 프레임워크는 실행의 주도권이 프레임워크 자체에있다.
 
따라서 프레임워크는 미리 정해진 구조를 제공하고 개발자가 그 안에서 코드를 작성하는 방식이다.  코드를 작성하면 프레임워크는 자체적인 제어 흐름 내에서 개발자의 코드를 호출해서 애플리케이션을 실행한다.
 
Next.js는 React.js와 달리 파일 기반 라우팅이기 때문에 pages 디렉토리의 파일 구조에 따라 자동으로 라우트를 생성한다.
 
이 방식은 개발자가 명시적으로 라우팅 구조를 정의할 필요가 없다. 따라서 개발자는 라우팅 로직 구현보다는 각 페이지의 내용에 집중할 수 있게 된다.

my-project/
│
├── pages/
│   ├── _app.js
│   ├── _document.js
│   ├── index.js
│   ├── about.js
│   └── posts/
│       ├── index.js
│       └── [id].js
...

 
 
 


 
이번 스터디를 진행하면서 라이브러리로 자유롭게 설계할 것인지, 아니면 프레임워크의 구조 안에서 효율적으로 개발할 것인지에 대해서 팀원들과 얘기를 나누면서 각각의 장단점을 더 깊이 이해할 수 있었다.
 
라이브러리는 프로젝트를 세밀하게 제어할 수 있는 자유를 제공하지만, 그만큼 많은 의사 결정을 개발자가 내려야 한다. 반면 프레임워크는 최적화된 기능을 제공하기 때문에 개발 속도를 높여주고 일관된 코드 베이스 유지에 도움을 준다.
 
이러한 고려 끝에 우리 팀은 이번 프로젝트에 React.js(라이브러리) 대신 Next.js(프레임워크)를 선택했다.
 
서버 사이드 렌더링, 이미지 최적화, 파일 기반 라우팅 등 Next.js가 제공하는 기능들이 우리 프로젝트의 요구사항과 잘 맞았기 때문이다. 특히 프로젝트에서 이미지가 많이 사용되기 때문에 최적화가 필수적인데 Next.js의 이미지 최적화 기능이 프로젝트의 이점으로 작용할 것 같다.
 
더불어 프로젝트 일정을 고려했을 때 라이브러리보다 프레임워크를 사용하는 것이 더 효율적일 것이라고 판단해서 Next.js를 선택했다. 이번 프로젝트도 화이팅💪

'Tips > IT 상식' 카테고리의 다른 글

[IT 상식] CORS(Cross Origin Resource Sharing) 개념정리  (0) 2024.06.17
버퍼(Buffer)란?  (3) 2024.04.08
HTTP 멱등성이란?  (1) 2024.04.06
하드코딩이란?  (0) 2024.04.02