View more

DEPARTフロントエンドエンジニアの間で話題のAstroをご紹介

Blog

DEPARTフロントエンドエンジニアの間で話題のAstroをご紹介

Jamstackにおける技術選定として、より静的サイトジェネレートを意識したフレームワークAstroをご紹介。 今後のWebサイト制作における大きなパラダイムになる可能性のあるツールやその動向を追っていくことで、より柔軟に新たな価値を提供できるように常に情報をアップデートしています。
DEPARTフロントエンドエンジニアの間で話題のAstroをご紹介

フォーカスしたいもの

Javascriptフレームワークを使うと制作が効率化される部分がありますが、SPAやSSRをしたいわけではないプロジェクトではなかなか使いづらい場合があると思います。

もっとライトでいいのに、でもコンポーネント駆動で開発したい。 そんな思いを実現できるのがAstroという静的サイトジェネレーターです。

※フルスタックなJavascriptフレームワークが悪いということが言いたいわけではありませんので、その点に関してはご理解いただければと思います。

Astroとは

最近のJavascriptフレームワーク、特にJamstack界隈では、Next.jsやNuxt.jsほどの機能が要らないけど高速でかつ同様のコンポーネント駆動で開発できるシステムが求められていました。

Next.jsやNuxt.jsは非常に強力で、やりたいことのほとんどのことが可能ではあるのですが、Jamstackをしようと思った時には必要ないものや、逆にJamstackだからこそ必要になる機能もあり、生成されたソースコードに多くのJavascriptが含まれてしまったりすることがあります。

なぜならば、Jamstack(静的サイトジェネレート)を目的として作られたわけではないからです。

 

そこでAstroの登場です。

Astroは独自のテンプレート構文を持ちながら、必要に応じてReactやVue.jsのコンポーネントも使えるように設計されています。

独自のテンプレート構文と言っても、ReactのJSXと同じように書けますし、Vue.jsのようにHTMLを書いているような感覚的なハードルの低さもあります。

また、11tyのような従来からあった静的サイトジェネレート用のライブラリのような設定の書き方もできたりと、さまざまなフレームワークのいいとこ取りのような構文になっています。

みんなが使いやすいように、そしてJamstackでの悩みにフォーカスして作られています。

公式のページを見ていただくとより意図が汲み取れると思います。

 

https://docs.astro.build/ja/concepts/why-astro/

https://docs.astro.build/ja/concepts/mpa-vs-spa/

Astroの特徴

コンポーネント駆動でも必要なければJavascriptは生成されない

冒頭でも書いていますが、Next.jsやNuxt.jsでJamstackをすることが多いと思いますが、

これらのフレームワークはJamstackを目的として開発されたわけではなくSPAもSSRも構築が可能です。

ですので機能を実装していなくても多少のJavascriptが必要になってしまいますし、それが高速化の妨げになる可能性もあります。

 

Astroは静的なコンポーネントとして定義し、それらをさまざまなページで使用してもJavascriptでの機能を作成していなければHTMLとCSSのみしか生成されません。

Javascriptフレームワークでのコンポーネント駆動開発そのままに静的サイトが制作できます。

そして静的であるからこそ、高速なWebサイトが構築可能になります。

 

ページでの記述

<Text
  tag="h3"
  text="タグやテキストをPropsで渡することも可能"
  className="text-3xl text-purple-700"
/>

コンポーネント内の記述

---
export interface Props {
  tag: string
  text: string
  className: string
}

const { tag, text, className } = Astro.props
const El = tag
---

<El class:list={[className, { 'is-active': true }]}>{text}</El>

出力されたHTML

<!-- 動的にタグを変更 -->
<h3 class="text-3xl text-purple-700 astro-M2SCGHYM is-active">タグやテキストをPropsで渡することも可能</h3>

 

ReactやVue.jsのコンポーネントを使うことができる

AstroはReactやVue.jsのコンポーネントを使うことができます。

その他SvelteやSolid.jsやLitなど徐々に人気が出てきているフレームワークのコンポーネントも使うことができます。

 

ただし気をつけなくてはいけないことがあります。

他のフレームワークのコンポーネントを使う場合にはJavascriptが読み込まれます。

これはそれぞれのフレームワークをそれと同じように動作させるために必要なJavascriptになるのですが、Astro Islandsという機能として提供されています。

https://docs.astro.build/ja/concepts/islands/

 

一部分のみの動的コンポーネントとしてや、今までの資産としてのソースコードの活用という場合には非常に便利ですので、ラーニングコストが気になる場合にも検討してみると良いと思います。

 

ページ側記述

<button>
  <VueButton rounded="fill" size="xl">ボタン</VueButton>
</button>

Vueコンポーネント Button.vue

<script lang="ts" setup>
/**
 * Vue Button
 */
import { computed } from 'vue'

export type Size = 's' | 'm' | 'l' | 'xl'
export interface Props {
  plain?: boolean
  size?: Size
  color?: string
  rounded?: string
}

const props = withDefaults(defineProps<Props>(), {
  plain: false,
  size: 'm',
  color: 'primary',
  rounded: '',
})

const className = computed(() => {
  return [
    'button',
    props.plain ? `plain` : '',
    `size-${props.size}`,
    `color-${props.color}`,
    props.rounded ? `rounded-${props.rounded}` : '',
  ]
})
</script>

<template>
  <span :class="className">
    <slot />
  </span>
</template>

<style lang="scss" scoped>
@import 'Button.scss';
</style>

生成されたボタン部分

<button class="astro-M2SCGHYM">
  <span class="button size-xl color-primary rounded-fill astro-M2SCGHYM" data-v-26d330cb><!--[-->ボタン<!--]--></span>
</button>

jsが生成される

// jsが生成される
../dist/client.ddfd679e.js

※このボタンのケースでは、静的なボタンなのでこのjsを読み込まなくても静的にボタンのスタイルは生成されます。

 

ルーティング機能もあり複数ページも可能

複数ページを作成できますので、もちろんルーティング機能があります。

Nuxt.jsなどと似た書き方で動的パスにマッチさせてページを生成することが可能ですので、従来のJamstackの手法をそのまま応用することが可能です。

 

[work].astroとして値を設定

pages
├── index.astro
├── works
│   └── [work].astro
└── works.astro
 

works.astro

---
import { getWorks } from '@/ts/fetch-works'

// API fetch
const works = await getWorks()
---

<ul>
  {
    works.map((work: { slug: any; title: unknown }) => (
      <li>
        <a href={`/works/${work.slug}`} class="text-blue-700 underline">
          {work.title}
        </a>
      </li>
    ))
  }
</ul>
 

fetch-works.ts

const endpoint = '<https://XXXXXXX.xxx>'

// 実績
const getWorks = async () => {
  const response = await fetch(endpoint)
  return await response.json()
}
 

 

SPA状態ではなくMPA状態での画面表示

Astroのコンセプトでもあるのですが、JamstackをするのになにもSPAである必要はないじゃないか。という思想で作られていますので、生成されたサイトはSPAではなくMPA(マルチページアプリケーション)になります。

https://docs.astro.build/ja/concepts/mpa-vs-spa/

 

大きな違いは、SPAだと前の画面の要素をアニメーションさせたり、残したまま遷移するようなことができますが、MPAはよくある普通のWebサイトになります。

そういった演出や機能が必ずしも必要なければAstroは選択肢に入るのではないでしょうか?

公式のページにも書かれていますが、どちらが良い悪いではなく、MPAでよければAstroを使用し、SPAがよければそれに向いているフレームワークを使用する方が良いということになります。

 

まだ発展途上

Astroや同様の考え方のフレームワークの領域はまだまだ登場したばかりです。

Astro自身も頻繁にアップデートされていますが、Astroに注目している開発者は同様に追従してくる後発のフレームワークにも注目しています。

もうすでにコンポーネント駆動でWebサイトを作ることは問題なく可能ですし、通常のWebサイトで求められる条件はクリアしているでしょう。

ですが今後より求められる機能や、運用状況によってプラグインの開発や、クラウドサービスなどとの連携もされていくと思います。

プロジェクト固有の状況ではまだ使用できない場合もあると思いますが、新規構築のWebサイトであれば選定の一つに加えてみてはいかがでしょう?

まとめ

今回はAstroの紹介をしましたが、Javascriptフレームワークは時代ややりたいことに合わせて常に進化し、また新しいものも生まれています。

Jamstackの目指すものとして、コンポーネント駆動で静的に高速なWebサイトを実現しようという流れは自然だと思いますし、それがフルスタックなJavascriptフレームワークとは方向性が違い、新たな流れができたのだと思います。

これからもそういった目的に合わせた最適なフレームワークが生まれていくと思いますし、それらを使って新たな価値を提供できるように常に情報をアップデートしていければと思っています。

株式会社デパートでは、Astroを使った制作も順次おこなっていきますので、ご興味がありましたらお問い合せください。

デパート採用情報

株式会社デパートでは一緒に働く仲間を募集しています