Svelte アプリケーションをデプロイするには?
この記事では、Svelteを使ってWebアプリケーションを構築し、Back4appコンテナを使ってデプロイする方法を学ぶ。
Svelteは、リアクティブでダイナミックなWebアプリケーションを開発するためのJavaScriptフレームワークです。Svelteフレームワークを使えば、軽量で高性能なアプリケーションを構築することができます。従来のJavaScriptフレームワークとは異なり、Svelteは多くの重労働をブラウザからビルド段階に移動させるからです。
Contents
プロジェクトの概要インベントリー・トラッカー
本記事では、Back4Appのリアルタイム・データベースと統合したインベントリー・トラッカーをご紹介します。
このアプリケーションは、ユーザーの在庫データを管理し、必要に応じて製品情報を追加、検索、削除することができます。
トラッカーは、商品名、価格、数量などの重要な情報をBack4Appに保存します。
これにより、ユーザーは簡単に在庫を管理・監視し、製品に関する正確で最新の情報を確保することができます。
Svelteアプリケーションの作成
このセクションでは、Vite(フロントエンドフレームワークのビルドツール)を使用してSvelteプロジェクトを作成します。
ターミナルで以下のコマンドを実行することで、SvelteアプリケーションをViteで作成することができます:
npm init vite
このコマンドを実行した後、プロジェクトの名前を指定し、フレームワーク(Svelte)を選択し、フレームワークの好みの言語バリアントを選択する。
こんな感じだ:
上の画像は、Svelteプロジェクトの名前がinventory-trackerで、言語がJavaScriptであることを示している。
次に、Svelteプロジェクトに必要な依存関係をインストールする必要があります。依存関係をインストールするには、プロジェクト・ディレクトリに移動して、以下のコマンドを実行してください:
# Switch to the project directory
cd inventory-tracker
# Install dependencies
npm install
このコマンドを実行すると、プロジェクトに必要な依存関係がすべてインストールされ、IDE上でアプリケーションのビルドを開始できます。
Svelteアプリケーションの構築
このセクションでは、SvelteとBack4appのbackend as a service機能を使って在庫追跡アプリケーションを構築します。
アプリケーションはCRUD(Create、Read、Update、Delete)機能を持ち、データの追加、取得、編集、削除ができます。
Svelteアプリケーションのビルドを開始する前に、svelte-routing
ライブラリをインストールしてください。
svelte-routing
ライブラリは、Svelteアプリケーションにルーティング機能を追加し、シングルページアプリケーション(SPA)を作成できるようにするライブラリです。
以下のコマンドを実行して、svelte-routing
ライブラリをインストールする:
npm i -D svelte-routing
インストールしたら、プロジェクトのsrc
ディレクトリにAddProduct
コンポーネントとHome
コンポーネントを作成します。AddProduct
コンポーネントに、以下のコードを追加します:
<!-- AppProduct.svelte -->
<script>
let product = {
name: "",
quantity: "",
price: "",
}
</script>
<form>
<input type="text" placeholder="Name of Product" bind:value={product.name}>
<input type="number" placeholder="No of Products" bind:value={product.quantity}>
<input type="number" placeholder="Price of Products" bind:value={product.price}>
<div>
<button>Add Product</button>
</div>
</form>
<style>
form{
display: flex;
flex-direction: column;
gap: 2rem;
align-items: center;
}
</style>
上のコードブロックは、商品の詳細を入力するフォームをレンダリングします。このフォームには、テキスト
(名前
) と数値
(数量と
価格
) の 3 つの入力
要素があります。
入力欄には、商品名、商品数、商品価格を入力する。
input
要素のbind:value
属性で、コードブロックは入力の値を指定された製品
オブジェクトのプロパティにバインドします。style
セクションには、このSvelteコンポーネントにスコープされたCSSスタイルが含まれています。
次に、以下のコードブロックをHome
コンポーネントに追加します:
<!-- Home.svelte -->
<script>
import {Link} from "svelte-routing";
</script>
<main>
<p>A way to manage and keep track of products in your inventory</p>
<Link to="/add-products" class="link">Add Products here →</Link>
</main>
<style>
main{
display: flex;
flex-direction: column;
gap: 2rem;
align-items: center;
}
</style>
Home
コンポーネントは、svelte-routing
ライブラリからLink
コンポーネントをインポートします。Link
コンポーネントはユーザーを“/add-products “ルートに誘導します。Link
コンポーネントが実際に動作するように、このルートを定義する必要があります。
ルートを定義するには、App
コンポーネントを開き、以下のコードブロックを追加します:
<!-- App.svelte -->
<script>
import {Route, Router} from "svelte-routing";
import AddProduct from './AddProduct.svelte';
import Home from './Home.svelte';
export let url = "";
</script>
<Router {url}>
<h1>Inventory Tracker</h1>
<div class="container">
<Route path="/" component={Home} />
<Route path="/add-products" component={AddProduct} />
</div>
</Router>
<style>
h1{
text-align: center;
font-family: "Poppins", sans-serif;
margin-block-start: 1rem;
margin-block-end: 6rem;
}
</style>
上記のコードブロックは、svelte-routingから
Route
コンポーネントとRouter
コンポーネントをインポートし、Home
コンポーネントとAddProduct
コンポーネントをインポートして、それぞれのルートを定義しています。
Route
コンポーネントで、アプリケーションの様々なルートを定義します。この場合、Home
ルートとAddProduct
ルートです。
HTMLセクションをルーター・コンポーネントで
囲むと、囲んだコンポーネントのルーティングが初期化されます。
上のコードブロックから、アプリケーションをレンダリングすると、ルートのパスが“/”なので、Home
ルートが最初に表示されます。
次のステップは、アプリケーションのグローバル・スタイルを定義することです。これを行うには、src
ディレクトリ内にstyles
フォルダを作成します。styles
フォルダの中にglobal.css
ファイルを追加します。
以下のコードブロックをglobal.css
ファイルに追加する:
/* global.css */
@import url('<https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap>');
@import url('<https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap>');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
font-family: "Montserrat", sans-serif;
background-color: #1F2124;
color: #FFFFFF;
}
.container{
inline-size: 60%;
margin: auto;
}
.link{
text-decoration: none;
color: inherit;
font-weight: 500;
}
.link:hover{
color: #99BCF6;
}
input{
padding: 1rem;
border-radius: 12px;
outline: none;
border: none;
font-family: "Montserrat", sans-serif;
color: #333333;
inline-size: 100%;
}
button{
padding: 0.7rem 1rem;
border-radius: 10px;
font-weight: 500;
background-color: #FFFFFF;
font-family: "Montserrat", sans-serif;
}
button:hover{
background-color: #99BCF6;
}
スタイルを定義したら、App
コンポーネントのglobal.css
ファイルをインポートして、定義したスタイルをアプリケーションに適用します。これは、App
コンポーネントのスクリプト・
セクションに次のコードを追加することで実行できます:
//App.svelte
import './styles/global.css';
これでSvelteアプリケーションのビルドは完了です。次に、Back4appを使ってアプリケーションのバックエンドを構築します。
Back4appアプリケーションのセットアップ
このセクションでは、Back4app AIエージェントを使用して、アプリケーションのバックエンドとなるBack4appアプリケーションを作成します。
作成にはBack4appアカウントが必要です。お持ちでない場合は、無料で作成できます。
アカウントにログインし、Back4appアカウントダッシュボードのナビゲーションバーにある “AI Agent “リンクをクリックしてください。
AIエージェントにアクセスできたら、AIエージェントにアプリケーションの作成を依頼するプロンプトを入力します。
プロンプトは以下のようなものでなければならない:
Create a new application named inventory-tracker
上のプロンプトにあるように、アプリケーション名を指定する必要があります。AIエージェントはアプリケーションの作成を完了するとすぐに、作成を確認する応答を送信します。
レスポンスには、以下の画像のようなアプリケーションの認証情報も含まれていなければならない。
AIエージェントが提供する様々なクレデンシャルのうち、アプリIDとJavaScriptキーをコピーしてください。これらはSvelteアプリケーションとBack4appアプリケーションを接続するために必要です。
次に、Back4app アプリケーションに在庫クラスを作成します。そのクラスに、名前、数量、価格のカラムを追加します。これを行うには、AIエージェントを使用して、次のプロンプトを記述します:
In the inventory-tracker app, create an inventory class and add a name, price, and quantity column to the class.
下の画像のような反応が返ってくるはずだ。
Svelte UI Back4appバックエンドの準備ができたので、UIをバックエンドに接続します。
SvelteアプリケーションをBack4appに接続する
このセクションでは、SvelteアプリケーションとBack4appアプリケーションを接続します。これにはParse SDKが必要です。
Parse SDKは、ウェブアプリケーションで使用できるバックエンドサービスを提供する開発ツールのセットです。
以下のコマンドを実行して Parse SDK をインストールします:
npm install parse
SDKをインストールした後、App.svelte
ファイルのscriptタグ内に、以下のコードブロックのコードを追加します。
import Parse from 'parse/dist/parse.min.js';
Parse.initialize('YOUR_APP_ID', 'YOUR_JAVASCRIPT_KEY');
Parse.serverURL = '<https://parseapi.back4app.com/>';
YOUR_APPLICATION_ID
」と「YOUR_CLIENT_KEY
」を、先ほどコピーした認証情報に置き換えてください。環境変数を使用して安全に保存してください。
Back4appにデータを追加する
Back4appにデータを追加するには、AddProduct
コンポーネントフォームの入力値を使用します。ユーザーから送信された値を受け取り、Back4appのデータベースに追加します。
AddProduct
コンポーネントのスクリプト
セクションに、addData
関数を作成します。この関数には、商品の詳細をBack4appに追加するロジックが含まれます。
こんな感じだ:
// AddProduct.svelte
import Parse from 'parse/dist/parse.min.js';
import { navigate } from "svelte-routing";
let addData = (event) => {
event.preventDefault();
try {
const Inventory = new Parse.Object("Inventory");
Inventory.set("name", product.name);
Inventory.set("quantity", +product.quantity);
Inventory.set("price", +product.price);
Inventory.save().then(() => {
console.log("New Product added successfully");
navigate("/", { replace: true });
});
} catch (error) {
console.log(error);
}
};
上のコード・ブロックでは、addData
関数がInventory
クラスの新しいParseオブジェクトInventoryを
作成しています。
これは、オブジェクトをデータベースに保存する前に、name
、quantity
、price
フィールドの値を、product
プロパティの対応する値に設定します。
product.quantityと
product.price
プロパティの前に単項のプラス(+)演算子があることに注意。
演算子は、プロパティを数値型に変換します。addData
関数を、AddProduct
コンポーネントのフォームにsubmit
イベント・ハンドラでバインドします。
これにより、ユーザーがフォームを送信するたびにaddData
関数がトリガーされます。
関数をsubmit
イベントハンドラを持つフォームにバインドするには、AddProduct
コンポーネントのフォームを以下のフォームに置き換えます:
<!--AddProduct.svelte-->
<form on:submit={addData}>
<input type="text" placeholder="Name of Product" bind:value={product.name}>
<input type="number" placeholder="No of Products" bind:value={product.quantity}>
<input type="number" placeholder="Price of Products" bind:value={product.price}>
<div>
<button>Add Product</button>
</div>
</form>
Back4appからデータを取得する
Back4appからデータを取得するには、前節でBack4appアプリケーションに保存したParseオブジェクトにアクセスし、オブジェクト内の値を取得する。
データを取得する前に、アプリケーションのsrc
ディレクトリにCard
コンポーネントを作成します。このコンポーネントがBack4appから取得したデータのルックアンドフィールを決定します。
コンポーネント・ファイルに次のコードを書く:
<!-- Card.svelte -->
<script>
export let name = '';
export let quantity = 0;
export let price = 0;
</script>
<div class="card">
<h3>{name}</h3>
<div class="details">
<p>Price: ${price}</p>
<p>Quantity: {quantity == 0 ? "out of stock" : quantity}</p>
</div>
<div>
<button>Delete</button>
</div>
</div>
<style>
.card{
display: flex;
flex-direction: column;
gap: 1.9rem;
padding: 1rem;
border-radius: 12px;
background-color: #e2e2e2;
color: #1F2124;;
inline-size: 100%;
}
.details{
display: flex;
gap: 3rem;
}
.details p{
font-size: 14px;
font-weight: 500;
color: #888888;
}
</style>
Card
コンポーネントは、商品の名前、数量、価格を表示します。上記のコードブロックの3つのプロップ(名前
、数量
、価格
)を使用して、親コンポーネントからこれらの値を取得します。
次に、Home
コンポーネントのscript
タグに、以下のコードブロックのコードを追加します:
//Home.svelte
import { onMount } from "svelte";
import Parse from "parse/dist/parse.min.js";
let products = [];
const fetchProducts = async () => {
try {
const query = new Parse.Query("Inventory");
const productsData = await query.find();
products = productsData;
} catch (error) {
console.log(error);
}
};
onMount(fetchProducts);
このコードでは、SvelteフレームワークからonMount
ライフサイクル関数をインポートしている。また、最初は空のproducts
配列を作成します。
コードブロックの中には、Back4appから必要なデータを取得するロジックを保持するfetchProducts
関数があります。
fetchProducts
関数は、Parse.Query
メソッドを使用して、アプリのデータベースから「Inventory」オブジェクトを検索します。
次に、クエリの
find()
メソッドを呼び出して、クエリ結果の配列を返します。最後に、結果の配列をproduct
変数に代入します。
fetchProducts
関数をonMount
関数の引数にすることで、Home
コンポーネントをレンダリングするたびにアプリケーションがデータをフェッチするようになります。
コンポーネントのHTMLセクションで、products配列のデータを表示します。
こんな感じだ:
<!-- Home.svelte-->
<div class="products">
{#each products as product}
<Card name={product.get('name')} quantity={product.get('quantity')} price={product.get('price')}/>
{/each}
</div>
each
ブロックは商品配列を繰り返し、配列内の各商品のカードコンポーネントを表示する。
Card
コンポーネントは、productのget
メソッドを使用して、name、quantity、product’s priceの値を取得します。そして、これらの値を小道具に代入します。
各ブロックを
包むdiv
タグにスタイルを設定するには、ホーム
コンポーネントのstyle
タグに以下の定義されたスタイルを追加します。
/* Home.svelte */
.products{
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 3rem;
border-top: 2px solid #e2e2e2;
margin-block-start: 3rem;
padding-block-start: 2rem;
}
Back4appからデータを削除する
Svelteアプリケーションに削除機能を追加するには。Card
コンポーネントからコンポーネントを変更する必要があります。Card
コンポーネントで、handleClickという
新しいpropを作成します。
コンポーネントのスクリプト
セクションに以下のコードを追加して、プロップを作成します:
//Card.svelte
export let handleClick;
では、コンポーネントのHTMLセクションのbutton
要素にclick
イベントハンドラでpropをバインドします。
こんな感じだ:
<!-- Card.svelte -->
<div>
<button on:click={handleClick}>Delete</button>
</div>
Home
コンポーネントでは、deleteProduct
関数を作成します。この関数には、選択した商品を削除するロジックが含まれています。
コンポーネントのスクリプト・
セクションに以下のコードを追加する。
// Home.svelte
const deleteProduct = async (id) => {
try {
const Product = Parse.Object.extend("Inventory");
const product = new Product();
product.id = id;
await product.destroy();
const newData = products.filter((item) => item.id !== id);
products = newData;
} catch (error) {
console.log(error);
}
};
上のコードブロックでは、deleteProduct
関数が新しい“Product “オブジェクトを作成し、そのオブジェクトのid
プロパティを関数のid
パラメータに設定し、オブジェクトの非同期destroy
メソッドを呼び出して、指定されたIDの製品を削除しています。
この関数は、product 配列から指定された ID を持つ商品を除外し、削除された商品を含まない新しい配列を作成します。そして、この関数は新しい配列を商品に
割り当てます。
次に、この関数をCard
コンポーネントのhandleClick
プロップに渡します。これで、ユーザがCard
コンポーネントのボタンをクリックするたびに、deleteProduct
関数がトリガされます。
こんな感じだ:
<!-- Home.svelte -->
<Card
name={product.get('name')}
quantity={product.get('quantity')}
price={product.get('price')}
handleClick={() => deleteProduct(product.id)}
/>
アプリケーションのテスト
アプリケーションが正しく動作することを確認するために、テストを行う必要があります。アプリケーションを起動するには、以下のコマンドを実行してください。
npm run dev
このコマンドは、開発サーバー上でアプリケーションを実行し、ウェブブラウザーでアプリケーションを表示できるようにリンクを提供します。
リンクをクリックすると、下の画像のようなアプリケーションが表示されます。
商品を追加する」リンクをクリックすると、次のような新しいページに移動します:
フォームに必要事項をご記入の上、「商品を追加する」ボタンをクリックして送信してください。
これにより、あなたが提供した詳細情報がBack4appのデータベースに追加されます。Back4appアプリケーションのダッシュボードにアクセスして確認することができます。
アプリケーションがデータの追加に成功すると、Back4appはデータベースに新しい行を追加します。
こんな感じだ:
フォームを送信すると、アプリケーションからホームページにリダイレクトされ、新商品が表示されます。
商品を削除するには、商品カードの「削除」ボタンをクリックしてください。
SvelteアプリケーションのDocker化
Back4appにデプロイする前に、SvelteアプリケーションをDocker化する必要があります。SvelteアプリケーションをDocker化するには、アプリケーションのルートディレクトリにDockerfileと
.dockerignore
ファイルを作成します。
Dockerfileに
以下のコードを書く:
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 5173
CMD ["npm", "run", "dev"]
Dockerイメージをビルドする際に、除外する必要があるディレクトリがいくつかあります。これらのディレクトリを指定するには、.dockerignore
ファイルに追加します。
例えば、こうだ:
# .dockerignore
node_modules
上記のコードブロックは、イメージビルドプロセス中にnode_modules
ディレクトリをコンテキストから除外するようDockerに指示します。ViteでSvelteアプリケーションを作成したので、DockerをサポートするようにViteを設定する必要があります。
これを行うには、アプリケーションのルートディレクトリにあるvite.config.js
ファイルにアクセスします。ファイル内のコードを以下のコードブロックに置き換えてください:
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
// <https://vitejs.dev/config/>
export default defineConfig({
plugins: [svelte()],
server: {
host: true,
strictPort: true,
port: 5173,
},
})
上記のコード・ブロックは、開発サーバーがリッスンするポートを指定し、指定されたポート以外ではアプリケーションが実行されないようにしている。
Dockerイメージをビルドするには、ターミナルで以下のコマンドを実行する:
docker build -t inventory-tracker .
Svelteアプリケーションのデプロイ
アプリケーションのDocker化が完了したら、次はSvelteアプリをデプロイします。Svelteアプリをデプロイするには、Back4app Containersを利用します。
アプリケーションをデプロイする前に、GitHub リポジトリにプッシュし、Back4app がそのリポジトリを使ってアプリケーションにアクセスできるようにする必要があります。Back4appがGitHubリポジトリにアクセスできるようにするには、Back4app Githubアプリを使います。
Back4appにアプリケーションのリポジトリへのアクセス権を与えた後、以下のプロンプトを使用して、AIエージェントを使用してBack4appにアプリケーションをデプロイすることができます:
Deploy my repository <<repository-url>> on Back4app containers
このプロンプトが表示されると、デプロイプロセスが開始されます。<>
をアプリケーションのリポジトリURLに置き換えてください。
デプロイに成功すると、AI エージェントから、アプリケーションのデプロイ ステータスとデプロイの詳細を知らせるメッセージが送信されます。
例えば、こうだ:
上の画像は、アプリケーションが正常にデプロイされ、指定されたApp URLにアクセスすることで、ブラウザからアプリケーションにアクセスできることを示しています。
結論
この記事では、Back4ppを使ってシンプルなSvelteアプリケーションを構築する方法を学びました。Back4app AIエージェントを使用して、アプリケーションのバックエンドを作成し、Parse SDKを使用してアプリケーションと対話しました。
AIエージェントは、Back4appコンテナへのアプリのデプロイプロセスも効率化します。
Back4appは、バックエンドとデプロイのニーズを管理することで、開発のワークフローを簡素化します。これにより、ユーザーに愛される製品作りに集中することができます。
このチュートリアルで使用したコードは、このGitHubリポジトリで入手できる。