[Astro] 설치 및 프로젝트 구성

2026-03-25 hit count image

Astro를 설치하고 블로그 프로젝트를 구성하는 방법을 공유합니다. astro.config.mjs 설정, 디렉토리 구조, SCSS 설정, 빌드 스크립트 등을 다룹니다.

astro

개요

이전 글 Jekyll에서 Astro로 마이그레이션한 이유에서 Jekyll에서 Astro로 옮기게 된 배경을 공유했습니다. 이번 글에서는 실제로 Astro를 설치하고 블로그 프로젝트를 구성하는 방법을 단계별로 설명합니다.

사전 준비

AstroNode.js 기반이므로, 먼저 Node.js가 설치되어 있어야 합니다.

Node.js 설치

Node.js 공식 사이트에서 LTS 버전을 설치합니다. nvm(Node Version Manager)을 사용하면 여러 버전을 쉽게 관리할 수 있습니다.

# nvm으로 Node.js 설치
nvm install --lts
nvm use --lts

# 버전 확인
node -v
npm -v

프로젝트 루트에 .nvmrc 파일을 만들어두면 팀원들과 Node.js 버전을 통일할 수 있습니다.

Astro 프로젝트 생성

Astro는 공식 CLI 도구로 프로젝트를 빠르게 생성할 수 있습니다.

npm create astro@latest

CLI 안내에 따라 프로젝트 이름, 템플릿 등을 선택합니다. 블로그 구조를 처음부터 직접 설계하면 프로젝트에 대한 이해도가 높아질 수 있기 때문에, 빈 프로젝트(Empty)로 시작하는 것을 추천합니다.

# 프로젝트 생성 후 이동
cd my-blog

# 의존성 설치
npm install

# 개발 서버 시작
npm run dev

개발 서버가 시작되면 http://localhost:4321에서 사이트를 확인할 수 있습니다. Vite 기반의 HMR 덕분에 파일을 수정하면 브라우저에 즉시 반영됩니다.

프로젝트 디렉토리 구조

이 블로그의 프로젝트 디렉토리 구조는 다음과 같습니다.

/
├── public/                  # 정적 파일 (이미지, robots.txt 등)
│   ├── assets/
│   │   └── images/
│   ├── robots.txt
│   ├── ads.txt
│   ├── CNAME
│   └── .nojekyll
├── src/
│   ├── components/          # 재사용 가능한 Astro 컴포넌트
│   │   ├── Head.astro
│   │   ├── Navbar.astro
│   │   ├── Footer.astro
│   │   ├── Breadcrumbs.astro
│   │   ├── Comments.astro
│   │   ├── SearchBar.astro
│   │   ├── SearchPage.astro
│   │   ├── Pagination.astro
│   │   ├── CategoryCard.astro
│   │   ├── PostCard.astro
│   │   └── ads/             # 광고 컴포넌트
│   ├── content/             # 블로그 포스트 (Content Collections)
│   │   ├── astro/
│   │   ├── react/
│   │   ├── jekyll/
│   │   └── ...
│   ├── data/                # 정적 데이터
│   │   └── categories.ts
│   ├── i18n/                # 다국어 번역
│   │   └── translations.ts
│   ├── layouts/             # 레이아웃 템플릿
│   │   ├── BaseLayout.astro
│   │   └── PostLayout.astro
│   ├── pages/               # 라우트 페이지
│   │   ├── [...path].astro  # 일본어 (기본)
│   │   ├── ko/              # 한국어
│   │   └── en/              # 영어
│   ├── plugins/             # 커스텀 rehype 플러그인
│   │   ├── rehype-picture.mjs
│   │   └── rehype-in-feed-ads.mjs
│   └── styles/              # 전역 스타일
│       └── global.scss
├── scripts/                 # 빌드/배포 스크립트
│   └── share.mjs
├── astro.config.mjs         # Astro 설정
├── package.json
└── tsconfig.json

주요 디렉토리 설명

주요 디렉토리를 좀 더 자세히 살펴보면 다음과 같습니다.

디렉토리역할
public/빌드 시 그대로 복사되는 정적 파일. 이미지, 폰트, 검증 파일 등
src/components/재사용 가능한 .astro 컴포넌트. Head, Navbar, Footer 등
src/content/Content Collections로 관리되는 마크다운 블로그 포스트
src/data/카테고리 정의 등 정적 데이터
src/i18n/다국어 번역 및 헬퍼 함수
src/layouts/페이지 레이아웃 템플릿
src/pages/파일 기반 라우팅. 디렉토리 구조가 곧 URL 구조
src/plugins/커스텀 rehype/remark 마크다운 처리 플러그인
src/styles/전역 SCSS 스타일

astro.config.mjs 설정

Astro의 핵심 설정 파일입니다. 이 블로그에서 사용하고 있는 실제 설정을 살펴보겠습니다.

// @ts-check
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
import rehypeExternalLinks from 'rehype-external-links';
import rehypeCallouts from 'rehype-callouts';
import rehypeInFeedAds from './src/plugins/rehype-in-feed-ads.mjs';
import rehypePicture from './src/plugins/rehype-picture.mjs';

export default defineConfig({
  site: 'https://deku.posstree.com',
  output: 'static',
  build: {
    inlineStylesheets: 'always',
  },
  trailingSlash: 'always',
  integrations: [
    sitemap({
      serialize(item) {
        item.lastmod = new Date();
        return item;
      },
      i18n: {
        defaultLocale: 'ja',
        locales: {
          ja: 'ja',
          ko: 'ko',
          en: 'en',
        },
      },
    }),
  ],
  markdown: {
    shikiConfig: {
      theme: 'material-theme-darker',
    },
    rehypePlugins: [
      [rehypeCallouts, { theme: 'github' }],
      [
        rehypeExternalLinks,
        { target: '_blank', rel: ['nofollow', 'noreferrer'] },
      ],
      rehypeInFeedAds,
      [
        rehypePicture,
        { publicDir: new URL('./public', import.meta.url).pathname },
      ],
    ],
  },
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          silenceDeprecations: ['import', 'global-builtin', 'color-functions'],
        },
      },
    },
  },
});

주요 설정 항목

site

site: 'https://deku.posstree.com',

사이트의 최종 배포 URL입니다. 사이트맵 생성, canonical URL, OG 태그 등에서 사용됩니다.

output

output: 'static',

정적 사이트로 빌드합니다. GitHub Pages에 배포하려면 반드시 'static'으로 설정해야 합니다.

build.inlineStylesheets

build: {
  inlineStylesheets: 'always',
},

모든 CSS를 HTML에 인라인으로 포함합니다. 별도의 CSS 파일 요청을 줄여 초기 로딩 속도를 개선합니다.

trailingSlash

trailingSlash: 'always',

모든 URL이 /로 끝나도록 설정합니다. /astro/installation이 아닌 /astro/installation/이 됩니다. Jekyll에서 사용하던 URL 형식을 유지하기 위해 설정했습니다.

integrations

integrations: [
  sitemap({ ... }),
],

@astrojs/sitemap 플러그인으로 다국어 사이트맵을 자동 생성합니다. 자세한 내용은 SEO 구현 포스트에서 다룹니다.

markdown

마크다운 처리를 위한 설정입니다.

  • shikiConfig: 코드 블록 구문 강조에 material-theme-darker 테마를 사용합니다
  • rehypePlugins: 마크다운을 HTML로 변환할 때 적용되는 플러그인들입니다
    • rehype-callouts: GitHub 스타일 콜아웃 블록 지원
    • rehype-external-links: 외부 링크에 자동으로 target="_blank", rel="nofollow noreferrer" 추가
    • rehype-in-feed-ads: 마크다운 내 <!-- ad --> 주석을 광고 블록으로 변환
    • rehype-picture: 이미지를 AVIF/WebP 형식의 <picture> 요소로 자동 변환

package.json 스크립트

블로그 프로젝트에서 사용하는 npm 스크립트입니다.

{
  "name": "deku-blog",
  "type": "module",
  "version": "1.0.0",
  "scripts": {
    "dev": "astro dev",
    "build": "astro build && npx pagefind --site dist",
    "prepreview": "npm run build",
    "preview": "astro preview",
    "predeploy": "npm run share:sync",
    "deploy": "gh-pages -d dist -r git@personal:posstree/deku.posstree.com.git -t"
  },
  "dependencies": {
    "@astrojs/rss": "^4.0.0",
    "@astrojs/sitemap": "^3.3.0",
    "astro": "^5.17.1",
    "rehype-callouts": "^2.1.2",
    "rehype-external-links": "^3.0.0",
    "sass": "^1.80.0",
    "sharp": "^0.33.0"
  },
  "devDependencies": {
    "dotenv": "^16.6.1",
    "gh-pages": "^6.3.0",
    "pagefind": "^1.4.0"
  }
}

주요 스크립트 설명

스크립트의 주요 기능은 다음과 같습니다.

스크립트설명
npm run dev개발 서버 시작. HMR으로 즉시 반영
npm run build프로덕션 빌드 + Pagefind 검색 인덱스 생성
npm run preview빌드된 사이트를 로컬에서 미리보기
npm run deployGitHub Pages에 배포

build 스크립트에서 astro build 후에 npx pagefind --site dist를 실행하는 것이 포인트입니다. Pagefind는 빌드된 HTML 파일을 분석하여 검색 인덱스를 생성하므로, 반드시 빌드 후에 실행해야 합니다.

주요 의존성 설명

Astro 프로젝트에서 사용되는 주요 패키지와 역할은 다음과 같습니다.

패키지역할
astro핵심 프레임워크
@astrojs/sitemap다국어 사이트맵 자동 생성
@astrojs/rssRSS 피드 생성
sassSCSS 전처리기
sharp이미지 변환 (AVIF/WebP)
rehype-calloutsGitHub 스타일 콜아웃
rehype-external-links외부 링크 처리
gh-pagesGitHub Pages 배포
pagefind정적 검색

SCSS 설정

이 블로그는 SCSS를 사용하여 스타일을 관리합니다. AstroVite를 내장하고 있어 sass 패키지만 설치하면 별도의 설정 없이 SCSS를 사용할 수 있습니다.

npm install sass

다만, Sass의 최신 버전에서 deprecated된 기능을 사용하는 경우 경고가 발생할 수 있습니다. astro.config.mjsvite 설정에서 이를 무시할 수 있습니다.

vite: {
  css: {
    preprocessorOptions: {
      scss: {
        silenceDeprecations: ['import', 'global-builtin', 'color-functions'],
      },
    },
  },
},

전역 스타일은 src/styles/global.scss에서 관리하며, 레이아웃 컴포넌트에서 import하여 사용합니다.

---
// BaseLayout.astro
import '../styles/global.scss';
---

완료

이번 글에서는 Astro 프로젝트의 설치와 기본 구성을 살펴보았습니다. 정리하면:

  • npm create astro@latest로 프로젝트 생성
  • astro.config.mjs에서 사이트 URL, 정적 빌드, 사이트맵, 마크다운 플러그인 설정
  • package.json에서 빌드, 개발, 배포 스크립트 구성
  • SCSS 설정 및 deprecation 경고 처리

다음 글 Content Collections와 마크다운 마이그레이션에서는 Jekyll의 마크다운 파일을 AstroContent Collections로 마이그레이션하는 방법을 다룹니다.

시리즈 안내

이 포스트는 Jekyll에서 Astro로 마이그레이션 시리즈의 일부입니다.

  1. Jekyll에서 Astro로 마이그레이션한 이유
  2. Astro 설치 및 프로젝트 구성
  3. Content Collections와 마크다운 마이그레이션
  4. 다국어(i18n) 구현
  5. SEO 구현
  6. 이미지 최적화 — 커스텀 rehype 플러그인
  7. 댓글 시스템 (Utterances)
  8. 광고 연동 (Google AdSense)
  9. Pagefind를 이용한 검색 구현
  10. 레이아웃과 컴포넌트 아키텍처
  11. GitHub Pages 배포
  12. 소셜 공유 자동화 스크립트
  13. 트러블슈팅과 팁

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

앱 홍보

책 홍보

블로그를 운영하면서 좋은 기회가 생겨 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.



SHARE
Twitter Facebook RSS