🚀

爆速Webサイトが作成できるAstroを触ってみた

2022/11/03に公開約10,900字

Astroとは?

AstroとはWebサイトを作成するために用意されたWebフレームワークで、
ビルド時にJavaScriptを排除することによって高速なWebサイトを作成することが可能なようです。
今回はセットアップと簡単なAstroコンポーネントを作成して表示するところまでをやってみたいと思います。

https://astro.build/

プロジェクトの作成

# npm
npm create astro@latest

# yarn
yarn create astro

プロジェクト名を聞かれますので、今回はsampleにしておきます。

? Where would you like to create your new project? › sample

1番上のa few best practices (recommended)を選択しました。

? How would you like to setup your new project? › - Use arrow-keys. Return to submit.
❯   a few best practices (recommended)
    a personal website starter kit
    an empty project

依存関係をインストールしますか?
yを入力します。

? Would you like to install yarn dependencies? (recommended) › (Y/n)

新しいgitリポジトリを初期化しますか?
yを入力します。

Would you like to initialize a new git repository? (optional) › (Y/n)

TypeScriptをどのようにセットアップしますか?
(TypeScriptの型チェックの厳しさを選択します。)
Strictを選択しました。

? How would you like to setup TypeScript? › - Use arrow-keys. Return to submit.
❯   Strict - (recommended)
    Strictest
    Relaxed
    Help me choose

ここまででプロジェクトのセットアップは完了です!

VSCodeの拡張機能をインストール

拡張子が.astroのファイルはハイライトがされません。
なので、最初にVSCodeの拡張機能Astroをインストールしておきます。
https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode

開発モードで起動

# npm
npm run dev

# yarn
yarn dev

sample配下でコマンドを実行します。
http://localhost:3000/にアクセスをして、以下のデフォルト画面が表示されます。

必要のない記述・ファイルを削除する

public/favicon.svg
ファイルを削除
src/components/Card.astro
ファイルを削除
src/layouts/Layout.astro
---
export interface Props {
	title: string;
}

const { title } = Astro.props;
---

 <!DOCTYPE html>
-  <html lang="en">
+ <html lang="ja">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width" />
- 		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="generator" content={Astro.generator} />
		<title>{title}</title>
	</head>
	<body>
		<slot />
	</body>
 </html>
- <style is:global>
- 	:root {
- 		--accent: 124, 58, 237;
- 		--accent-gradient: linear-gradient(45deg, rgb(var(--accent)), - #da62c4 30%, white 60%);
- 	}
- 	html {
- 		font-family: system-ui, sans-serif;
- 		background-color: #F6F6F6;
- 	}
- 	code {
- 		font-family: Menlo, Monaco, Lucida Console, Liberation Mono, - DejaVu Sans Mono,
- 			Bitstream Vera Sans Mono, Courier New, monospace;
- 	}
- </style>
src/pages/index.astro
---
import Layout from '../layouts/Layout.astro';
- import Card from '../components/Card.astro';
---

-  <Layout title="Welcome to Astro.">
+ <Layout title="タイトル">
- 	<main>
- 		<h1>Welcome to <span class="text-gradient">Astro</span></h1>
- 		<p class="instructions">
- 			To get started, open the directory <code>src/pages</code> in your project.<br />
- 			<strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above.
- 		</p>
- 		<ul role="list" class="link-card-grid">
- 			<Card
- 				href="https://docs.astro.build/"
- 				title="Documentation"
- 				body="Learn how Astro works and explore the official API docs."
- 			/>
- 			<Card
- 				href="https://astro.build/integrations/"
- 				title="Integrations"
- 				body="Supercharge your project with new frameworks and libraries."
- 			/>
- 			<Card
- 				href="https://astro.build/themes/"
- 				title="Themes"
- 				body="Explore a galaxy of community-built starter themes."
- 			/>
- 			<Card
- 				href="https://astro.build/chat/"
- 				title="Community"
- 				body="Come say hi to our amazing Discord community. ❤️"
- 			/>
- 		</ul>
- 	</main>
 </Layout>

-  <style>
- 	main {
- 		margin: auto;
- 		padding: 1.5rem;
- 		max-width: 60ch;
- 	}
- 	h1 {
- 		font-size: 3rem;
- 		font-weight: 800;
- 		margin: 0;
- 	}
- 	.text-gradient {
- 		background-image: var(--accent-gradient);
- 		-webkit-background-clip: text;
- 		-webkit-text-fill-color: transparent;
- 		background-size: 400%;
- 		background-position: 0%;
- 	}
- 	.instructions {
- 		line-height: 1.6;
- 		margin: 1rem 0;
- 		border: 1px solid rgba(var(--accent), 25%);
- 		background-color: white;
- 		padding: 1rem;
- 		border-radius: 0.4rem;
- 	}
- 	.instructions code {
- 		font-size: 0.875em;
- 		font-weight: bold;
- 		background: rgba(var(--accent), 12%);
- 		color: rgb(var(--accent));
- 		border-radius: 4px;
- 		padding: 0.3em 0.45em;
- 	}
- 	.instructions strong {
- 		color: rgb(var(--accent));
- 	}
- 	.link-card-grid {
- 		display: grid;
- 		grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
- 		gap: 1rem;
- 		padding: 0;
- 	}
-  </style>

Astroコンポーネントを作成してみる

Header・Footerを作成

src/layouts/Header.astro
+ ---

+ ---

+ <header class="header">
+   Header
+ </header>

+ <style>
+   .header {
+     font-size: 28px;
+     font-weight: bold;
+     color: #FF7E33;
+     background-color: #2A233E;
+     padding: 20px;
+   }
+   .title {
+     margin: 0;
+   }
+ </style>
src/layouts/Footer.astro
+ ---

+ ---

+ <footer class="footer">
+   Footer
+ </footer>

+ <style>
+   .footer {
+     font-size: 28px;
+     font-weight: bold;
+     color: #FF7E33;
+     background-color: #2A233E;
+     padding: 20px;
+   }
+ </style>

src/layouts/Header.astrosrc/layouts/Footer.astroそれぞれをsrc/layouts/Layout.astroで読み込む。

src/layouts/Layout.astro
---
+ import Footer from './Footer.astro';
+ import Header from './Header.astro';

export interface Props {
	title: string;
}

const { title } = Astro.props;
---

 <!DOCTYPE html>
 <html lang="ja">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width" />
		<meta name="generator" content={Astro.generator} />
		<title>{title}</title>
	</head>
	<body>
+ 		<Header />
		<slot />
+ 		<Footer />
	</body>
 </html>


作成したHeaderとFooterを表示させることができました🎉

<slot /> 要素を使用してMainコンポーネントを作成してみる

<slot />は公式ドキュメントで以下のように説明されています。

<slot /> 要素は外部HTMLコンテンツのプレースホルダーで、他のファイルからコンポーネントテンプレートに子要素を注入(はめ込む=スロット)できます。
デフォルトでは、コンポーネントに渡されたすべての子要素は、その <slot /> 内でレンダリングされます。

説明だけだと分かりづらいかと思いますので、実際にコードを書いてみます。

Mainコンポーネントを作成

src/layouts/Main.astro
+ ---

+ ---

+ <main class="main">
+   <slot />
+ </main>

+ <style>
+   .main {
+     font-size: 28px;
+     font-weight: bold;
+     color: #FF7E33;
+   }
+ </style>

src/pages/index.astroで読み込みをする

src/pages/index.astro
---
import Layout from '../layouts/Layout.astro';
+ import Main from '../layouts/Main.astro';
---

 <Layout title="タイトル">
+	<Main>
+		<p>Main</p>
+	</Main>
 </Layout>

Mainコンポーネントの表示が確認できました🎉
作成したコンポーネントのタグで囲まれた中に記述されている内容が、<slot />になっていることが分かります。

Buttonコンポーネントを作成

ここではpropsをButtonコンポーネントに渡して、クリックするとアラートが表示されるようにしてみます。

src/components/Button.astro
+ ---
+ const { title } = Astro.props;
+ ---

+ <button type="button" class="button">
  {title}
+ </button>

+ <style>
+   .button {
+     display: block;
+     width: 200px;
+     padding: 10px;
+     border: none;
+     background-color: #2A233E;
+     color: #FF7E33;
+     font-size: 18px;
+     font-weight: bold;
+     margin-bottom: 40px;
+     cursor: pointer;
+   }
+ </style>

+ <script>
+   const button = document.querySelector(".button");
+   button.addEventListener('click',()=>{
+     alert('クリックされました');
+   })
+ </script>

src/pages/index.astroでButtonコンポーネントを読み込んで、propsを渡す。

---
import Button from '../components/Button.astro';
import Layout from '../layouts/Layout.astro';
import Main from '../layouts/Main.astro';
---
 <Layout title="タイトル">
	<Main>
		<p>Main</p>
+ 		<Button title="ボタン" />
	</Main>
 </Layout>

Buttonコンポーネントの表示とクリックするとアラートがでることが確認できました🎉

画像を表示してみる

今回はAstroの公式サイトにある画像を使用してみます。
ダウンロードしたfull-logo-light.pngを作成したpublic/imagesフォルダの中に配置します。

src/pages/index.astro
---
import Button from '../components/Button.astro';
import Layout from '../layouts/Layout.astro';
import Main from '../layouts/Main.astro';
---

 <Layout title="タイトル">
 <Main>
		<p>Main</p>
		<Button title="ボタン" />
+ 		<img src="/images/full-logo-light.png" alt="" width="500">
	</Main>
 </Layout>

画像の表示が確認できました🎉

Scss(.scss/.sass)導入

sassをインストールします。

#npm
npm install -D sass

#yarn
yarn add -D sass

.astroファイルで<style lang="scss">または<style lang="sass">を追加することによって使用できるようになります。

<style lang="scss">

</style>

Tailwind CSS導入

Tailwind CSSをインストールします

# npm
npm install @astrojs/tailwind tailwindcss
# yarn
yarn add -D @astrojs/tailwind tailwindcss

tailwind.config.cjsを作成

npx tailwindcss init

設定ファイルに追加

astro.config.mjs
import { defineConfig } from "astro/config";
+ import tailwind from "@astrojs/tailwind";

// https://astro.build/config

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

設定ファイルに追加

tailwind.config.cjs
/** @type {import('tailwindcss').Config} */
module.exports = {
+   content: ["src/**/*.{html,js,jsx,astro}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

これだけでTailwind CSSのスタイルを当てると反映されることが確認できます。

React導入

reactをインストールすると使用可能になります。

npx astro add react

動作確認

components/Counter.jsxを作成します。

src/components/Counter.jsx
+ import {useState} from 'react';

+ export const Counter = () => {
+   const [count,setCount] = useState(0);

+   const countUp = () => {
+     setCount(count + 1);
+   }

+   const countDown = () => {
+     setCount(count - 1);
+   }

+   return (
+     <>
+       <p>{count}</p>
+       <button type="button" onClick={countUp}>+</button>
+       <button type="button" onClick={countDown}>-</button>
+     </>
+   )
+ }

src/pages/index.astroで作成したcomponents/Counter.jsxをimportします。

src/pages/index.astro
---
+ import Counter from '../components/Counter.jsx';
import Button from '../components/Button.astro';
import Layout from '../layouts/Layout.astro';
import Main from '../layouts/Main.astro';
---

 <Layout title="タイトル">
 <Main>
		<p>Main</p>
		<Button title="ボタン" />
		<img src="/images/full-logo-light.png" alt="" width="500">
+ 		<Counter client:load /> 

	</Main>
 </Layout>

client:loadを設定後、カウントアップが正常に動作していることが確認できます。

ビルド

# npm
npm run build

# yarn
yarn build

ビルド実行後にプロジェクトフォルダ直下にdistフォルダが作成されます。

まとめ

今回は試しに触ってみた程度の内容ですが、
今後Web制作でも使いやすいようにカスタマイズなどしていけたらないいなと思いました。
公式ドキュメントも日本語で翻訳されていたりなど分かりやすく、徐々に使いこなせるようになりたいです!

Discussion

ログインするとコメントできます