출시·고도화 중
Vue.js · Nuxt 안내서 · 2/6
Vue 프로젝트와 Nuxt 프로젝트는 폴더 구성이 다릅니다. Vue(create-vue)는 Vite 프로젝트의 관례를 따르고 진입점을 직접 작성하는 반면, Nuxt는 정해진 폴더 이름에 의미가 있어서 파일을 알맞은 곳에 두기만 하면 라우트·컴포넌트·서버 API로 인식됩니다. 이 장에서는 두 구조와 주요 설정 파일을 살펴봅니다.
TypeScript, Router, Pinia, Vitest를 골라 만든 프로젝트는 대략 다음과 같습니다.
my-vue-app/
├── index.html # Vite의 진입 HTML
├── public/ # 그대로 복사되는 정적 파일
├── src/
│ ├── main.ts # 앱 생성과 플러그인 등록
│ ├── App.vue # 최상위 컴포넌트
│ ├── assets/ # 빌드 과정을 거치는 CSS·이미지
│ ├── components/ # 재사용 컴포넌트
│ ├── views/ # 라우트에 연결되는 화면 컴포넌트
│ ├── router/index.ts # Vue Router 설정
│ └── stores/ # Pinia 스토어
├── vite.config.ts
├── tsconfig.json
└── package.jsonviews/와 components/는 관례일 뿐 강제는 아니지만, 화면 단위 컴포넌트와 재사용 부품을 나눠 두면 프로젝트가 커져도 찾기 쉽습니다.
Vue 앱은 createApp으로 만들고, 플러그인을 등록한 뒤 index.html의 요소에 마운트합니다.
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import router from "./router";
import "./assets/main.css";
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.mount("#app");라우트는 src/router/index.ts에서 직접 선언합니다. 자주 쓰지 않는 화면은 () => import(...)로 지연 로딩하면 첫 번들이 작아집니다.
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{ path: "/", name: "home", component: HomeView },
{ path: "/about", name: "about", component: () => import("../views/AboutView.vue") },
],
});
export default router;Vite 설정에는 Vue 플러그인과 경로 별칭이 들어 있습니다. @는 src 폴더를 가리키므로 import Foo from "@/components/Foo.vue"처럼 쓸 수 있습니다.
import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
resolve: {
alias: { "@": fileURLToPath(new URL("./src", import.meta.url)) },
},
});환경 변수는 프로젝트 루트의 .env 파일에 두며, VITE_로 시작하는 이름만 import.meta.env.VITE_API_URL처럼 클라이언트 코드에 노출됩니다.
Nuxt는 폴더 이름이 곧 규칙입니다. 최근 Nuxt는 애플리케이션 코드를 app/ 폴더 아래에 두고, 서버 코드는 루트의 server/에 둡니다. 예전 구조처럼 pages/, components/를 루트에 둔 프로젝트도 볼 수 있습니다.
my-nuxt-app/
├── app/
│ ├── app.vue # 최상위 컴포넌트
│ ├── pages/ # 파일 기반 라우트
│ ├── components/ # 자동 가져오기 되는 컴포넌트
│ ├── composables/ # 자동 가져오기 되는 composable
│ ├── layouts/ # 페이지를 감싸는 레이아웃
│ ├── middleware/ # 라우트 미들웨어
│ └── plugins/ # 앱 시작 시 실행되는 플러그인
├── server/
│ ├── api/ # /api/* 엔드포인트
│ └── routes/ # /api 접두사 없는 서버 라우트
├── public/ # 정적 파일
└── nuxt.config.ts| 폴더 | 하는 일 |
|---|---|
pages/ | 파일 경로가 URL이 됩니다. pages/about.vue는 /about |
components/ | 가져오기 없이 템플릿에서 바로 사용합니다 |
composables/ | useXxx 함수가 자동으로 가져와집니다 |
server/api/ | 파일마다 하나의 API 엔드포인트가 됩니다 |
layouts/ | 머리글·바닥글 같은 공통 틀을 정의합니다 |
Nuxt의 설정은 defineNuxtConfig 하나에 모입니다. 모듈, 전역 CSS, 런타임 설정, 라우트별 렌더링 규칙 등을 여기서 정합니다.
export default defineNuxtConfig({
modules: ["@pinia/nuxt"],
css: ["~/assets/css/main.css"],
runtimeConfig: {
apiSecret: "", // 서버에서만 읽힘
public: { apiBase: "/api" } // 클라이언트에도 노출
},
devtools: { enabled: true },
});runtimeConfig 값은 실행 시 NUXT_API_SECRET, NUXT_PUBLIC_API_BASE 같은 환경 변수로 덮어쓸 수 있고, 코드에서는 useRuntimeConfig()로 읽습니다. Nuxt는 .nuxt/ 폴더에 타입 정보를 생성하므로 이 폴더는 버전 관리에서 제외합니다.
main.ts에서 앱을 만들고 라우트를 router/index.ts에 직접 선언합니다.@ 별칭과 VITE_ 접두사 환경 변수를 기억해 둡니다.pages/, components/, composables/, server/ 같은 폴더 이름이 규칙이며, 설정은 nuxt.config.ts에 모입니다.runtimeConfig에 두고 환경 변수로 주입합니다.
댓글 0개
로그인 · 로그인하면 댓글을 남길 수 있습니다.
첫 댓글을 남겨 보세요.