[Vue.Js] Nuxt.js ··· ②

Nuxt.js 구조 및 라우터(Router) 설정 방법

Posted by ChaelinJ on November 29, 2023

1. 프로젝트의 패키지 구조

Nuxt.js는 Vue.js의 구조를 기반으로 하고 있으며, 각 페이지는 pages 폴더 내에 Vue 파일 형태로 구성됩니다.

.
├── assets/           # 스태틱 에셋 파일 (이미지, 스타일시트 등)
├── components/       # 컴포넌트 파일
├── layouts/          # 레이아웃 파일
├── middleware/       # 미들웨어 파일
├── pages/            # 페이지 파일
├── plugins/          # 플러그인 파일
├── static/           # 정적 파일
├── store/            # Vuex 스토어 파일
├── nuxt.config.js    # Nuxt.js 설정 파일
└── package.json      # 프로젝트 정보 및 의존성 패키지 관리 파일
  • assets/: 이미지, 스타일시트 등과 같은 정적 에셋 파일들이 위치하는 디렉토리입니다.
  • components/: Vue.js 컴포넌트들이 위치하는 디렉토리입니다. 이 디렉토리에 위치한 컴포넌트들은 페이지에서 사용됩니다.
  • layouts/: Nuxt.js 레이아웃 파일들이 위치하는 디렉토리입니다. 레이아웃 파일은 페이지의 공통 구조를 정의하는 파일로, 모든 페이지에서 동일하게 적용됩니다.
  • middleware/: 미들웨어 함수들이 위치하는 디렉토리입니다. 미들웨어 함수는 페이지나 레이아웃을 렌더링하기 전에 실행되는 함수로, 인증, 로깅 등의 작업을 수행합니다.
  • pages/: 실제 페이지 컴포넌트 파일들이 위치하는 디렉토리입니다. 파일 이름에 따라 URL이 자동으로 매핑됩니다.
  • plugins/: Vue.js 플러그인 파일들이 위치하는 디렉토리입니다.
  • static/: 정적 파일들이 위치하는 디렉토리입니다. 빌드 시에는 그대로 복사되어 배포됩니다.
  • store/: Vuex 스토어 파일들이 위치하는 디렉토리입니다.
  • nuxt.config.js: Nuxt.js 설정 파일입니다. 빌드, 서버, 라우팅, 플러그인 등의 설정을 관리합니다.
  • package.json: 프로젝트 정보와 의존성 패키지들이 정의되어 있는 파일입니다. npm 등의 패키지 매니저를 이용하여 프로젝트의 의존성 패키지들을 설치하거나 관리할 수 있습니다.

위는 기본 구조이며, 필요에 따라 utility 디렉토리를 추가해 여러 컴포넌트나 미들웨어, 플러그인 등에서 공통적으로 사용되는 함수나 코드들을 모아놓을 수 있습니다.

middleware는 클라이언트나 서버에서 라우팅하기 전에 실행되는 함수입니다. 이를 사용하면 라우팅하기 전에 인증, 권한 등의 작업을 처리할 수 있습니다. 하지만 모든 프로젝트에서 미들웨어가 필요한 것은 아니므로, 필요에 따라 사용하거나 사용하지 않을 수 있습니다. 따라서 미들웨어 디렉토리가 제외된 경우는 해당 프로젝트에서 미들웨어를 사용하지 않기로 결정했을 때입니다.


2. Nuxt.js Router설정 방법

아래 내용은 공식 문서를 참고해 작성되었습니다.

Nuxt.js는 자동으로 pages 디렉토리 내의 Vue 파일의 파일 트리를 기반으로 vue-router 설정을 생성합니다. 따라서 pages 디렉토리에 .vue 파일을 생성하면 추가적인 설정 없이 기본적인 라우팅이 작동합니다.

2.1. Basic Routes

pages 폴더 안에 라우트와 매칭되는 파일을 생성합니다. 파일 이름이 URL 경로가 됩니다.

pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue

위와 같은 구조는 자동으로 아래와 같이 동작하게 됩니다.

router: {
    routes: [
        {
            name: 'index',
            path: '/',
            component: 'pages/index.vue'
        },
        {
            name: 'user',
            path: '/user',
            component: 'pages/user/index.vue'
        },
        {
            name: 'user-one',
            path: '/user/one',
            component: 'pages/user/one.vue'
        }
    ]
}

Dynamic routes(동적 라우트)나 Nested routes(중첩 라우트)를 생성하거나 Router 속성을 추가로 구성해야 할 수도 있습니다.


2.2. Dynamic Routes

API를 호출하여 사용자 목록이나 블로그 게시물 목록과 같은 라우트의 이름을 미리 알 수 없는 경우가 있습니다. 이러한 경우를 동적 라우트(dynamic routes) 라고 합니다.

동적 라우트를 생성하려면 .vue 파일 이름 또는 디렉토리 이름 앞언더스코어(_)를 추가해야 합니다. 파일 또는 디렉토리 이름은 마음대로 지을 수 있지만 반드시 언더스코어로 시작해야 합니다.

This file tree:

pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue

will automatically generate:

router: {
    routes: [
        {
            name: 'index',
            path: '/',
            component: 'pages/index.vue'
        },
        {
            name: 'users-id',
            path: '/users/:id?',
            component: 'pages/users/_id.vue'
        },
        {
            name: 'slug',
            path: '/:slug',
            component: 'pages/_slug/index.vue'
        },
        {
            name: 'slug-comments',
            path: '/:slug/comments',
            component: 'pages/_slug/comments.vue'
        }
    ]
}

‘users-id’에서 :id?는 선택적이고, 이를 필수로 하기 위해선 index.vue 파일을 users/_id 경로에 만들면 됩니다.

Nuxt.js 2.13 버전 이상에서는 링크 태그(link tags)를 크롤링하여 해당 링크를 기반으로 동적 라우트를 자동으로 생성하는 크롤러(crawler)가 설치되어 있습니다. 그러나 비밀 페이지와 같이 링크되지 않은 페이지가 있는 경우에는 해당 동적 라우트를 수동으로 생성해야 합니다.

2.2.1. Locally Accessing Route Params

로컬 페이지 또는 컴포넌트에서 현재 라우트 파라미터(route parameter)에 접근하려면 this.$route.params.parameterName}를 참조하면 됩니다.

예를 들어, 동적인 사용자 페이지 (users/_id.vue)가 있고 사용자를 로드하거나 정보를 처리하기 위해 id 파라미터에 액세스하려는 경우, 다음과 같이 변수에 접근할 수 있습니다: this.$route.params.id

로컬 페이지 또는 컴포넌트에서 현재 라우트 파라미터(route parameter)에 접근한다는 것은, 현재 페이지의 URL에 있는 동적 파라미터 값을 가져와서 해당 값을 사용하여 페이지를 렌더링하거나 다른 작업을 수행할 수 있다는 것을 의미합니다.

예를 들어, URL이 “/users/1”일 때, “1”은 동적 파라미터 값이며, 로컬 페이지 또는 컴포넌트에서 해당 값을 참조하여 해당 사용자의 정보를 가져올 수 있습니다.


2.3. Nested Routes

Nuxt.js는 vue-router의 자식 라우트(children routes)를 사용하여 중첩된 라우트(nested routes)를 생성할 수 있습니다.

중첩된 라우트의 부모 컴포넌트를 정의하려면, 자식 뷰(children views)를 포함하는 디렉토리와 같은 이름을 가진 Vue 파일을 만들어야 합니다.

This file tree:

pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue

will automatically generate:

router: {
    routes: [
        {
            path: '/users',
            component: 'pages/users.vue',
            children: [
                {
                    path: '',
                    component: 'pages/users/index.vue',
                    name: 'users'
                },
                {
                    path: ':id',
                    component: 'pages/users/_id.vue',
                    name: 'users-id'
                }
            ]
        }
    ]
}

부모 컴포넌트(.vue 파일) 내에서 NuxtChild 컴포넌트를 포함해주는 것을 잊지 마세요.

Nuxt에서 중첩된 라우트를 사용하려면, 부모 라우트를 정의하고 그 안에 자식 라우트를 추가해야 합니다. 이때, 자식 컴포넌트를 렌더링하려면 NuxtChild 컴포넌트를 사용해야 합니다. NuxtChild 컴포넌트는 자식 라우트를 렌더링하고, 중첩된 라우트를 효율적으로 처리하는데 도움을 줍니다.

<template>
  <div>
    <h1>Parent Component</h1>
    <NuxtChild />
  </div>
</template>

위 코드에서 NuxtChild는 부모 컴포넌트가 가지고 있는 중첩된 자식 라우트를 렌더링하는데 사용됩니다. 이를 통해 중첩된 라우트를 효율적으로 처리할 수 있습니다.


2.4.Unknown Dynamic Nested Routes

URL 구조의 Depth를 알 수 없을 때, _.vue를 사용해 동적으로 중첩된 경로를 사용할 수 있습니다. 이는 특정한 경로에 부합하지 않는 요청을 처리합니다.

This file tree:

pages/
--| people/
-----| _id.vue
-----| index.vue
--| _.vue
--| index.vue

Will handle requests like this:

/ -> index.vue
/people -> people/index.vue
/people/123 -> people/_id.vue
/about -> _.vue
/about/careers -> _.vue
/about/careers/chicago -> _.vue

404 Page 처리 로직에 활용할 수 있습니다.


2.5. Extending the Router

2.5.1. The router Property

Nuxt router(vue-router)를 커스터마이징 할 수 있습니다.

export default {
    router: {
        // customize the Nuxt router
    }
}

2.5.2. Base

기본 URL을 설정할 수 있습니다. 전체 경로가 특정 경로 아래에서 제공되는 경우 설정합니다.

export default {
    router: {
        base: '/app/'    // Default: '/'
    }
}

2.5.3. extendRoutes

Nuxt에서 생성된 Route를 확장하고 싶을 때 extendRoutes 옵션을 사용할 수 있습니다.

export default {
    router: {
        extendRoutes(routes, resolve) {
            routes.push({
                name: 'custom',
                path: '*',
                component: resolve(__dirname, 'pages/404.vue')
            })
        }
    }
}

2.5.3.1. sortRoutes

라우트 정의 객체의 배열을 인자로 받아 해당 라우트들을 정렬하여 라우트의 순서를 변경하는 메소드입니다. 이 메소드를 사용하면 페이지를 라우팅할 때 라우트의 우선순위를 변경할 수 있습니다.

라우트 정의 객체를 정렬하는 것은 라우트 매칭을 더 빠르게 처리할 수 있도록 해줍니다. 라우트 정의 객체가 정렬되면 일치하는 경로가 더 빨리 찾아지므로 라우팅 성능이 향상됩니다. 정렬은 경로의 길이를 기준으로 이루어지며, 길이가 같은 경우 정규식 표현식이 있는 경로가 우선적으로 정렬됩니다. (라우팅 경로의 길이를 기준으로 하는 이유는 일반적으로 경로의 길이가 더 짧은 경로가 우선순위가 높기 때문입니다.)

import { sortRoutes } from '@nuxt/utils'
export default {
    router: {
    extendRoutes(routes, resolve) {
        // Add some routes here ...
    
          // and then sort them
          sortRoutes(routes)
        }
    }
}

2.5.3.2. chunkNames

명명된 컴포넌트의 chunkNames를 해당 컴포넌트와 함께 추가해야 합니다.

chunkName: Nuxt.js에서 code splitting을 수행할 때 동적으로 생성되는 JavaScript 파일들의 이름을 설정하는데 사용됩니다. 라우팅된 페이지와 관련된 JavaScript 파일의 이름을 설정함으로써 라우팅된 각 페이지는 자신만의 JavaScript 파일을 가지게 되어 페이지 간 이동 시 로드되는 JavaScript 파일의 크기를 줄일 수 있습니다.

export default {
    router: {
        extendRoutes(routes, resolve) {
            routes.push({
                path: '/users/:id',
                components: {
                    default: resolve(__dirname, 'pages/users'), // or routes[index].component
                    modal: resolve(__dirname, 'components/modal.vue')
                },
                chunkNames: {
                    modal: 'components/modal'
                }
            })
        }
    }
}

2.5.4. 기타 옵션

2.5.4.1. fallback

브라우저가 history.pushState를 지원하지 않을 때, mode 옵션을 history로 설정해도 hash 모드로 자동으로 fallback 하도록 설정하는 옵션입니다.

2.5.4.2. linkActiveClass

활성화된 링크에 대한 클래스 이름을 설정하는 Nuxt.js 라우터 옵션입니다. 예를 들어, 라우터 링크가 활성화되면 클래스 이름 active를 설정하려면 다음과 같이 사용할 수 있습니다.

export default {
    router: {
        linkActiveClass: 'active'
    }
}

위 문서는 Chat GPT 응답과 공식 사이트 문서 기반으로 작성되었습니다.


감사합니다.

Text by Chaelin. Photographs by Chaelin, Unsplash.