Astro 완벽 가이드: 초보자부터 고급 사용자까지
Astro는 개발자들에게 사랑받는 프레임워크로, 단순하면서도 강력한 기능을 제공합니다.
이 글에서는 Astro의 기본 개념부터 고급 기능까지, 초보자도 쉽게 따라할 수 있도록 자세히 설명합니다.
Astro, 왜 인기일까요?
Astro는 매우 간단하게 시작할 수 있습니다.
HTML에 몇 가지 변수를 추가해 템플릿을 만들고 싶다면, Astro가 딱 맞습니다.
하지만 더 복잡한 기능이 필요할 때도 유연하게 대응할 수 있죠.
예를 들어, 리액트(React)와 같은 프론트엔드 UI 프레임워크를 Astro 사이트에 통합할 수 있습니다.
Astro 프로젝트 시작하기
Astro 프로젝트를 시작하려면 먼저 노드(Node)가 필요합니다.
노드 버전은 18.17.1 이상 또는 20.3 이상을 권장합니다.
노드가 설치되어 있지 않다면, nodejs.org에서 최신 LTS 버전을 다운로드하세요.
Astro CLI를 사용해 새로운 프로젝트를 생성해 볼게요. 터미널에서 다음 명령어를 입력합니다:
npm create astro@latest AstroSample
프로젝트 설정을 위해 다음 옵션을 선택합니다:
- 빈 프로젝트 생성
- 타입스크립트(TypeScript) 사용
- 엄격 모드(Strict Mode) 활성화
- 새로운 깃(Git) 저장소 생성
이제 VSCode와 크롬을 열어 프로젝트를 시작해 볼게요. 터미널에서 다음 명령어를 입력합니다:
npm run dev
이제 localhost:4321
에서 기본 Astro 프로젝트를 확인할 수 있습니다.
Astro 프로젝트 구조 이해하기
Astro 프로젝트의 기본 구조는 다음과 같습니다:
src
디렉토리: 페이지와 컴포넌트 등 주요 소스 코드가 위치합니다.public
디렉토리: Astro가 수정하지 않는 정적 파일이 위치합니다.
src
디렉토리
src
디렉토리 안에는 pages
디렉토리가 필수입니다.
이 디렉토리에는 index.astro
파일이 홈 경로 역할을 합니다.
파일 기반 라우팅을 사용하므로, 파일 이름을 변경하면 경로도 변경됩니다.
---
// index.astro
const myNum = 1;
---
<h1>Astro {myNum}</h1>
public
디렉토리
public
디렉토리에 있는 파일은 Astro가 수정하지 않으므로, 파비콘이나 정적 자원을 이곳에 두면 됩니다.
예를 들어, favicon.svg
파일을 변경하면 브라우저 탭에 반영됩니다.
Astro 파일 구조와 프론트 매터
Astro 파일은 프론트 매터(Front Matter)와 HTML 콘텐츠로 구성됩니다.
프론트 매터에서는 자바스크립트 로직을 작성하고, HTML 콘텐츠는 페이지에 출력됩니다.
---
// 프론트 매터 (JavaScript 로직)
const myNum = 1;
---
<h1>Astro {myNum}</h1>
프론트 매터에서 정의한 변수는 중괄호 {}
를 사용해 HTML에서 참조할 수 있습니다.
데이터 가져오기
Astro에서는 로컬 데이터, 프로젝트 내 데이터, 외부 API 데이터를 쉽게 가져올 수 있습니다.
로컬 데이터
---
const myArray = ["항목1", "항목2"];
---
<ul>
{myArray.map((item) => (
<li>{item}</li>
))}
</ul>
프로젝트 내 데이터
src/data
디렉토리에 JSON 파일을 생성하고 가져올 수 있습니다.
---
import people from "../data/sample.json";
---
<ul>
{people.map((person) => (
<li>{person.name}</li>
))}
</ul>
외부 API 데이터
---
const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const data = await response.json();
---
<pre>{JSON.stringify(data, null, 2)}</pre>
레이아웃과 슬롯
레이아웃을 사용하면 중복되는 코드를 줄일 수 있습니다.
src/layouts
디렉토리에 레이아웃 파일을 생성하고, 슬롯을 사용해 콘텐츠를 삽입합니다.
---
// src/layouts/BaseLayout.astro
---
<main>
<slot />
</main>
페이지에서 레이아웃을 사용하려면 다음과 같이 import합니다:
---
import BaseLayout from "../layouts/BaseLayout.astro";
---
<BaseLayout>
<h1>홈</h1>
</BaseLayout>
프롭스(Props) 전달
컴포넌트 간에 데이터를 전달하려면 프롭스를 사용합니다.
---
// BaseLayout.astro
const title = Astro.props.title || "기본 제목";
---
<h1>{title}</h1>
<slot />
페이지에서 프롭스를 전달합니다:
<BaseLayout title="홈">
<h1>홈 콘텐츠</h1>
</BaseLayout>
컴포넌트 생성
재사용 가능한 컴포넌트를 생성해 보겠습니다.
src/components
디렉토리에 Link.astro
파일을 생성합니다.
---
// src/components/Link.astro
const { href } = Astro.props;
---
<a href={href}>
<slot />
</a>
스타일을 추가하려면 <style>
태그를 사용합니다:
<style>
a {
color: blue;
}
</style>
스타일링
Astro에서는 스코프된 스타일, 인라인 스타일, CSS 모듈, CSS 프레임워크 등을 지원합니다.
스코프된 스타일
<style>
h1 {
color: red;
}
</style>
<h1>제목</h1>
글로벌 스타일
<style is:global>
body {
background-color: peachpuff;
}
</style>
테일윈드 CSS 사용
터미널에서 다음 명령어를 입력해 테일윈드를 설치합니다:
npm install tailwindcss
npx tailwindcss init
tailwind.config.js
파일을 설정하고, 컴포넌트에 클래스를 추가합니다:
<div class="bg-blue-500 text-white p-4">테일윈드 예제</div>
클라이언트 사이드 자바스크립트
Astro는 기본적으로 클라이언트 사이드 자바스크립트를 포함하지 않습니다.
필요할 경우 <script>
태그를 사용해 추가할 수 있습니다.
모듈 스크립트
<script>
console.log("페이지 로드 시 실행");
</script>
인라인 스크립트
<script is:inline>
console.log("인라인 스크립트");
</script>
유틸리티 함수 가져오기
src/lib
디렉토리에 유틸리티 함수를 생성하고 가져올 수 있습니다.
// src/lib/utils.ts
export function consoleMe() {
console.log("유틸리티 함수 호출");
}
페이지에서 함수를 가져와 사용합니다:
---
import { consoleMe } from "../lib/utils";
consoleMe();
---
<h1>홈</h1>
UI 프레임워크 통합
Astro에서는 리액트, 뷰, 스벨트 등 다양한 UI 프레임워크를 통합할 수 있습니다. 터미널에서 다음 명령어를 입력해 리액트를 추가합니다:
npm install react react-dom
리액트 컴포넌트를 생성하고 Astro 페이지에서 사용합니다:
// src/components/Card.tsx
import React from "react";
export default function Card() {
const handleClick = () => {
console.log("클릭됨!");
};
return (
<div>
<p>카드</p>
<button onClick={handleClick}>클릭하세요</button>
</div>
);
}
Astro 페이지에서 리액트 컴포넌트를 사용합니다:
---
import Card from "../components/Card.tsx";
---
<Card client:visible />
client:visible
디렉티브를 사용하면 컴포넌트가 뷰포트에 나타날 때만 자바스크립트가 로드됩니다.
고급 기능
Astro는 서버 사이드 렌더링, 미들웨어, 동적 라우트, API 라우트, 콘텐츠 컬렉션, 서버 아일랜드 등 다양한 고급 기능을 제공합니다.
서버 사이드 렌더링(SSR)
Astro는 기본적으로 정적 사이트 생성(SSG)을 지원하지만, SSR 어댑터를 추가해 동적 렌더링을 구현할 수 있습니다.
npm install @astrojs/node
astro.config.mjs
파일에 어댑터를 설정합니다:
import { defineConfig } from "astro/config";
import node from "@astrojs/node";
export default defineConfig({
adapter: node(),
});
미들웨어
미들웨어를 사용해 요청과 응답을 중간에서 처리할 수 있습니다.
// src/middleware.ts
import { Middleware } from "astro";
export const onRequest: Middleware = (context, next) => {
console.log("요청 처리 중...");
return next();
};
astro.config.mjs
파일에 미들웨어를 등록합니다:
import { defineConfig } from "astro/config";
import { onRequest } from "./src/middleware";
export default defineConfig({
middleware: [onRequest],
});
동적 라우트
동적 라우트를 사용해 동적인 페이지를 생성할 수 있습니다. src/pages
디렉토리에 [slug].astro
파일을 생성합니다:
---
const { slug } = Astro.params;
---
<h1>동적 라우트: {slug}</h1>
API 라우트
API 라우트를 사용해 서버 측 로직을 처리할 수 있습니다. src/pages/api
디렉토리에 example.ts
파일을 생성합니다:
import type { APIRoute } from "astro";
export const GET: APIRoute = ({ request }) => {
return new Response(JSON.stringify({ message: "Hello, API!" }), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});
};
콘텐츠 컬렉션
콘텐츠 컬렉션을 사용해 Markdown 파일을 쉽게 관리할 수 있습니다. src/content/config.ts
파일을 생성하고 설정합니다:
import { defineCollection } from "astro:content";
const blogCollection = defineCollection({
type: "content",
schema: ({ image }) => ({
title: "string",
description: "string",
publishDate: "date",
coverImage: image(),
}),
});
export const collections = {
blog: blogCollection,
};
서버 아일랜드
서버 아일랜드를 사용해 특정 컴포넌트를 서버에서 렌더링할 수 있습니다. client:only
디렉티브를 사용합니다:
---
import ServerComponent from "../components/ServerComponent.astro";
---
<ServerComponent client:only />
결론
Astro는 단순하면서도 강력한 프레임워크입니다.
이 글에서는 Astro의 기본 개념과 주요 기능을 살펴보았습니다.
'Javascript' 카테고리의 다른 글
TypeScript로 구현하는 최신 ESM 기반 npm 패키지 퍼블리싱 가이드 (0) | 2025.03.03 |
---|---|
JavaScript Temporal, 날짜와 시간을 다루는 새로운 방법 (0) | 2025.03.02 |
PM2, 정말 괜찮은 걸까요? 2025년 Node.js 앱 관리, 메모리 누수 이슈와 대안 솔루션 총정리 (Kubernetes, Systemd) (0) | 2025.02.13 |
TypeScript 튜플의 모든 것: 실전 예제로 풀어보는 타입 활용법 (1) | 2025.02.13 |
TypeScript의 템플릿 리터럴 타입: 타입 검사 중 파싱 및 활용 방법 (0) | 2025.02.13 |