ざっくりと理解するBlitz.js

はじめに

最近少しBlitz.jsを触ってみたので備忘録的に書いてみます。

執筆時点では v0.24.3 / 0.25.0-canary.2です。 ドキュメントからの部分抜粋みたいになってしまったので、これからBlitz触ってみようかな、という人向けの記事です。

Blitz.jsのはじまり

https://blitzjs.com/docs/community-history

ざっくりとはBlitz.jsは作者BrandonBayer氏がReactによるRuby on Railsが欲しいなとつぶやいていたものの誰も全然やってくれないからもう自分でやろう、みたいな形でスタートしています。なので端的にいうとReactを用いたNode.js向けのRuby on Railsのようなフルスタックアプリケーションを作れるフレームワークを目指すという思想で始まっています。

プロジェクトの指針は ここ で説明されています。見出しのみ抜粋。

Fullstack & Monolithic
API Not Required
Convention over Configuration
Loose Opinions
Easy to Start, Easy to Scale
Stability
Community over Code

主要なパッケージと依存

Blitz.jsには下記の主要なパッケージがあります。それぞれを知っていると捗ります(ものによってはそこまで知らなかったのでつらかったです)

Next.js

Blitz.jsは基本的にNext.jsの上に作られています。

React(Concurrent Mode)

Reactはexperimental-xxx系のパッケージが使用し、Concurrent Modeを有効にしています。これは抜けるかもしれませんが、大変そうだったので頑張っては試していません。

この影響でデフォルトではConcurrent Modeに対応していないUIフレームワーク等は動きません。 例としてAnt Design/antdは動くコンポーネントと動かないコンポーネントがあります。Material-UIは未検証です。

Prisma (2.0)

Prismaは必須ではないようですが、デフォルトでは型付けされたクライアントを生成するためにPrismaが設定されており、blitz db系のコマンドもほとんどがPrismaのCLIのプロキシです。 Knex.jsを使用するサンプルはこちらにありますが、内容・手順等は未確認です。(起動はできました)

react-query

Blitz.jsではreact-queryをラップして作られた関数群(useQueryなど)が提供されており、Blitz.js内で定義されたquery/mutationを使う場合はBlitzのもの、外部APIなどを使う場合はreact-queryのものを使う形になります。 ここの依存度が厳密に必須なのかはわかりませんが、バックエンド・フロントエンドを一本化するためにフロントエンドではquery/mutationがRPC Clientを通してサーバーサイド実装からAPIリクエストに変換されるようですが、この辺りが変換されているかという検証やこの情報を元にしてreact-queryの設定値をよしなにしてくれているので、大人しくreact-queryに乗っかったほうが良さそうです。 この辺りの実装の影響から外部APIにはBlitz.jsのuseQueryではなく、react-queryの素のものを使う、という形になっています。

Blitz.jsの標準機能

https://blitzjs.com/docs/why-blitz

Next.jsに対して大きく下記のような標準機能の追加があります。

Data Layer

https://blitzjs.com/docs/query-usage

You may be wondering how that can work since it's importing server code into your component: At build time, the direct function import is swapped out with a network call. So the query function code is never included in your client code.

https://blitzjs.com/docs/rpc-specification

File: app/products/queries/getProduct.ts
URL: /api/products/queries/getProduct

Blitz.jsではquery/mutationの1定義で、バックエンド/フロントエンドにインポートしてそのまま使用できます。 また、そのコードは上述の通りビルド時にAPIルートとクライアントではAPIリクエストに置き換わり関数のコード隠蔽されます。これが割とBlitzの大きな機能で所謂魔法な所だと思われます。

ここは正直ドキュメントからそうなるのは分かったけど…みたいな所で記事を書くのを挫折しかけましたがmizchiさんがこの部分の仕組みをコードベースしっかりと追ってる記事を書いてました。 順を追ってしっかり解説されてて完成度がすごいので詳しく知りたい方は読むことをおすすめします!

pagesの分離

https://blitzjs.com/docs/pages

Next.jsでは単一の pages/ フォルダをルーティングとして変換しますが、Blitz.jsでは ルートのapp/配下にあるpages/ディレクトリ全てをマージしてルーティングに変換されます。

app/pages/about.tsx
app/projects/pages/projects/index.tsx
app/tasks/pages/projects/[projectId]/tasks/[taskId].tsx

この構成では下記のルートが生成されます。

/pages/about
/pages/projects
/pages/projects/[projectId]/tasks/[taskId]

組み込みの認証とセッション管理

https://blitzjs.com/docs/auth

Blitz.jsは標準で認証(Email/Password)とセッション管理の仕組み備えています。

また、この組み込み認証は Passport.jsのadapterを備えており、Passport.jsのStrategyを追加することにより、SNS認証等を簡単に追加できます。サンプルはこちら

セッション管理はSuperTokensを参考に実装されており、実際にSperTokensのCTOであるRishabh Poddar氏が実装等を監督しているようです。

Code Scaffolding

https://blitzjs.com/docs/cli-generate

Ruby on Rails の rails generate scaffoldと同じようなCLIが提供されており、blitz generate all project name:stringで Model定義、Queryの生成、Mutationの生成、Pageの生成が行われます。

ただ現時点では Model の nameにしか対応してなさそうなコードが生成されます。どうやって作っていくべきか、という雛形としては便利ですが、コマンド一発終了という所まではいけていなさそうです。

Recipeのインストール

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

blitz install tailwindというようなコマンドを打つだけで各種設定が自動的にインストールされます。

現状の公式recipeはこちら

初期設定ファイル群

大体プロジェクトを始める時に最近では eslint / prettier / husky / git hooksなどを設定すると思いますが、それが標準で設定済みです。設定変更が必要であればそれを適用する、という程度で開発をスタートできます。(このセットで足りれば)

その他色々

ハマりどころ/難しい所

ここ最近のバージョン依存の内容も含みます。

seedが動かない

v0.24.3が現行ですが、他ファイルのimportをしているか、かどうか条件は忘れましたがseedが動かないことがあります。これは0.25.0-canary.0で修正されていますので blitz@canaryでcanaryのバージョンを使うと動きます。

generator

blitz generate で生成されるコードの型というか実装コードが型と一致していないため、自分で定義するモデル生成に使用すると型エラーが大量に発生します。このタイミングでコミットしようとするとpre-commit hooktscが含まれているのでコミットできなくなります。generateの後にコミットしたい方はpre-commitからpre-pushに移しておいても良い気がします。

また、このgenerator周りでの好みかもしれませんが、

  • Model定義をschema.prismaで行い、blitz db migrate
  • その後 blitz generate crud ModelName (queries/mutationが生成される) blitz generage pages ModelName (crudに対するpageが生成される)でひな形を作成して編集

が、良いのかなと思いました。

blitz generate xxxx で可能なオペレーションはこちらに記載されています。

Prisma Migrate

https://www.prisma.io/docs/concepts/components/prisma-migrate#supported-operations

この機能まだExperimentalなため、一部のオペレーションに対応していないので注意が必要です。

それなりにバグを踏む

まだαであり、コマンドを実行すると

You are using alpha software - if you have any problems, please open an issue here:
      https://github.com/blitz-js/blitz/issues/new/choose

と表示されるのですが、そのとおりにちょいちょバグを踏みます。見つけた場合はどんどんissue/PRあげると良さそうです。 作者がフルタイムで参加していることもあり、issue/PRに対するレスポンスはかなり良いです。slackも割とアクティブな気がするので動きを知りたい人は入っておくと良いかもしれません。 PRなど、コード面で参加する場合、コードベースは初期に参加者向けにビデオ会議で説明している動画があるので今は変わっているとこもありますが、大枠は一緒そうなのでこれを見るのも面白いと思います。

Next.js/Prisma/react-queryの知識

正直それぞれの単体をそこまで理解せずに触ってみると結構苦しいというか、何がどこのライブラリと紐付いていて、Blitz.jsがどういう変更を入れているかを理解するのに時間がかかります。なので「あー、これはあそこからの機能ね」という感じで分かるくらいで触ると結構楽しいのではと思いました。とはいえいきなり飛び込んで調べながらやってもつらいですが学びは結構ありました。

おわりに

Reactのexperimentalバージョンの依存だったり、Prismaもv2が7月リリース、migrate機能についてはまだExperimentalだったりと先を行く構成なせいか、対応していない操作だったり、対応していない関連ライブラリがありつつ、Blitzもまだαのため、現状では安定してがんがん開発していける、かはちょっと分かりませんが、触ってさくさく作れるのは楽しい所です。また、型付けがしっかりしているので候補出して使い方分かることも多くて楽です。 今回触れていない部分も大量にあるので興味が出てきた場合は是非公式チュートリアルをやってみたり、ドキュメント を読んでみてください!

なんかドキュメントを全体的に抜粋した感じになってしまった…。空き時間にちまちま一週間触ってみた程度ですので間違いや指摘があれば是非ご指摘頂ければ幸いです。

© 2020 isoppp.com all rights reserved.