完成サイト
ソースコード
動機
この記事を拝見して、
DenoのNext.js系フレームワークAleph.jsではなくて、Freshを使って同様のサイトを構築してみたいなと思ったから。というのも、筆者は以前Aleph.jsを使用してDB検索システムを作ったのだが、
デプロイがうまくいかず、Aleph.jsのアルファ版故のバグに悩まされたため、新しくサイトを作る際にはDenoで使えるフレームワークでより開発が進んでいるものを採用したかったという理由がある。もちろんAleph.jsでサイトを作ることも不可能ではないけれども、勉強がてらFreshで作ってみたいと思った。
ryusouさんの記事をとても参考にしたので、上記の記事をFreshでやってみたというのが正しい。役立つ情報ありがとうございます。
Freshでの開発
Freshプロジェクトの作成
Denoはすでにインストール済という前提で書いていく。
deno run -A -r https://fresh.deno.dev fresh-profile
プロジェクト名は適当に設定してプロジェクトを作成する。作成時に色々聞かれるが、僕はWebStromを利用しているのでVSCode用の設定は利用しない形でプロジェクトを作成しました。その他はyesで作成。
ディレクトリの構成
fresh-profile
├── deno.json
├── deno.lock
├── dev.ts
├── fresh.gen.ts
├── import_map.json
├── lib
│ └── microcmsClient.ts
├── main.ts
├── routes
│ └── index.tsx
├── static
└── twind.config.ts
MicroCMSの準備
今回は練習なのでシンプルな構成にしました。
あとは適当にサンプルデータを入れときましょう。
MicroCMSと連携
MicroCMS Clientの作成
/lib 下にmicrocmsClient.ts を作成する。
import { createClient } from "microcms";
import "dotenv/load.ts";
export const microcmsClient = createClient({
serviceDomain: "freshpractice",
apiKey: Deno.env.get("X_API_KEY")
});
次に .envファイルをプロジェクトディレクトリ直下に作成し、MicroCMSのAPIKEYをここに保存する。
X_API_KEY=YOUR_API_KEY
index.tsx
index.tsxの全容を紹介する。
import {Handlers, PageProps} from "$fresh/server.ts";
import {Head} from "$fresh/src/runtime/head.ts";
import {microcmsClient} from "../lib/microcmsClient.ts";
import dayjs from "dayjs";
export interface Post {
contents: [{
id: string;
url: string;
title: string;
published_article?: string;
}];
}
//タイムゾーンを設定
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault("Asia/Tokyo");
export const handler: Handlers<Post> = {
async GET(_req, ctx) {
const articles = await microcmsClient.get<Post>({
endpoint: "articles",
queries: {limit: 99},
});
if (!articles) {
return new Response("Response not found", {status: 404});
}
return ctx.render(articles);
},
};
export default function Home({data}: PageProps<Post>) {
return (
<div class="h-screen bg-yellow-200">
<Head>
<title>Stead Profile</title>
</Head>
<div
class=
"max-w-screen-sm mx-auto px-4 sm:px-6 md:px-8 pt-12 pb-20 flex flex-col"
>
<h1 class="font-extrabold text-5xl text-gray-800 flex justify-center">Stead Profile</h1>
<section class="m-8">
{data.contents.map((content) => {
return (
<div class="p-4" key={content.id}>
<a href={content.url} alt={content.title}>
<p>{content.title}</p>
<time
class="text-gray-500 text-sm"
dateTime={content.published_article}
>
{dayjs(content.published_article).format("YYYY-MM-DD HH:mm:ss")}
</time>
</a>
</div>
)
})}
</section>
<a href="https://fresh.deno.dev">
<img width="197" height="37" src="https://fresh.deno.dev/fresh-badge.svg"
alt="Made with Fresh"/>
</a>
</div>
</div>
)
}
今回はhandlerで記事一覧を取得して、描画するだけのページを作成した。
Fresh v1.1よりTwindがオフィシャルファーストパーティプラグインとなったので少し記述が楽になった。
// pages/index.tsx
- import { tw } from "@twind";
export default function IndexPage() {
return (
- <h1 class={tw`text-4xl font-bold`}>Hello, world!</h1>
+ <h1 class="text-4xl font-bold">Hello, world!</h1>
);
}
localhostで動作確認
deno task start
でローカルサーバーが立ち上がる。
watcherも動いてるので変更内容がすぐに反映されるので楽。
deno deployでデプロイ。
あとはdenoのオフィシャルエッジサービス、deno deployでデプロイしてみる。
Git hub上でプロジェクトを管理していると、デプロイが楽。
環境変数のところにAPI KEYを設定することを忘れないようにする。
まとめ
これぐらいのレベルのサイト構築であるとFresh, MicroCMS & deno deployの組み合わせは爆速で開発できる気がする。とは言っても筆者はフロントエンド開発というのを初めてまだ一ヶ月ちょいのペーペーなので詳しいことはわからない。記事内にも用語の誤用が多数含まれていると思うので、ご指摘してくださるとありがたい。