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
dir 프로젝트 위치와 프로젝트명
tmpl 어떤 템플릿 쓸건지 (A basic, minimal starter가 추천이라 그냥했다)
deps 종속성 관련 설치하고
git 레포지토리는 연결하지않았다
그러면 astro.config.mjs 가 포함된 astro 프로젝트가 생성된다.
타입스크립트 https://docs.astro.build/en/guides/typescript/
위 문서대로 따라해보자.
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/
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란 뭔가 를 찾아보면서 체험?만 해봤다.
오늘의 일기(?) 끗~~
'Javascript' 카테고리의 다른 글
구글캘린더 - 팀원 일정 긁어와서 휴가 모아보기 캘린더 만들기 (0) | 2025.01.10 |
---|---|
숫자 천 단위 마다 콤마 찍어주세요 (1,000) 소수점 숫자도 나와야해요. RegExr, toLocaleString (정규 표현식_Lookahead/Lookbehind_사파리 lookbehind 오류에 대해서..) (0) | 2022.06.22 |
(lodash) 값 타입에 따라 isUndefined, isEmpty 뭐를 써야할까? (0) | 2022.01.17 |
CORS 에러를 해결하자, 어떻게? JSONP로! (0) | 2021.11.01 |
마우스로 창을 움직여보자! (0) | 2021.02.01 |
[jQuery기초] ajax (0) | 2020.06.30 |
[jQuery기초] 요소조작_이벤트_slice_trim_extend_each (0) | 2020.06.30 |
[jQuery기초] 요소조작_이벤트_replaceAll_replaceWith (0) | 2020.06.30 |