|
| 1 | +--- |
| 2 | +sidebar_position: 10 |
| 3 | +--- |
| 4 | +# NextJS와 함께 사용하기 |
| 5 | + |
| 6 | +NextJS에서도 FSD 아키텍처를 적용할 수 있지만, NextJS의 기본 프로젝트 구조와 FSD 원칙 간에 몇 가지 충돌이 발생할 수 있습니다. |
| 7 | + |
| 8 | +#### 주요 차이점 |
| 9 | + |
| 10 | +- NextJS의 `pages` 폴더와 FSD의 `pages` layer 간의 이름 충돌 |
| 11 | +- NextJS 13 이전 버전에서는 FSD의 `app` layer에 해당하는 명확한 폴더 구조가 없음 |
| 12 | + |
| 13 | +## FSD와 NextJS의 `pages` layer 충돌 {#pages-conflict} |
| 14 | + |
| 15 | +NextJS는 파일 시스템 기반 라우팅을 위해 `pages` 폴더를 사용하며, 해당 폴더 내 파일이 자동으로 라우트에 매핑됩니다. |
| 16 | +그러나 이 방식은 FSD의 `pages layer 개념과 충돌`하며, 특히 FSD에서 권장하는 평탄한(flat) slice 구조를 NextJS의 중첩 라우팅 방식에서 유지하기 어려운 문제가 있습니다. |
| 17 | + |
| 18 | +### NextJS의 `pages` 폴더를 루트 폴더로 이동 (권장) |
| 19 | + |
| 20 | +가장 권장되는 방법은 NextJS의 `pages` 폴더를 프로젝트 루트에 배치하고, FSD 구조는 `src` 폴더 내에서 유지하는 것입니다. |
| 21 | +이렇게 하면 NextJS의 라우팅 시스템을 그대로 활용하면서도 FSD 아키텍처를 온전히 적용할 수 있습니다. |
| 22 | + |
| 23 | +```sh |
| 24 | +├── pages # NextJS의 라우팅 시스템용 폴더 |
| 25 | +├── src |
| 26 | +│ ├── app |
| 27 | +│ ├── entities |
| 28 | +│ ├── features |
| 29 | +│ ├── pages # FSD의 pages layer |
| 30 | +│ ├── shared |
| 31 | +│ ├── widgets |
| 32 | +``` |
| 33 | + |
| 34 | +### FSD 구조 내 `pages` 폴더 이름 변경하기 |
| 35 | + |
| 36 | +다른 방법으로는 FSD의 `pages` layer 이름을 변경하여 NextJS의 `pages` 폴더와의 충돌을 방지하는 것입니다. |
| 37 | +예를 들어, `pages`를 `views`로 변경하면 NextJS의 라우팅 시스템과 FSD 구조를 동시에 유지할 수 있습니다. |
| 38 | + |
| 39 | +```sh |
| 40 | +├── app |
| 41 | +├── entities |
| 42 | +├── features |
| 43 | +├── pages # NextJS 라우팅용 폴더 |
| 44 | +├── views # 이름이 변경된 FSD pages layer |
| 45 | +├── shared |
| 46 | +├── widgets |
| 47 | +``` |
| 48 | + |
| 49 | +폴더 이름을 변경한 경우, 프로젝트의 README나 내부 문서에 이를 명확하게 기록하는 것이 중요합니다. |
| 50 | +이러한 변경 사항은 ["프로젝트 지식"][project-knowledge]의 일부로 문서화하여 팀원들이 쉽게 이해할 수 있도록 해야 합니다. |
| 51 | + |
| 52 | +## NextJS에서 FSD의 `app` layer 구현하기 {#app-absence} |
| 53 | + |
| 54 | +NextJS 13 이전 버전에서는 FSD의 `app` layer에 해당하는 명확한 폴더 구조가 제공되지 않았습니다. |
| 55 | +대신 `pages/_app.tsx` 파일이 애플리케이션의 진입점 역할을 하며, 전역 상태 및 레이아웃을 관리합니다. |
| 56 | + |
| 57 | +### `pages/_app.tsx`에 app layer 기능 통합하기 |
| 58 | + |
| 59 | +FSD의 `app` layer 개념을 NextJS에 적용하려면, `app` 폴더에 애플리케이션의 프로바이더와 레이아웃 구성을 정의한 후, 이를 `pages/_app.tsx`에서 가져와 사용할 수 있습니다. |
| 60 | + |
| 61 | +```tsx |
| 62 | +// app/providers/index.tsx |
| 63 | + |
| 64 | +const App = ({ Component, pageProps }: AppProps) => { |
| 65 | + return ( |
| 66 | + <Provider1> |
| 67 | + <Provider2> |
| 68 | + <BaseLayout> |
| 69 | + <Component {...pageProps} /> |
| 70 | + </BaseLayout> |
| 71 | + </Provider2> |
| 72 | + </Provider1> |
| 73 | + ); |
| 74 | +}; |
| 75 | + |
| 76 | +export default App; |
| 77 | +``` |
| 78 | + |
| 79 | +그다음, `pages/_app.tsx`에서 `App` 컴포넌트를 가져와 NextJS의 진입점으로 설정하고, 전역 스타일을 로드할 수 있습니다. |
| 80 | + |
| 81 | +```tsx |
| 82 | +// pages/_app.tsx |
| 83 | + |
| 84 | +import 'app/styles/index.scss' |
| 85 | + |
| 86 | +export { default } from 'app/providers'; |
| 87 | +``` |
| 88 | + |
| 89 | +## App Router 사용하기 {#app-router} |
| 90 | + |
| 91 | +NextJS 13.4 버전부터 정식 지원되는 App Router는 `pages` 폴더 대신 `app` 폴더를 통해 라우팅을 구현합니다. |
| 92 | +FSD 아키텍처를 App Router와 함께 사용할 때도 앞서 설명한 것과 유사한 방식으로 구조를 설정할 수 있습니다. |
| 93 | + |
| 94 | +NextJS의 app 폴더를 프로젝트 루트에 배치하고, FSD의 app layer는 `src` 폴더 내에서 유지하는 것이 좋습니다. |
| 95 | +또한, App Router와 Pages Router는 함께 사용할 수 있으므로, 필요에 따라 두 라우팅 시스템을 모두 활용할 수도 있습니다. |
| 96 | + |
| 97 | +``` |
| 98 | +├── app # NextJS의 App Router용 폴더 |
| 99 | +├── pages # NextJS의 Pages Router용 폴더 (선택적) |
| 100 | +│ ├── README.md # 폴더의 용도 설명 |
| 101 | +├── src |
| 102 | +│ ├── app # FSD의 app layer |
| 103 | +│ ├── entities |
| 104 | +│ ├── features |
| 105 | +│ ├── pages # FSD의 pages layer |
| 106 | +│ ├── shared |
| 107 | +│ ├── widgets |
| 108 | +``` |
| 109 | + |
| 110 | +[][ext-app-router-stackblitz] |
| 111 | + |
| 112 | +## 참고 자료 {#see-also} |
| 113 | + |
| 114 | +- [(스레드) NextJS의 pages 폴더에 대한 토론](https://t.me/feature_sliced/3623) |
| 115 | + |
| 116 | +[project-knowledge]: /docs/about/understanding/knowledge-types |
| 117 | +[ext-app-router-stackblitz]: https://stackblitz.com/edit/stackblitz-starters-aiez55?file=README.md |
| 118 | + |
| 119 | + |
0 commit comments