⚡️Blitz.js - React on Rails
みなさん、Blitz.js をご存知ですか?
⚡️Blitz.js - Rails にインスパイアされて作られたフルスタック React フレームワーク!
React エンジニアが WEB サイトを構築するまでには、いくつも考えること、導入するツールがあります!
「使いやすい Form ライブラリはどれだ」「ORM はどれだ」「ディレクトリ構成はどれだ」「linter 設定」などを決めなくてはいけません!
やだ大変!🤮
Rails や Laravel のようにパワフルなフレームワークのおかげですぐに本質的な作業に入りたいそこのあなた!
⚡️Blitz.jsをご存知ですか?
Introduction
なにはともあれ、サイトを立ち上げてみましょう!
blitz
CLI を global install します。
$ yarn global add blitz # npm i -g blitz
$ blitz new myAppName
React Final Form
かReact Hook Form
どちらを使用するか聞かれます。お好きな方をどうぞ。
選ぶとプロジェクトが generate されます。
generate されると
Your new Blitz app is ready! Next steps:
1. cd myApp
2. blitz db migrate (when asked, you can name the migration anything)
3. blitz start
$ cd myAppName
$ blitz db migrate
blitz db migrate
すると、マイグレーションが実行されます。
次のファイルが生成されます。
細かい説明は後回しにしますが、ユーザーテーブルの生成を行ってくれます。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = ["sqlite", "postgres"]
url = "***"
}
generator client {
provider = "prisma-client-js"
}
// --------------------------------------
model User {
id Int @default(autoincrement()) @id
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String?
email String @unique
hashedPassword String?
role String @default("user")
sessions Session[]
}
model Session {
id Int @default(autoincrement()) @id
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
expiresAt DateTime?
handle String @unique
user User? @relation(fields: [userId], references: [id])
userId Int?
hashedSessionToken String?
antiCSRFToken String?
publicData String?
privateData String?
}
初期設定では sqlite に接続されますので、このままアプリケーションだけ起動してもデータが保存されます。
さあ、blitz start
しましょう。
$ blitz start
すると http://localhost:3000/ にサイトが展開されます。
おや、Sign Up
ボタンとLogin
ボタンがありますね?
既に会員登録とログイン機能が実装されています。
Sign Up
Login
はじめからバリデーションもされてますね。
パワフルな CLI
起動画面に表示されたコマンドを実行してみましょう。
$ blitz generate all project name:string
すると
$ blitz generate all project name:string
You are using alpha software - if you have any problems, please open an issue here:
https://github.com/blitz-js/blitz/issues/new/choose
✔ Model for 'project' created successfully:
> model Project {
> id Int @default(autoincrement()) @id
> createdAt DateTime @default(now())
> updatedAt DateTime @updatedAt
> name String
> }
Now run blitz db migrate to add this model to your database
CREATE app/projects/pages/projects/[projectId]/edit.tsx
CREATE app/projects/pages/projects/[projectId].tsx
CREATE app/projects/pages/projects/index.tsx
CREATE app/projects/pages/projects/new.tsx
CREATE app/projects/components/ProjectForm.tsx
CREATE app/projects/queries/getProject.ts
CREATE app/projects/queries/getProjects.ts
CREATE app/projects/mutations/createProject.ts
CREATE app/projects/mutations/deleteProject.ts
CREATE app/projects/mutations/updateProject.ts
table の生成だけでなく、ページも含めて1機能の CRUD が生成されました。
- Page(
app/project/pages/*
) - Form(
app/project/components/*
) - Query(
app/project/query/*
) - Mutations(
app/project/mutations/*
)
忘れずに migrate しましょう
$ blitz db migrate
http://localhost:3000/projects
へ行くとと CRUD が実装されているのがわかります。
優れた DataBase Viewer
blitz db studio
と入力してみてください。
$ blitz db studio
Generating Prisma Client ... done
Studio started at http://localhost:5555
すると http://localhost:5555 に次の画面が立ち上がります。
この快適な画面で、データの閲覧や、作成がサクッとできます!
ゼロ API
さて、先程生成されたファイルの中身の話です。(getProject.ts
)
import { NotFoundError, SessionContext } from "blitz"
import db, { FindOneProjectArgs } from "db"
type GetProjectInput = {
where: FindOneProjectArgs["where"]
// Only available if a model relationship exists
// include?: FindOneProjectArgs['include']
}
export default async function getProject(
{ where /* include */ }: GetProjectInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize()
const project = await db.project.findOne({ where })
if (!project) throw new NotFoundError()
return project
}
引数でwhere
を取るような形になっており、
...
import { Head, Link, useRouter, useQuery, useParam, BlitzPage } from "blitz"
import getProject from "app/projects/queries/getProject"
...
export const Project = () => {
const projectId = useParam("projectId", "number")
const [project] = useQuery(getProject, { where: { id: projectId } })
...
useQuery
でgetProject
を呼び出してアクセスします。これだけ!
GraphQL を内部的に使用しているようですが、うまくラップされていて GraphQL のような code 生成をしなくてもデータアクセスができます!
React の実験的な機能を導入
また、React の Concurrent モード(並列モード) が導入されており、Suspense
やErrorBoundary
が使えます。(generate されたソースに使用されています)
blitz console
orm の repl です!Blitz.js では mutation も叩けます!
mutation も叩ける!すごい!
(なのですが、auth 認証が入っているのでgetProject
で叩くにはちょっとキツイかも、、、)
Blitz.js on Next.js
Blitz.js は Next.js の上に構成されているので、Next でできることは手厚いサポートがされています。
Blitz では Recipe として、blitz install <recipe>
できます。
例えば、tailwind の導入は、
$ blitz install tailwind
これで、必要なパッケージのインストールや、設計ファイルの変更をやってくれます。
CLI 上でインタラクティブに確認が入るので、Enter を押していけばどんどんやってくれます!
終わればあとは tailwind でスタイリングするだけ!
...
<ul className="bg-blue-500">
...
Recipe に対応しているものは、Github を見れば確認できます。
現在は、chakra、emotion、material-ui、render、tailwind に対応しているようですね。
blitzjs、めっちゃパワフルで素敵ですね!
ぜひ触ってみてください!
Reference
正直この Brandon の動画を記事に起こしただけなのですが、これをみるだけで Blitz の生産性を感じられると思います!
Discussion