Freshハンズオン 中級編
Freshハンズオンのための記事です。
こちらは中級編となっております。
基本的にJSフレームワークの利用経験がある人向けにざっくりとしか説明していないため、不明点は気軽に聞いて下さい。
準備
下記の基本ツールがインストールされていることを確認してください。
- VSCode
- Deno
- Deno for VSCode
また、Deno Deployに事前にサインアップしてください。
そして、今回のKV書き込み確認用に、Kiviをインストールします。
※まだ安定した拡張機能とは言い難いので、まともに動かなかった場合はworkaroundの項を参照してください。
Web掛け軸を作ろう
とにかくクソデカな文字を画面に表示するだけです。
まずはinit
deno run -A -r https://fresh.deno.dev kakejiku
今度は下記の設定で生成します。
- Styling library: y
- twind(2)
- VSCode: y
※ここでtailwindcssがrecommendedであるにもかかわらず選択しない理由は、GitHub Actionsが必須となりハンズオンには少し回り道になってしまうためです。twindは一部utility classが使用できないことに留意する必要があります。
でっかい文字を表示しよう
index.tsxを下記のように置き換えます。
export default function Home() {
return (
<div>
<link
href="https://fonts.googleapis.com/css2?family=Yuji+Syuku&display=swap"
rel="stylesheet"
>
</link>
<style>
{`h1 {font-family: 'Yuji Syuku', sans-serif;}`}
</style>
<h1 class="text-9xl flex justify-center items-center h-screen">
臥薪嘗胆
</h1>
</div>
);
}
※標語は好きに変えてください
deno task start
でプレビューしてください。
デプロイ
deployctlをインストールし deployctl deploy
を実行します。
main.tsが自動でエントリポイントと判別されます。アップロードが実行され、URLが発行されます。
標語を変更できるようにする
標語をハードコードせずにDBにストアして、自由に変更できるようにしましょう。
まずHome関数にasyncを追加します。
export default async function Home() {
その次の行にこの2行を追記します。
const db = await Deno.openKv()
const word = await db.get<string>(["word"])
するとブラウザ上でこのように怒られてしまいます。
Deno KVの有効化
これはまだDeno KVがunstableな機能だからで、これを通すにはdeno.jsonに下記を追加します。
"unstable": [
"kv"
],
また、VSCode上のエラーを消すためにmain.tsに下記の行を追加する必要がありました。
/// <reference lib="deno.unstable"/>
取得した値の埋め込み
では早速、取得した標語を埋め込んでみましょう。
<h1 class="text-9xl flex justify-center items-center h-screen">
{word.value}
</h1>
まだDBには何も値を入れていないのでブラウザは真っ白になります。
Kiviで値を追加してみます。
Kiviタブを選択してこの画面になるか確認してください。
正しく表示されている場合、keyにword
, Valueに好きな標語を入れてCreateを押下します。
標語は表示されましたか?
ワークアラウンド
Kiviタブが表示されなかった場合、Denoでスクリプトを書いて直接更新を行ってください。
update-kv.ts
:
const kv = await Deno.openKv();
const res = await kv.set(["word"], "実質ゼロカロリー");
console.log(res);
deno run -A --unstable-kv update-kv.ts
再デプロイ
さて、下記でもう一度デプロイしましょう。
deployctl deploy --prod
もちろん画面は真っ白ですね。リモートのDeno KVには値が入っていません。
Deno Deployの該当プロジェクトを見てみましょう。
KVタブを開くと、接続のための文字列が取得できます。
APIキーが必要になりますので、Set up access tokens for Deno CLI
をクリックして適当な名前で作成します。
.envファイルを下記の内容で作成します。
DENO_KV_ACCESS_TOKEN=<取得したAPIキー>
Kiviで接続する場合は、Deno DeployのダッシュボードからUUIDをコピーします。
Kivi下部の"Default Database"をクリックして、UUIDをペーストします。
これでローカルからリモートDBに書き込みできるようになりました。
workaround
CLIから接続する場合は、下記のガイダンスに従ってください。
Deno KVのAPIについてもう少し説明
基本的にはget, list, set, deleteを使用します。
const res = await kv.get<string>(["config"]);
このように型を指定して値を取得することができます。
- keyには配列を指定します。これによってコレクションを表現することができます。
- keyにはstringやnumberだけではなく、Uint8Array, bigint, booleanを使うこともできます。
- valueには最大64KBまでのオブジェクトを格納することができます。structuredCloneで使えるtypeを使うことができます(Array, Map, Set, DateなどもOK)
詳しくは公式ドキュメントを参照してください。
更新フォームを作る
VSCode経由の更新はちょっと面倒ですね。
更新フォームを作りましょう。
update.tsxを作成します。
import { FreshContext, Handlers } from "$fresh/server.ts";
const kv = await Deno.openKv();
export const handler: Handlers = {
async POST(req: Request, _ctx: FreshContext) {
const form = await req.formData();
const word = form.get("word");
const res = await kv.set(["word"], word);
return new Response("Success");
},
};
export default function Update() {
return (
<div>
<form action="/update" method="post" class="p-8">
<input name="word" class="border p-2" />
<button type="submit" class="border p-2">Submit</button>
</form>
</div>
);
}
ここでのポイントは、ハンドラ関数(上半分)でPOSTを受けて、下半分のコンポーネントでGETを受けていることです。このようなスタイルをfreshではmixed handler and component routeと呼んでいます。
このようなフォームを作成することができます。
BASIC認証をかける
勝手に誰かに書き換えられたら困るので、BASIC認証をつけましょう。
import { defineConfig } from "$fresh/server.ts";
import twind from "$fresh/plugins/twindv1.ts";
import twindConfig from "./twind.config.ts";
import basicAuthPlugin from "https://deno.land/x/hashrock_fresh_plugins@1.0.1/basic.ts";
export default defineConfig({
plugins: [twind(twindConfig), basicAuthPlugin("/update")],
});
.envにパスワードを追加します。
BASIC_AUTH_USER=hoge
BASIC_AUTH_PASSWORD=fuga
これでBASIC認証を設定できました。
deployctl deploy --prod
でデプロイします。
なお、本番環境の環境変数はダッシュボードに追加するUIがあります。
ここまででハンズオンは終了です。
時間が余った人向け
- 複数文を保存できるようにしましょう
- Fresh Componentsを使ってアイコンなどを追加しましょう
- メールお知らせ機能をつけましょう
- Islandを使って動的なUIを追加しましょう
リポジトリ
Discussion