지난 포스팅에는 레이아웃과 컴포넌트에 대해 설명했는데요, 이번에는 웹 애플리케이션 개발에 필수적인 정적 리소스 관리 방법에 대해 알아보겠습니다. 이미지, CSS, 폰트 등의 리소스를 효율적으로 관리하는 방법과 Nuxt.js에서 제공하는 assets과 public 디렉토리의 차이점을 이해하고, 실제 프로젝트에 적용하는 방법을 배워보겠습니다.

1. 에셋(Assets)과 정적 파일(Public)의 차이
Nuxt.js에서는 정적 파일을 관리하기 위한 두 가지 주요 디렉토리를 제공합니다: assets와 public. 이 두 디렉토리는 비슷해 보이지만 사용 목적과 처리 방식에 중요한 차이가 있습니다.
assets 디렉토리
assets
디렉토리는 빌드 프로세스를 거치는 파일들을 저장하는 곳입니다. 이 디렉토리에 있는 파일들은 Webpack과 같은 빌드 도구에 의해 처리됩니다.
- CSS, SCSS, LESS 등의 스타일 파일
- 최적화가 필요한 이미지 파일
- 폰트 파일
- JavaScript 모듈
assets 디렉토리의 주요 특징:
- 빌드 시 처리되어 최적화됨
- 파일명에 해시가 추가되어 캐싱 문제 방지
- 번들러(Webpack)의 로더를 통해 처리 가능
- 코드에서 상대 경로나
~/assets/
로 참조
public 디렉토리
public
디렉토리는 빌드 프로세스 없이 그대로 서버의 루트에 제공되는 파일들을 저장하는 곳입니다.
- robots.txt, favicon.ico와 같은 루트 파일
- SEO를 위한 sitemap.xml
- 정적 HTML 파일
- 변환 없이 그대로 사용할 이미지
public 디렉토리의 주요 특징:
- 빌드 프로세스를 거치지 않고 그대로 복사됨
- URL에서 직접 접근 가능 (예:
/images/logo.png
) - 파일명이 그대로 유지됨
- 빌드 시간에 영향을 주지 않음
2. assets 디렉토리 활용하기
이미지 파일 관리
assets 디렉토리에 이미지를 저장하고 컴포넌트에서 사용하는 방법을 알아보겠습니다.
// 디렉토리 구조
assets/
├── images/
├──── logo.png
├──── banner.jpg
├─── icons/
├──── home.svg
└──── user.svg
Vue 컴포넌트에서 이미지 사용하기:
<template>
<div>
<img src="~/assets/images/logo.png" alt="로고" />
<!-- 동적 이미지 경로 사용 -->
<img :src="require(`~/assets/images/icons/${iconName}.svg`)" alt="아이콘" />
</div>
</template>
Nuxt 3 부터는 더 간편하게 useAsset
컴포저블을 사용할 수 있습니다:
<script setup>
const logoUrl = useAsset('/images/logo.png')
</script>
<template>
<img :src="logoUrl" alt="로고" />
</template>
CSS 및 스타일 파일 관리
assets 디렉토리에 CSS, SCSS 등의 스타일 파일을 저장하고 활용하는 방법입니다.
// 디렉토리 구조
assets/
├── css/
├─── main.css
├─── variables.scss
└─── _mixins.scss
전역 CSS 파일을 nuxt.config.js에 등록하기:
// nuxt.config.js
export default defineNuxtConfig({
css: [
'~/assets/css/main.css',
// SCSS 파일도 등록 가능
'~/assets/css/variables.scss'
]
})
컴포넌트에서 스타일 파일 가져오기:
<style lang="scss">
@import '~/assets/css/_mixins.scss';
.container {
@include flex-center;
background-color: #f5f5f5;
}
</style>
폰트 파일 관리
웹 폰트를 assets 디렉토리에 저장하고 사용하는 방법입니다.
// 디렉토리 구조
assets/
├── fonts/
├─── Roboto-Regular.woff2
└─── Roboto-Bold.woff2
CSS에서 폰트 등록하기:
/* assets/css/fonts.css */
@font-face {
font-family: 'Roboto';
src: url('~/assets/fonts/Roboto-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Roboto';
src: url('~/assets/fonts/Roboto-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
nuxt.config.js에 폰트 CSS 등록:
// nuxt.config.js
export default defineNuxtConfig({
css: [
'~/assets/css/fonts.css'
]
})
3. public 디렉토리 활용하기
정적 파일 관리
public 디렉토리에 저장된 파일들은 빌드 과정 없이 그대로 서버 루트에 제공됩니다.
// 디렉토리 구조
public/
├── favicon.ico
├── robots.txt
├── images/
├──── logo.png
├── documents/
└──── terms.pdf
HTML에서 public 파일 참조하기:
<template>
<div>
<img src="/images/logo.png" alt="로고" />
<a href="/documents/terms.pdf" target="_blank">이용약관 PDF</a>
</div>
</template>
favicon과 같은 특수 파일들은 자동으로 인식됩니다:
// public/robots.txt
User-agent: *
Allow: /
SEO 관련 파일
SEO를 위한 파일들도 public 디렉토리에 저장하는 것이 좋습니다.
// public/sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
<lastmod>2023-01-01</lastmod>
</url>
</urlset>
4. CSS 프레임워크 연동하기 – Tailwind CSS
Nuxt.js 프로젝트에 Tailwind CSS를 연동하는 방법을 알아보겠습니다. Tailwind CSS는 유틸리티 우선 접근 방식의 CSS 프레임워크로, 빠르게 UI를 구축할 수 있게 도와줍니다.
Tailwind CSS 설치
# npm으로 설치
npm install -D tailwindcss postcss autoprefixer
# 설정 파일 생성
npx tailwindcss init
Tailwind 설정 파일 구성
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./components/**/*.{js,vue,ts}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./nuxt.config.{js,ts}",
"./app.vue",
],
theme: {
extend: {},
},
plugins: [],
}
PostCSS 설정
// nuxt.config.js
export default defineNuxtConfig({
postcss: {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
},
})
CSS 파일 생성 및 등록
// assets/css/tailwind.css
@tailwind base;
@tailwind components;
@tailwind utilities;
/* 커스텀 스타일 추가 */
@layer components {
.btn-primary {
@apply px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600;
}
}
// nuxt.config.js
export default defineNuxtConfig({
css: ['~/assets/css/tailwind.css'],
// 다른 설정들...
})
Tailwind CSS 사용 예시
<template>
<div class="container mx-auto px-4 py-8">
<h1 class="text-3xl font-bold text-gray-800 mb-6">Nuxt.js와 Tailwind CSS</h1>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-xl font-semibold mb-4">카드 제목</h2>
<p class="text-gray-600">카드 내용이 여기에 들어갑니다.</p>
<button class="btn-primary mt-4">자세히 보기</button>
</div>
<!-- 추가 카드들... -->
</div>
</div>
</template>
5. 실전 예제: 이미지 최적화
Nuxt.js에서는 @nuxt/image
모듈을 사용하여 이미지를 최적화할 수 있습니다. 이 모듈은 이미지 크기 조정, 포맷 변환, 지연 로딩 등의 기능을 제공합니다.
@nuxt/image 설치
npm install @nuxt/image
nuxt.config.js에 모듈 등록
// nuxt.config.js
export default defineNuxtConfig({
modules: [
'@nuxt/image',
],
image: {
// 이미지 모듈 설정
quality: 80,
format: ['webp', 'jpg', 'png'],
screens: {
xs: 320,
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
xxl: 1536,
}
}
})
NuxtImg 컴포넌트 사용
<template>
<div>
<!-- 기본 사용법 -->
<nuxt-img src="/images/hero.jpg" alt="히어로 이미지" />
<!-- 크기 조정 및 최적화 -->
<nuxt-img
src="~/assets/images/product.jpg"
alt="제품 이미지"
width="400"
height="300"
format="webp"
loading="lazy"
placeholder
/>
<!-- 반응형 이미지 -->
<nuxt-img
src="~/assets/images/banner.jpg"
alt="배너"
sizes="sm:100vw md:50vw lg:400px"
preload
/>
</div>
</template>
NuxtPicture 컴포넌트로 고급 최적화
<template>
<nuxt-picture
src="~/assets/images/photo.jpg"
alt="사진"
format="webp"
:imgAttrs="{
class: 'rounded-lg shadow-md',
loading: 'lazy'
}"
/>
</template>
6. 프로젝트 구조 예시
실제 프로젝트에서 assets와 public 디렉토리를 어떻게 구성하는지 예시를 살펴보겠습니다.
my-nuxt-project/ ├── assets/ │ ├── css/ │ │ ├── main.css │ │ ├── tailwind.css │ │ └── variables.scss │ ├── images/ │ │ ├── backgrounds/ │ │ ├── icons/ │ │ └── logos/ │ ├── fonts/ │ │ ├── OpenSans-Regular.woff2 │ │ └── OpenSans-Bold.woff2 │ └── js/ │ └── utils.js ├── public/ │ ├── favicon.ico │ ├── robots.txt │ ├── sitemap.xml │ ├── images/ │ │ └── static-banner.jpg │ └── documents/ │ └── terms-of-service.pdf └── ...
7. 정리 및 모범 사례
Nuxt.js에서 정적 리소스를 관리할 때 고려해야 할 모범 사례를 정리해보겠습니다.
- assets 디렉토리 사용 시기: 빌드 프로세스를 통해 최적화가 필요한 파일들 (이미지, CSS, JS 모듈)
- public 디렉토리 사용 시기: 원본 그대로 제공되어야 하는 파일들 (favicon, robots.txt, 다운로드 파일)
- 이미지 최적화: 가능한 @nuxt/image 모듈을 사용하여 이미지 최적화
- CSS 관리: 전역 스타일은 nuxt.config.js에 등록, 컴포넌트별 스타일은 스코프드 스타일 사용
- 폰트 최적화: font-display: swap 속성 사용, 필요한 폰트 웨이트만 로드
- 디렉토리 구조: 목적에 맞게 하위 디렉토리로 구분하여 관리
다음 포스팅 예고: 데이터 가져오기 (Data Fetching) 기초
다음 포스팅에서는 Nuxt.js의 가장 강력한 기능 중 하나인 데이터 가져오기(Data Fetching)에 대해 알아보겠습니다. useFetch
와 useAsyncData
를 활용하여 API에서 데이터를 가져오는 방법, 클라이언트 및 서버 사이드에서의 데이터 호출 차이점, 로딩 및 에러 상태를 효과적으로 처리하는 방법 등을 배울 예정입니다. Nuxt.js의 데이터 가져오기 기능은 SSR(서버 사이드 렌더링)의 장점을 최대한 활용할 수 있게 해주는 핵심 기능이니 꼭 참여해주세요!
이번 포스팅에서는 Nuxt.js에서 정적 리소스를 관리하는 방법에 대해 알아보았습니다. assets과 public 디렉토리의 차이점을 이해하고, 각각의 용도에 맞게 활용하는 방법에 대해 설명했습니다. 또한 Tailwind CSS와 같은 CSS 프레임워크를 연동하는 방법과 이미지 최적화 기법도 살펴보았습니다. 다음 포스팅에서는 더 동적인 웹 애플리케이션을 만들기 위한 데이터 가져오기 기능에 대해 알아보겠습니다.
답글 남기기