Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
83
Help us understand the problem. What is going on with this article?
@nitaking

⚡️Blitz.js - React on Rails

image.png

⚡️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

image.png

React Final FormReact Hook Formどちらを使用するか聞かれます。お好きな方をどうぞ。

選ぶとプロジェクトがgenerateされます。

image.png

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すると、マイグレーションが実行されます。

2020-08-28 00.13.19.gif

次のファイルが生成されます。

image.png

細かい説明は後回しにしますが、ユーザーテーブルの生成を行ってくれます。

// 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/ にサイトが展開されます。

image.png

おや、Sign UpボタンとLoginボタンがありますね?
既に会員登録とログイン機能が実装されています。

Sign Up
2020-08-28 00.23.33.gif

Login
2020-08-28 00.24.04.gif

はじめからバリデーションもされてますね。

パワフルな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が実装されているのがわかります。

2020-08-28 00.37.07.gif

優れた DataBase Viewer

blitz db studioと入力してみてください。

$ blitz db studio

Generating Prisma Client ... done
Studio started at http://localhost:5555

すると http://localhost:5555 に次の画面が立ち上がります。

この快適な画面で、データの閲覧や、作成がサクッとできます!

2020-08-28 00.41.10.gif

ゼロAPI

さて、先程生成されたファイルの中身の話です。(getProject.ts)

app/projects/queries/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を取るような形になっており、

app/projects/pages/projects/[projectId].tsx
...
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 } })
...

useQuerygetProjectを呼び出してアクセスします。これだけ!
GraphQLのようなcode生成をしなくてもデータアクセスができます!

React の実験的な機能を導入

また、Reactの Concurrentモード(並列モード) が導入されており、SuspenseErrorBoundaryが使えます。(generateされたソースに使用されています)

blitz console

ormのreplです!Blitz.jsではmutationも叩けます!

2020-08-28 01.30.40.gif

mutationも叩ける!すごい!
(なのですが、auth認証が入っているのでgetProjectで叩くにはちょっとキツイかも、、、)

2020-08-28 01.32.16.gif

Blitz.js on Next.js

Blitz.jsはNext.jsの上に構成されているので、Nextでできることは手厚いサポートがされています。

BlitzではRecipeとして、blitz install <recipe>できます。

例えば、tailwindの導入は、

$ blitz install tailwind

これで、必要なパッケージのインストールや、設計ファイルの変更をやってくれます。
CLI上でインタラクティブに確認が入るので、Enterを押していけばどんどんやってくれます!

image.png

終わればあとはtailwindでスタイリングするだけ!

...
    <ul className="bg-blue-500">
...

image.png

https://blitzjs.com/docs/using-recipes

Recipeに対応しているものは、Githubを見れば確認できます。

image.png

現在は、chakra、emotion、material-ui、render、tailwindに対応しているようですね。


blitzjs、めっちゃパワフルで素敵ですね!

ぜひ触ってみてください!

参考

83
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
nitaking
ReactNativeエンジニアからのフルスタックエンジニア zennはこちら: https://zenn.dev/nitaking
aircloset
「新しい当たり前を作る」を作ることをミッションに、airClosetを開発・運営しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
83
Help us understand the problem. What is going on with this article?