Astro 프레임워크 체험기

 

챗 지피티에게 물어본 

Astro의 주요 특징
1. 멀티 프레임워크 지원: Astro는 React, Vue, Svelte, Solid.js 등 다양한 프론트엔드 프레임워크의 컴포넌트를 한 프로젝트에서 함께 사용할 수 있습니다.
2. Partial Hydration (부분 하이드레이션): Astro는 기본적으로 정적 HTML을 생성하며, 필요한 부분만 JavaScript로 하이드레이션(동적으로 활성화)하여 클라이언트에서 실행합니다.
이를 통해 JavaScript 로딩을 최소화하고 페이지 로드 속도를 최적화합니다.
3. 파일 기반 라우팅: 파일 구조를 기반으로 라우팅을 자동으로 처리합니다.
4. 빠른 빌드와 최적화: Vite를 기반으로 하여 빌드 속도가 매우 빠릅니다. 정적 HTML을 우선 생성하고, 필요한 JavaScript만 로드하므로 성능이 뛰어납니다.
5. SEO와 접근성 최적화: 정적 콘텐츠 중심이라 검색 엔진 최적화(SEO)와 초기 로드 속도가 뛰어납니다.
6. Markdown과 통합: Markdown 파일을 쉽게 작성하고 렌더링할 수 있어 블로그나 문서 사이트에 적합합니다.

 

사용 사례
- 블로그나 개인 포트폴리오
- 문서 사이트 (예: 개발 문서, 튜토리얼)
- 마케팅 랜딩 페이지
- SEO가 중요한 정적 웹사이트

 

장점
- 빠른 성능과 작은 JavaScript 번들 크기
- 멀티 프레임워크 호환성
- 쉬운 정적 사이트 생성
- 개발자 경험이 우수함 (간단한 API와 설정)

 

 


 

React, Vue, Svelte, Solidjs 등의 웹 프레임워크의 컴포넌트 지원? 궁금해서 간단히 써봤다. 

Astro 사이트 들어가보면 https://astro.build/ Get Started를 통해 튜토리얼 진행하면 되는 정도의 체험기.


튜토리얼을 진행해보자 

프로젝트 설치

// create a new project with npm
npm create astro@latest

Project initializing

 

dir 프로젝트 위치와 프로젝트명

tmpl 어떤 템플릿 쓸건지 (A basic, minimal starter가 추천이라 그냥했다)

How would you like to start your new project?

deps 종속성 관련 설치하고

git 레포지토리는 연결하지않았다

 

그러면 astro.config.mjs 가 포함된 astro 프로젝트가 생성된다. 

new project

 

타입스크립트 https://docs.astro.build/en/guides/typescript/

 

TypeScript

Learn how to use Astro's built-in TypeScript support.

docs.astro.build

위 문서대로 따라해보자.

 

tsconfig.json 

extends 는 base, strict, strictest 중에 설정할수 있다.

npm install @astrojs/ts-plugin

 

@astrojs/ts-plugin 설치한다음 tsconfig.json에 추가해준다

{
  "extends": "astro/tsconfigs/strict",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": ["dist"],
  "compilerOptions": {
    "plugins": [
      {
        "name": "@astrojs/ts-plugin"
      },
    ],
  }
}

 

 

 

자 이제 체험이니까 다른 설정관련해서는 넘어가고 

React 관련 설정을 좀 해보겠다

https://docs.astro.build/en/guides/integrations-guide/react/

 

@astrojs/react

Learn how to use the @astrojs/react framework integration to extend component support in your Astro project.

docs.astro.build

 

Astro에는 astro add를 통해 공식적으로 통합 설정을 자동화하는 명령이 포함되어 있다고한다.

아래처럼 입력하면 react 관련해서 통합 설정해주고, vue로 바꾸면 vue에 대한 통합 설정을 해준다. (오~)

npx astro add react

 

즉, 수동으로 종속 패키지를 install 안하고 통합된 종속 패키지들을 한방에 다운받을수 있다. (오!)

continue? 라고 물어보면 설치 끝날때까지 계속 엔터로 넘기기 

완료되면 어디 뭐 추가됐는지 보여준다. 친절하다.

설치 완료 후 노출창

 

 

설치를 마친후 astro.config.mjs들어와보면, 아래와 같이 react가 추가된 걸 볼수 있다.

// @ts-check
import { defineConfig } from 'astro/config';

import react from '@astrojs/react';

// https://astro.build/config
export default defineConfig({
  integrations: [react()]
});

 

 

vue도 동일하게 진행

https://docs.astro.build/en/guides/integrations-guide/vue/

npx astro add vue

 

 

그리고 스타일에 사용할 tailwind로 똑같이 진행.

https://docs.astro.build/en/guides/integrations-guide/tailwind/

 

똑같은 과정을 거치고 나면 astro.config.mjs 파일에 vue, tailwind가 추가되어있을것이다.

 

최초 화면은 어떻게 생겼을지,

dev를 명령어를 입력하고 띄어보자. 

npm run dev

 

요렇게 기본 화면 뜨는것 까지 확인!

초기화면

 

 

디렉토리 및 파일 (https://docs.astro.build/en/basics/project-structure/)

  • src/*- 프로젝트 소스 코드(구성요소, 페이지, 스타일, 이미지 등)
  • public/*- 코드가 아니고 처리되지 않은 자산(글꼴, 아이콘 등)
  • package.json- 프로젝트 매니페스트.
  • astro.config.mjs- Astro 구성 파일. (권장)
  • tsconfig.json- TypeScript 구성 파일. (권장)

 

react, vue로 컴포넌트

자 이제 react, vue로 컴포넌트를 만들어보자.

 

근데 src > components > Welcome.astro 파일을 보면,,

구조가 신기하다.

 — 주석과 — 주석 사이에 스크립트 넣고 하위는 html, style을 넣어준다. (스타일을 제외한 코드)

 

Welcome.astro

---
import astroLogo from '../assets/astro.svg';
import background from '../assets/background.svg';
---

<div id="container">
	<img id="background" src={background.src} alt="" fetchpriority="high" />
	<main>
		<section id="hero">
			<a href="https://astro.build"
				><img src={astroLogo.src} width="115" height="48" alt="Astro Homepage" /></a
			>
			<h1>
				To get started, open the <code><pre>src/pages</pre></code> directory in your project.
			</h1>
			<section id="links">
				<a class="button" href="https://docs.astro.build">Read our docs</a>
				<a href="https://astro.build/chat"
					>Join our Discord <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"
						><path
							fill="currentColor"
							d="M107.7 8.07A105.15 105.15 0 0 0 81.47 0a72.06 72.06 0 0 0-3.36 6.83 97.68 97.68 0 0 0-29.11 0A72.37 72.37 0 0 0 45.64 0a105.89 105.89 0 0 0-26.25 8.09C2.79 32.65-1.71 56.6.54 80.21a105.73 105.73 0 0 0 32.17 16.15 77.7 77.7 0 0 0 6.89-11.11 68.42 68.42 0 0 1-10.85-5.18c.91-.66 1.8-1.34 2.66-2a75.57 75.57 0 0 0 64.32 0c.87.71 1.76 1.39 2.66 2a68.68 68.68 0 0 1-10.87 5.19 77 77 0 0 0 6.89 11.1 105.25 105.25 0 0 0 32.19-16.14c2.64-27.38-4.51-51.11-18.9-72.15ZM42.45 65.69C36.18 65.69 31 60 31 53s5-12.74 11.43-12.74S54 46 53.89 53s-5.05 12.69-11.44 12.69Zm42.24 0C78.41 65.69 73.25 60 73.25 53s5-12.74 11.44-12.74S96.23 46 96.12 53s-5.04 12.69-11.43 12.69Z"
						></path></svg
					>
				</a>
			</section>
		</section>
	</main>

	<a href="https://astro.build/blog/astro-5/" id="news" class="box">
		<svg width="32" height="32" fill="none" xmlns="http://www.w3.org/2000/svg"
			><path
				d="M24.667 12c1.333 1.414 2 3.192 2 5.334 0 4.62-4.934 5.7-7.334 12C18.444 28.567 18 27.456 18 26c0-4.642 6.667-7.053 6.667-14Zm-5.334-5.333c1.6 1.65 2.4 3.43 2.4 5.333 0 6.602-8.06 7.59-6.4 17.334C13.111 27.787 12 25.564 12 22.666c0-4.434 7.333-8 7.333-16Zm-6-5.333C15.111 3.555 16 5.556 16 7.333c0 8.333-11.333 10.962-5.333 22-3.488-.774-6-4-6-8 0-8.667 8.666-10 8.666-20Z"
				fill="#111827"></path></svg
		>
		<h2>What's New in Astro 5.0?</h2>
		<p>
			From content layers to server islands, click to learn more about the new features and
			improvements in Astro 5.0
		</p>
	</a>
</div>

<style>
// ...
</style>

 

 

기본적으로 html 렌더링된거 보면 type="module" 로 컴포넌트 코드가 들어가있더라.

 

 

여튼 React와 Vue 컴포넌트를 생성해보자. (각 구조에 맞춰 만들어야함)

components 파일 하위에 컴포넌트를 하나 생성해준다. 

 

 

ReactHeader.tsx

export default function ReactHeader() {
  return <div className="bg-pink-200">ReactHeader</div>;
}

 

 

VueBody.vue

<script>
export default {};
</script>

<template>
  <div className="bg-blue-50">Vue Body</div>
</template>

 

 

astro는 파일기반 라우팅이라 /src/pages 파일 경로에 따라 사이트 엔드포인트가 된다. (에러페이지 같은 경우는 src/pages/404.astro 이런형태로 만들면 된다.

(src/pages에서 파일 유형을 지원: .astro .md .mdx .html .js)

 

pages/index.astro에서 import 해보면 되겠지?

 

index.astro

---
import ReactHeader from '../components/ReactHeader';
import VueBody from '../components/VueBody.vue';
import Layout from '../layouts/Layout.astro';
---

<Layout>
	 <ReactHeader />
	 <VueBody />
</Layout>

 

 

오 문제없이 (vscode가 경고를 안하고있다) import가 되었다.

props는 각각 아래와 같이(문법대로) 넘기면 된다. (느낌아니까)

 

index.astro

---
import ReactHeader from '../components/ReactHeader';
import VueBody from '../components/VueBody.vue';
import Layout from '../layouts/Layout.astro';
---

<Layout>
	 <ReactHeader title="React Header"/>
	 <VueBody title="Vue Body"/>
</Layout>

 

 

 

ReactHeader.tsx

interface Props {
  title: string;
}

export default function ReactHeader(props: Props) {
  return <div className="bg-pink-200">{props.title}</div>;
}

 

 

VueBody.vue

<script>
export default {
  props: {
    title: String,
  },
};
</script>

<template>
  <div className="bg-blue-50">{{ title }}</div>
</template>

 

 

props도 각 구조에 맞게 사용하면된다.

자 이제 클릭을 받는 버튼과, 클릭 시 클릭 횟수를 노출시켜보겠다.

 

ReactHeader.tsx

import { useState } from "react";

interface Props {
  title: string;
}

export default function ReactHeader(props: Props) {
  const [count, setCount] = useState(0);

  return (
    <div className="bg-pink-200">
      <div className="bold">{props.title}</div>
      <div>{`클릭횟수: ${count}`}</div>
      <button
        className="border-[1px] border-blue-500 bg-white px-4 py-1 rounded-full"
        onClick={() => {
          setCount((prev) => prev + 1);
        }}
      >
        클릭
      </button>
    </div>
  );
}

 

 

이때 클릭 눌러도 클릭횟수는 변경되지 않는다. 

 

왜냐면?

기본적으로 Astro는 모든 UI 구성 요소를 HTML 및 CSS로만 자동 렌더링하고 클라이언트 측 JavaScript를 모두 자동으로 제거하기 때문이라고한다. (참고: https://docs.astro.build/en/concepts/islands/)

 

따라서 UI 구성요소에 JavaScript를 사용하고 싶다면,

client:* 지시문을 추가해야한다.

추가할 경우 JavaScript를 자동으로 빌드하고 번들링한다.

 

그리고 상호작용은 구성 요소 수준에서 구성되므로 사용에 따라 각 구성 요소에 대해 다른 로딩 우선순위를 처리할 수 있다고한다.

예를 들어, client:idle 브라우저가 유휴 상태가 되면 구성 요소에 로드할 수 있고 client:visible 뷰포트에 들어가면 한 번만 구성 요소에 로드할 수 있다. 일단 astro 쓰기로했으면 무조건 필수로 알아둬야할 것 같다. 

 

 

index.astro

---
import ReactHeader from '../components/ReactHeader';
import VueBody from '../components/VueBody.vue';
import Layout from '../layouts/Layout.astro';
---

<Layout>
	 <ReactHeader title="React Header" client:load/>
	 <VueBody title="Vue Body"/>
</Layout>

 

아까 그 코드에 client:load를 넣어주기만하면,, 잘 동작한다.

뭐 만들어보고 싶은건 없어서, 진짜 간단하게 astro란 뭔가 를 찾아보면서 체험?만 해봤다.

 

오늘의 일기(?) 끗~~ 

 

+ Recent posts