Sota Tech Blog.

Astroを使ってみる - Typescriptを利用したブログを作るハンズオン - Vol.1投稿日: 2023年 3月15日

Astroの本領発揮

実際に公式ドキュメントを参考にしつつ作っていく
お手本の部分と大き違うところは今回のアプリはデフォルトで用意されているtypescriptを利用している
全体像としては少し長くなりそうになるため何回かに分けて投稿してく
前回のAstroの記事について
参考サイト

完成予定コード

何かわからないところがあればここをみてほしい
Github

開発環境の構築

エディターはVScodeを利用します。
※ nodeのバージョンについてはv16.12.0以上を利用してください

$ node -v
v19.8.0

雛形の作成

ここでは

  1. 作成するディレクトリを指定
  2. どうやってプロジェクトを始めるか
  3. 依存するパッケージをインストールするか
  4. TSを使う予定はあるか
  5. 使う場合の型の厳しさを指定

今回では以下のようにしています。

$ npm create astro@latest
------------
╭─────╮  Houston:
│ ◠ ◡ ◠  Let's build something awesome!
╰─────╯
 astro   v2.1.3 Launch sequence initiated.
------------
   dir   Where should we create your new project?
astro-handson
------------
   tmpl   How would you like to start your new project?
         ○ Include sample files 
         ○ Use blog template 
         ● Empty 
------------
  deps   Install dependencies? (recommended)
         ● Yes  ○ No 
------------
    ts   Do you plan to write TypeScript?
         ● Yes  ○ No 
------------
 use   How strict should TypeScript be?
         ● Strict (recommended)
         ○ Strictest 
         ○ Relaxed 
------------
 git   Initialize a new git repository? (optional)
         ● Yes  ○ No 
------------
$ cd astro-handson
------------
$ npm run dev

aboutページを作成

前回をの述べたようにダイナミックルーティングの仕様になっているため、pageフォルダ内でabout.astroファイルを作成することで自動でルーティングしてくれる
astroファイルではNextjsのようなLinkタグは必要ない

about.astro

<body>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <h1>About Page</h1>
</body>

マークダウン周りの作成

pagesフォルダの中にpostsフォルダを作成する
さらに作成したフォルダ内でpost-1.mdファイルを作成する
マークダウンのチートシート

pages/posts/post-1.md

---
title: 'Dev sota tech blog'
pubDate: 2023-03-16
description: 'Sample hands-on new blog article'
author: 'sota'
tags: ['programming', 'hands-on', 'astro']
---
# Dev sota tech blog
最初の俺のブログの記事となる
もちろんハンズオンということをお忘れなく
---
This will be my first blog post.
Don't forget, of course, that it's hands-on.
## Profile me
今日はラーメンをしっかりといただいた
好きな食べ物はホタテ
---
I had a good bowl of ramen today.
My favorite food is scallops.

blogファイルの作成

pagesフォルダにblogファイルを作成する。

blog.astro

<body>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="/blog">Blog</a>
  <ul>
    <li><a href="/posts/post-1">Post - 1</a></li>
  </ul>
</body>

追加でmdファイルを追加

md .... markdownのこと
内容は適当で大丈夫

blog.astro

<!-- 追加 -->
    <li><a href="/posts/post-2">Post - 2</a></li>
    <li><a href="/posts/post-3">Post - 3</a></li>
<!-- --------- -->

定数を利用

以前記述したコードフェンスという概念に基づいて作成する
肌間だが慣れるとしっかりと分割してあってかなり記述しやすくなっているような感じがする
JSXとほんとにそっくり

about.astro

---
const pageTitle: string = 'About page';
interface Personal {
  firstName: string;
  lastName: string;
  country: string;
  hobbies: string[];
}
const personal: Personal = {
  firstName: 'sample',
  lastName: 'taro',
  country: 'japan',
  hobbies: ['soccer', 'react'],
};
const one: number = 1;
const flag: boolean = false;
---
<body>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="blog">Blog</a>
  <h1>{pageTitle}</h1>
  <p>{personal.firstName}</p>
  <p>{personal.lastName}</p>
  <p>{personal.country}</p>
  <ol>
    {personal.hobbies.map((hobby) => <li>{hobby}</li>)}
  </ol>
  {one === 1 ? <p>Yes</p> : <p>No</p>}
  {flag && <p>true</p>}
</body>

デザインまわり

スコープ内の適用と全体への適用の二つがある
普段はtailwindを利用しているので少し久しぶりな感じがした

スコープ内
about.astro

const countryColor: string = 'navy';
---
<body>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="blog">Blog</a>
  <h1>{pageTitle}</h1>
  <style define:vars={{ countryColor }}>
    h1 {
      color: aquamarine;
      font-size: 4rem;
    }
    .list {
      /* 直接 - direct */
      /* color: cadetblue; */
      /* 定数 - const */
      color: var(--countryColor);
      font-weight: bold;
    }
  </style>
  <p>{personal.firstName}</p>
  <p>{personal.lastName}</p>
  <p>{personal.country}</p>
  <ol>
    {personal.hobbies.map((hobby) => <li class="list">{hobby}</li>)}
  </ol>
  {one === 1 ? <p>Yes</p> : <p>No</p>}
  {flag && <p>true</p>}
</body>

グローバル

srcファイルの中にstyles/global.cssファイルを作成

src/styles/global.css

html {
  background-color: #f1f5f9;
  font-family: sans-serif;
}


body {
  margin: 0 auto;
  width: 100%;
  max-width: 80ch;
  padding: 1rem;
  line-height: 1.5;
}


* {
  box-sizing: border-box;
}


h1 {
  margin: 1rem 0;
  font-size: 2.5rem;
}

about.astro

import '../styles/global.css';

匿名でコメント