学習記録「Hono」 「Remix」 「Reactのテスト手法」を学びました!
Posted date at 2024-09-16直近の学習内容を共有します。
単体テストの手法や最新のフレームワークについて情報収集を兼ねてハンズオンで学習しました。
🚀Hono
ClaudFlareの日本人エンジニアであるYusuke Wada氏が開発したJavaScriptフレームワークです。バックエンド開発においては、Node.jsよりも高速で動作します。GitHubのスター数が爆発的に増えています。今後の動向に注目します。
知識のインプット、ハンズオンには以下の動画を使用させて頂きました。バックエンド開発においてはNode.js/Expressと同じ感覚でコーディングできます。TypeScriptがデフォルトなのも良いです。
Hono Webフレームワークの新しい選択肢
講師:ムーザルちゃんねるさん
動画時間:32分 林がかけた時間:1.5時間
【Hono入門】爆速でAPI開発ができるHonoに入門してデプロイまで学んでみよう【CloudFlare Workersを利用】
講師:ShinCodeさん
動画時間:34分 林がかけた時間:2時間
🚀Remix
ReactのフレームワークであるRemixについてハンズオン形式で学びました。クライアントサイドの記述とサーバサイドの記述を同じファイルにできる点がNextと大きく異なります。
Nextと対になるフレームワークなので今後の動向に注目します。
【Remix入門】完全初心者OK!簡単なブログを作ってRemixの1歩を踏み出してみよう
講師:ShinCodeさん
動画時間:1時間 林がかけた時間:4.5時間
アウトプットとして、簡単な例で、RemixとNextの違いを示しておきます。
🐡Remixでのフェッチ処理のサンプル
以下のファイルでは、loaderメソッドはサーバ側で実行される。
Postsコンポーネントはサーバ側とクライアント側で以下の通り実行される。
①サーバ側でHTMLのレンダリングがされる。
②ブラウザにJavaScriptが読み込まれた後、onClickイベントやuseStateなどのJavaScriptがHTMLに紐づけられる(ハイドレーションという)。
これらは以下の通り記述をすればRemixが行ってくれる。1つのファイルで、サーバ処理とクライアント処理を記述できる。
//posts.tsx import { json } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; import { useState } from "react"; //-----------------サーバサイドで実行される----------------- export const loader = async () => { return json({ posts: await prisma.post.findUnique({ where: { slug, }, }); }; //--------------------------------------------------------- //------サーバサイドとクライアントサイドで実行される---------- export default async function Posts() { const { posts } = useLoaderData<typeof loader>(); //---------クライアントサイドのみで実行される-------------- const [toggle,settoggle] = useState(false); const handoleClick()=>{ setToggle(!toggle); } //------------------------------------------------------- return ( <main> <h1>Posts</h1> <ul> {posts.map((post) => ( <li key={post.slug}> <Link to={post.slug} className="text-blue-600 underline"> {post.title} </Link> </li> ))} </ul> <Link to="admin" className="text-red-600 underline"> Admin </Link> <button onClick={handleClick}>Click me</button> </main> ); } //---------------------------------------------------------
🐡同じ処理をNext.jsで書いた場合
一方Next.jsでは、クライアント処理とサーバ処理を別ファイルに分ける必要がある。APIRoutesでサーバサイドの処理をAPIとして公開し、クライアントコンポーネントからuseEffectでフェッチする。
なお、useStateやonClickイベントを使用しない場合は、Remixと同様、1つのファイルで記述することができる。その場合、Postsコンポーネントがサーバコンポーネントになるためである。
// app/api/posts/route.ts import { NextResponse } from 'next/server'; //-----------------サーバサイドで実行される----------------- export async function GET() { const posts = await prisma.post.findUnique({ where: { slug, }, }); return NextResponse.json(posts); }
//Posts.tsx 'use client'; //---------クライアントサイドで実行される-------------- import { useState, useEffect } from 'react'; import Link from 'next/link'; interface Post { slug: string; title: string; } export default function Posts() { const [posts, setPosts] = useState<Post[]>([]); const [loading, setLoading] = useState<boolean>(true); const [error, setError] = useState<string | null>(null); const [toggle,settoggle] = useState(false); const handoleClick()=>{ setToggle(!toggle); } useEffect(() => { async function fetchPosts() { try { const response = await fetch('/api/posts'); if (!response.ok) { throw new Error(`Error: ${response.statusText}`); } const data: Post[] = await response.json(); setPosts(data); } catch (err: any) { setError(err.message || 'Unknown error'); } finally { setLoading(false); } } fetchPosts(); }, []); if (loading) { return <p>Loading posts...</p>; } if (error) { return <p>Error loading posts: {error}</p>; } return ( <main> <h1>Posts</h1> <ul> {posts.map((post) => ( <li key={post.slug}> <Link href={`/posts/${post.slug}`} className="text-blue-600 underline"> {post.title} </Link> </li> ))} </ul> <Link href="/posts/admin" className="text-red-600 underline"> Admin </Link> <button onClick={handleClick}>Click me</button> </main> ); } //--------------------------------------------------
🐡Next.jsで書いた場合(useState、onClickを使用しない場合)
サーバコンポーネントとなり、サーバサイドで実行される。
//Posts.tsx //---------サーバサイドで実行される-------------- import Link from 'next/link'; interface Post { slug: string; title: string; } export default function Posts() { const posts = await prisma.post.findUnique({ where: { slug, }, }); return ( <main> <h1>Posts</h1> <ul> {posts.map((post) => ( <li key={post.slug}> <Link href={`/posts/${post.slug}`} className="text-blue-600 underline"> {post.title} </Link> </li> ))} </ul> <Link href="/posts/admin" className="text-red-600 underline"> Admin </Link> </main> ); } //--------------------------------------------------
🚀単体テスト
ShinCodeさんのUdemy講座でReactのテスト手法についてハンズオンで学びました。フロントエンド開発におけるテスト手法を学ぶ中で、普段使用しているPrettierやESLintの設定方法や各種設定ファイルの役割についても知見を深めることができました。
個人開発レベルでは単体テストを使用することは少ないかもしれませんが、チーム開発でコンポーネント単位で役割分担をする場合には有効です。
講座名:【Reactテスト入門】React Testing Library/Jest/Vitestで学ぶフロントエンドテスト入門
講師:ShinCodeさん
動画時間:4.5時間 林がかけた時間:11時間
🚀まとめ
現在JavaScriptのフレームワークやランタイムは、覇権争いの様相を呈しています。特にランタイムについては、2022年ごろからNode.jsに代わる、BunとDenoが台頭してきています。
両者ともNode.jsと互換性がありNode.jsよりも高速であるため、Node.jsの後継となる可能性が高いと言われています。ちなみにBunの開発チームは会社を設立し、700万ドルの資金を調達したそうです。
いつでも飛び乗れるように、基本的な感覚はハンズオンでつかんでおきたいと考えています。
こんなこと学んでどうするんだという意見もあるかもしれませんが、マイナスの言い方をすると時代遅れの技術しか知らないのに、難しい、できない、作れないというのは怠慢だと思いますので、これからもキャッチアップして共有していきます。
←ホームに戻る