KINTO Tech Blog
Development

AstroでSvelte使ってみた - Svelte不定期連載-04

Cover Image for AstroでSvelte使ってみた - Svelte不定期連載-04

AstroでSvelte使ってみた

こんにちは(こんばんは)、Svelte不定期連載その4です。
過去の記事はこちら

  1. SvelteKit + Svelte を1年間くらい使ってみた知見など※SvelteKit メジャーリリース対応済み
  2. Svelteと他JSフレームワークとの比較 - Svelte不定期連載-01
  3. Svelteでユニットテスト - Svelte不定期連載-02
  4. SvelteでStorybookを使ってみる - Svelte不定期連載-03

今回はAstroでSvelte使ってみたの回です。

今回はSvelte連載ではあるものの、少し毛色を変えてみます。

巷を騒がせているAstroというフレームワークをご存知でしょうか。

デフォルトでクライアントサイドのJavaScriptを一切使用せずにウェブサイトを構築する、といったフレームワークです。デフォルトではJavaScriptを読み込ませずに、コンポーネントに明示的な指定をすることでJavaScriptが読み込まれます。Astroではアイランドというネーミングで親しまれています。また公式にもある通り、色々なフレームワークをAstroにマウントして使用することが出来ます(!)

https://astro.build/

Astroの特徴を掻い摘んでみます。

  • ゼロJavaScript
  • マルチページアプリケーション(MPA)
  • 様々なUIフレームワークをAstro上にインテグレーションできる

今回はAstro上でSvelteを動かしてみましょう。propsやバインディングなど色々試してみようと思います。

  • 環境用意
  • AstroにSvelteコンポーネントをimport
  • AstroとSvelteでpropsしてみる
  • AstroとSvleteバインディングで行う

環境用意

AstroとSvelteをインストールしてみる

yarn create astro astro-svelte

Astroのcliを用いて astro-svelteディレクトリにAstroをインストールします。

これでAstroを動かす用意は出来ましたが、これだけではSvelteを使えません。

次にAstro上でSvelteを動かせるようにSvelteとAstro用のSvelteモジュールをインストールしましょう。

yarn add @astrojs/svelte svelte

Astro + Svelteを動かすモジュールが揃いましたので、AstroのConfigファイルであるastro.config.mjsにSvelteを使う旨を書きます。これでAstro上でSvelteを動かす準備ができました。

CLIのおかげでとても手順が少なくてEASYです。

astro.config.mjs
import { defineConfig } from 'astro/config';
// ここを追加
import svelte from '@astrojs/svelte';

// https://astro.build/config
export default defineConfig({

 // ここを追加
  integrations: [svelte()],
});

用意出来たので実際にAstro上でSvelteを動かしてみましょう。

AstroにSvelteコンポーネントをimport

src/components/Sample.Svelte
<script>
  let text = 'Svelte'
</script>

<p>{text}</p>

まずは子となるSvelteコンポーネントを作りました。

<p>タグの中にSvelteという文字列が挿入されるコンポーネントです。

では次にAstroの親コンポーネントにSvelteコンポーネントをimportします。

src/pages/index.astro
---
import Sample from '../components/Sample.svelte'
---

<Sample />

表示されましたね、とても簡単。というかすごいですね…!

AstroはMPAなのでルーティングだけAstroに任せてコンポーネントはSvelteみたいな使い方も出来そうです。

AstroとSvelteでpropsしてみる

先程のSvelteコンポーネントの値をexportします。

src/components/Sample.Svelte
<script>
  export let text = ''
</script>

<p>{text}</p>

Astro側で文字列を挿入します。

src/pages/index.astro
---
import Sample from '../components/Sample.svelte'
---

<Sample text="Svelte" />

同じようにSvelteという文字列が表示されました。

では、逆にSvelteを親としてPropsはできるのでしょうか。試してみます。

Astroの子コンポーネントを定義して…

src/components/Child.astro
---
export interface Props {
  astrotext: ''
}
const {astrotext} = Astro.props
---

<p>{astrotext}</p>

Svelteのコンポーネントで読み込む!

src/components/Sample.svelte

<script>
  import Child from './Child.astro'
  export let text = ''
</script>

<p>{text}</p>
<Child astrotext="Svlete" />

NGでした。

どうやら親はAstroである必要ありそうです。

では親も子もSvelteの場合はどうでしょう。

まずSvelteの子コンポーネントを作ります。

src/components/SvelteChild.svelte
<script>
  export let svelteChild = ''
</script>

<p>{svelteChild}</p>

それをSvelteの親コンポーネントで定義…!

src/components/Sample.Svelte
<script>
  import SvelteChild from "./SvelteChild.svelte";
  export let text = ''
</script>

<p>{text}</p>
<SvelteChild svelteChild="SvelteChild" />

無事に表示されました!

当たり前といっちゃあたりまえなのですがSvelte to Svelteはいけるようです。

またpage配下のファイルも*.astroファイルである必要がありそうです。

NGケース

  • src/pages/+page.svelte
  • src/pages/index.svelte

異なるUIフレームワーク拡張子のファイルをimportするには、*.astroが親である必要があることが判明しました。

SvleteのバインディングをAstroで行う

最後にバインディングを行ってみます。

Svelteでバインディングします。

src/components/Sample.svelte
<script>
  export let text = ''
	let name = '';
</script>

<input bind:value={name}>
<p>{name}</p>
<p>{text}</p>

nameという文字列部分がバインディングされていく想定です。

src/page/index.astroは変わらないので画面を見てみます。

入力しても反映されません・・・。

Astroでは、一部のクライアントサイド特有の機能(例えばこのようなインプットフィールドへのユーザー入力)はデフォルトでは機能しません。

これらの機能を利用したい場合は、import しているComponentに対してAstroのclient:loadディレクティブを使用することでバインディングが可能になります。

src/page/index.astro
---
import Sample from '../components/Sample.svelte'
---

<Sample text="Svelte" client:load />

無事に動きました。

clientディレクティブも:loadだけではないので色々試してみると面白いかもです。
https://docs.astro.build/ja/reference/directives-reference/#client-directives

まとめ

本当に動くの・・・?みたいな半信半疑で始めましたがAstro x UIフレームワーク
プロダクトで使えそうなくらいの実用性がありますね。
コーポレートサイトなどは特にAstro使いやすそうです、ここでは触れてませんがsitemap周りの機能も強力です。

以上、AstroでSvelte使ってみたでした。

次は連載最後、Svelteの実用的なTipsです(経験則)。

Facebook

関連記事 | Related Posts

We are hiring!

【フロントエンドエンジニア(コンテンツ開発)】新車サブスク開発G/東京

新車サブスク開発グループについてTOYOTAのクルマのサブスクリプションサービスである『 KINTO ONE 』のWebサイトの開発、運用をしています。​業務内容トヨタグループの金融、モビリティサービスの内製開発組織である同社にて、自社サービスである、クルマのサブスクリプションサービス『KINTO ONE』のWebサイトコンテンツの開発・運用業務を担っていただきます。

フロントエンドエンジニア(レコメンドシステム)/DX開発G/東京

DX開発グループについてKINTO ONE売上拡大を目的とした、新しいクルマの買い方を提案するプロジェクトチームによるレコメンド&パーソナライズシステム開発、全国約3,600店舗の販売店に対するテクノロジーを用いたソリューション提案のためのシステム開発と、『 KINTOマガジン...