Deno製フレームワークAleph.js(beta)をmicroCMSで試す
この記事はmicroCMS Advent Calender 2021 3日目の記事です。
以前Next.jsインスパイアのDeno製フレームワークであるAleph.jsを紹介させていただきました。
この記事はその続きです。
Aleph.jsはこの数ヶ月でalpha版からbetaへとバージョンアップしています。
Next.jsインスパイアというわけあって、Next.jsの機能に追従しつつも独自に進化遂げていて個人的にとても注目しているフレームワークの1つです。
バージョンアップしてみる
前回の記事の時点のバージョンが v0.3.0-alpha.33
のalphaでした。
まずは雑にバージョンアップしてみようと思います。
この間Denoのバージョンも上がっているので、最新版をインストールしてみます。
バージョンを指定することで任意のバージョンをインストールすることもできます。
deno upgrade
今回検証したDenoのバージョンは以下の通りです。
deno 1.16.4 (release, aarch64-apple-darwin)
v8 9.7.106.15
typescript 4.4.2
Aleph.jsもバージョンアップしてみます。
最新バージョンをインストールします。
deno run -A https://deno.land/x/aleph/install.ts
バージョンは以下の通りです。
Aleph.js v0.3.0-beta.19
前回でも書いた通り、Aleph.jsでは、 import_map.json
でバージョン管理することができるので以下のようにバージョンを上げます。
基本的にはURL+バージョン名を記入すればOKです。
{
"imports": {
"~/": "./",
"aleph/": "https://deno.land/x/aleph@v0.3.0-beta.19/",
"aleph/type": "https://deno.land/x/aleph@v0.3.0-beta.19/types.d.ts",
"framework": "https://deno.land/x/aleph@v0.3.0-beta.19/framework/core/mod.ts",
"framework/react": "https://deno.land/x/aleph@v0.3.0-beta.19/framework/react/mod.ts",
"react": "https://esm.sh/react@17.0.2",
"react-dom": "https://esm.sh/react-dom@17.0.2",
"microcms": "https://esm.sh/v58/microcms-js-sdk@2.0.0"
},
"scopes": {}
}
開発環境で実行します。
aleph dev
本番環境にデプロイしてみます。
Verselへのデプロイが一番試しやすく、簡単だと思います。
設定方法は以下をご覧ください
以下のような設定をします
Build Command: deno run -A https://deno.land/x/aleph/cli.ts build
Output Directory: dist (you can override it in aleph.config.ts)
Install Command: curl -fsSL https://deno.land/x/install/install.sh | DENO_INSTALL=/usr/local sh
問題なくデプロイできました。alphaからbetaへの移行はスムーズにできそうです。
新機能を試す
以下の記事を参考にさせていただきました。Aleph.js以外にもDenoのフロントエンドについてまとまっていてとても参考になりました。
その中から気になった機能を試してみます。
esbuild+swcへの移行
ビルドが tsc
から移行されました。
39s
(記事数30件)から 33s
(記事数35件)へと少し短縮されました。ビルドの要素自体が少ないので誤差ですがビルド時間の短縮が期待できそうです。
Scoped CSS
前回の記事で、CSSのコンパイルがスコープなのかという課題がありましたが、CSS modulesサポートや link
タグをコンポーネントごとに読み込むことにより、ScopedなCSSをかけるようになりました。
具体的にはCSS modulesファイルをコンポーネントごとに用意します。
.card {
margin: 20px;
}
.card:hover {
opacity: 0.7;
}
.cardLink {
text-decoration: none;
color: black;
}
コンポーネントで使用するときはlinkをコンポーネント内で読み込み、$プレフィックスで参照します。
import React from "react";
export const Card: React.VFC<Props> = (
{ url, title },
) => {
return (
<article className="$card">
<link rel="stylesheet" href="./card.module.css" />
<a
href={url}
className="$cardLink"
target="_blank"
rel="noopener noreferrer"
>
<h3>{title}</h3>
</a>
</article>
);
};
Plugin
その他にも(試せてはいませんが)Next.jsにも実装され話題となったmiddlewareなどの機能も追加されているそうです。
中でも個人的に良いなと思ったのは、Pluginの機能です。
これは設定ファイル aleph.config.ts
にPluginを書くことによって、その処理をページ読み込み時に実行する機能になります。
同じような仕組みをVue.jsのフレームワークであるNuxt.jsが実装しています。
ページが読み込まれる前に処理が実行されるので、認証などの必ずページ読み込み以前に走らせたい処理を実行させるのに便利です。
公式では、Google Tag Manegerを読み込む処理などが紹介されています。
import type { Plugin } from 'aleph/type'
export default <Plugin> {
name: 'google-analytics-plugin',
setup: aleph => {
const id = Deno.env.get('GTAID')
if (id && aleph.mode === 'production') {
aleph.onRender(({ html }) => {
html.scripts.push(
{
src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(id)}`,
async: true
},
`
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', ${JSON.stringify(id)});
`
)
})
}
}
}
Framework API
Aleph内のReactにもAPIが追加されています。
dynamic import
dynamic importは個別にコンポーネントを取得することでパフォーマンスを向上させることができます。
Fallback
を利用することで、コンポーネント読み込み時の処理を追加することができます。
Reactの Suspence
のような機能です。
import { useDeno } from "framework/react";
import React from "react";
import { dynamic, Fallback } from 'framework/react';
import "../style/home.css";
import { microcmsClient } from "../lib/microcmsClient.ts";
import type { Post } from "../types/post.ts";
const Card = dynamic(() => import("../components/Card/card.tsx"))
export default function Home() {
const articles = useDeno<Post>(async () => {
return await microcmsClient.get({
endpoint: "articles",
queries: { limit: 99 },
});
});
return (
<div className="page">
<head>
<title>Ryusou Profile</title>
</head>
<section>
{articles.contents.map((content) => {
const categorys = content.category.map((category) => category.id);
const categoryId = categorys[0];
return (
<React.Fragment key={content.id}>
<Fallback to={<p>Loading....</p>}>
<Card
url={content.url}
title={content.title}
publish_article={content.publish_article}
category={categoryId}
/>
</Fallback>
</React.Fragment>
);
})}
</section>
</div>
);
}
microCMS
microcms-js-sdkにあった変化についてもご紹介します。
現在バージョンは v2.0.0
です
型定義の見直し
以前までですと、offset
totalCount
などの型定義を自前で用意する必要がありました。
type Contents = {
contents: Contents[];
//以下のようなクエリを自前で用意する必要があった
totalCount: number;
limit: number;
offset: number;
};
これらの型定義はmicrocms-js-sdkに含まれるようになったので、書く必要はありません。
API-KEYの移行
権限などをキーごとに設定できます。
使用方法などはこれまでとは基本的に変わりません。
以下のように設定をします。Denoは以下のようにして .env
の値を取得することができます。
import { createClient } from "microcms";
export const microcmsClient = createClient({
serviceDomain: "your-subDomain",
apiKey: `${Deno.env.get("X_MICROCMS_API_KEY")}`,
});
useDeno
Hookで呼び出します。このHooksはサーバーサイドで実行されるのでAPIキーの漏洩の問題はありません。
const articles = useDeno<Post>(async () => {
return await microcmsClient.get({
endpoint: "articles",
queries: { limit: 99 },
});
}, { revalidate: true });
またAleph.jsではbetaからSSRオプションが使用できるようになったので、そちらでも呼び出せることができます(Next.jsでいうところのgetServerSidePropsなどに近いです)。
POST,PATCHなどのWRITE系のAPIはサーバーサイド側で実行する必要があります。
Next.jsのAPI Routesにあたる機能もAleph.jsには存在するので、APIをそこで定義して使用することになると思います。
ここら辺はかなりNext.jsと近い感覚で実装できるのではないかと思っています。
最後に
Next.jsにも URL imports
というかなりDenoを意識した機能が先日v12で発表されました。
そんな中Aleph.jsはどのような発展をしていくのか?
注目しています。
皆さんもぜひ、年末は新しい技術に挑戦してみてはいかがでしょうか?
Discussion