フロントエンドのランタイムとかビルドツールとかエコシステム的なものを学ぶ
雰囲気でnodeもnpmも使ってるのでもろもろちゃんと調べてみる。
ランタイム
とりあえずランタイムについて。JavaScriptの実行環境について大きく以下のような場所があると理解している。
- ブラウザ
- Node
- Deno
- Bun
- Cloudflare Workers
JavaScriptの実行エンジンとしては1番有名なのでV8エンジンがあると思うがこれはChromeやNode, Deno, Cloudflare Workersとほとんどの実行環境で使用されている。ちなみに、BunはSafariで使用されているJavaScriptCoreがエンジンとして使用されているらしい。
DenoやBun, Cloudflare Workersといった先進的な技術は非常に魅力的だけどまだ実務運用できるフェーズではないという気もするので一旦ブラウザとNodeの話。
Webブラウザ
Webブラウザでサイトが表示されるには様々な技術が複雑に絡み合って表示されている。JavaScriptはシングルスレッドのためイベントループを使った非同期処理、DOM、JavaScriptやHTML、CSSなどが組み合わされた結果webサイトとして表示することができている。
この仕組みの詳細はまた難しくなるのでまた今度。
フロントエンドを追うならWeb標準を追えとよく聞くが、Web標準とは各団体が定めるHTML, JavaScript, CSS, DOM, アクセシビリティといった技術の標準化であり、これらは Mozilaが運営するMDNを読むのが1番学びになりそう。
このWeb標準を追うのも大変なため詳細はまた今度。
Node
Node.jsはサーバーでJavaScriptを実行するために開発されたランタイムでエンジンにはV8エンジンが使われている。Nodeには標準でnpmというパッケージマネージャーが同梱されており最近ではTypeScriptやテストも標準で組み込まれてそうで開発は積極的にまだ続いている。
また、モジュールシステムとしてCommonJSが使われてきた経緯があるがESMをサポートしておりもうrequreなどは使わなくてよくなっているが、公開されているライブラリによってはまだESM対応していないのもありそう。
DenoやBunなどがあるが現状Next.jsなどを動かすにはNodeで動かすしかない。
サーバーTSならBun + Honoとかできるのかな?
Cloud RunならDockerfileを書くわけなのでDockerfileのimageにBunとかを指定すれば普通に動きそう。
Nodeも掘り下げればまだいろいろありそうだけど詳細はまた今度。
Nodeのバージョン管理
nvmとかnodenvとかいろいろあったけど今はこちらが良さそう。
プロジェクトでnodeのバージョンを固定したい場合は、package.jsonにvolta特有のフィールドを追加することで実現できそうだが、チーム全体でvoltaを使用することを強要することになるので.npmrcなどに記載してバージョン違いによるパッケージインストールをエラーにするくらいがいいのかな?ちょっとここの良い運用はまだよくわからない。
とりあえずvolta使ってみる。
curl https://get.volta.sh | bash
export VOLTA_HOME=$HOME/.volta
export PATH="$VOLTA_HOME/bin:$PATH"
volta -v
2.0.1
# LTSのnodeをインストール
volta install node
パッケージマネージャー
今のところ以下の3つが存在する
- npm
- yarn
- pnpm
Nodeにnpmは同梱されているため1番簡単に使えるが今普通に使うならpnpmが良さそう。あんまり良く知らないけど。ちなみに、voltaでnodeインストールしたらpnpmも一緒にインストールされてた。
package.jsonをもとにパッケージをnode_modulesにインストールするならばBun installでも可能で、Bunはパッケージマネージャーとしても機能するよう。
ビルド
ビルドに関しては今はviteを使っていれば問題ないでしょう。JavaScriptのビルドには歴史的にBabelのようなトランスパイラやWebpackのようなバンドラーが必要だったが今はviteがいい感じになんとかしてくれる。
viteは内部でesbuildとRollupを使ってる。
viteに遅れてTurbopackというツールもあり、Nextが正式採用しているっぽいのでもしかしたらTurbopackが来る未来もあるかもしれない。
TypeScript
TypeScriptで書かれたプログラムをビルドして実行するにはコンパイラであるtscを使い、トランスパイルをする必要がある。tscの役割は型チェックとトランスパイルであり、TypsScriptで書かれたプログラムは最終的にはその型はすべて剥がされることになる。
実際はviteなどを使うことが多いと思うし、生のTypeScriptのコードを書くならDenoとかを使うのが1番簡単そう。NodeのデフォルトTSサポートの話も出てたし。
エコシステム
テスト
テストはjestが主流だったっぽいが今はvitestで書いてるっぽい。正直なんでBDDっぽいテスティングフレームワークが好まれるのかはよくわかってないが、みんなが使うものに従おう。
jestやvitestはカスタムhookやコンポーネントのロジックをテストする単体テストに使用されるでしょう。フロントエンドはViewに対してテストをしなければならず、ビューの最小限のテスト、つまりコンポーネント単位のテストは後述のStory Bookを使うことである程度できるのかなと思ってるけど、正直わからない。
どちらかといえばフロントエンドにおいてはe2eテストやビジュアルリグレッションテストなどを導入したほうが多くのユースケース、結合されたビューのテストができ、品質の向上につながるだろう。
e2eテストやビジュアルリグレッションテストでよく聞くのはpuppetterやplaywraightだろう。
CSS
最近の流行りとしてCSSをJSと一緒に書き、コンポーネント内で閉じているというのがある。これはCSS in JSと呼ばれEmotionやvanillajsといったライブラリがたくさんある。何を使ったらいいのかよくわからない。Nextが古くからあるCSS modulesを採用したとかで正直何が生き残るかわからないのでCSS modules使っといた方が何が生き残っても変更しやすいよみたいな話も聞いた。
別のアプローチとしてTailwindがある。これはBootstrapのようなクラスでスタイルを作っていくスタイルで可読性が終わるみたいな意見もあるけど、AIで生成しやすいみたいな意見も聞いた。
正直CSSは個人的にはなんでもいいのでCSS modulesかTailswindを使うと思う。
UIコンポーネント
すでに用意されているコンポーネントを使えるライブラリ。モーダルとか一から作らなくていいんだと思う。1番よく聞くのはChakra UI。
最近はshadcn/uiをよく聞く。
データフェッチ
これは採用している通信プロトコルによりそうだが以下のようなライブラリがありそう。
- SWR(Vercelが開発)
- React Query(Tanstack Query)
- React Queryは以前の名称で今はTanstack Queryが正式名称らしい
- Appollo Client(GraphQL)
ルーティング
Next.jsなどを使っていれば追加で用意する必要はないがReactでSPAを作るとなるとルーティングが必要になる。これにはReact Routerが使われてきた。
で、あんまり詳しく調べていないがReact Routerは単純なルーティング以外の機能も持ちフルスタックルーティングよ呼ばれるような存在になっているよう。そして、最近よく聞くRemixとReact Routerの差分がほとんどなくなってきたとしてRemixとReact Routerを統合しReact Router v7の名称で次のRemixは出すとのことで少しざわついていた。
そして、今はTanstack Routerという選択肢も増えたらしくReactでSPAを作ろうとするならば、ルーティングライブラリについても考える必要がありそう。
たた、React RouterがもはやRemixというのであればRemixを使うかReact + Tanstack Routerみたいな感じになるのだろうか。
通信クライアント
- HTTP
- gRPC
- Connect
- GraphQL
- tRPC
みたいな感じだろうか。
とりあえず、HTTP通信というかRestなAPIとやりとりするなら前述のデータフェッチライブラリを使っていい感じにデータ取得と更新を行えばよい気がする。
OpenAPIで作られているならAPI定義から型生成もできそうなので型安全にデータのやり取りを行えそう。
gRPCに関してはgRPC-webを使うことになると思うが、gRPCサーバーの前段にenvoyを立てる必要があり、手間なのとConnectがメジャーリリースされた今Connectで良いと思う。
ConnectはProtobuf定義で型安全にサーバーとやりとりできるので個人的には推しだが、GraphQLやtRPC、Tanstack Queryなんかと比べた時にどうなのかはわからないのでなんとも言えない。
最近GraphQLでさえやりすぎだというか面倒だみたいな意見も聞くが、現状いい感じにクライアント主導でデータを取得するならGraphQLなんじゃないかなとは思う。
APIもTSで書くならtRPCを採用すると、APIエンドポイントなどを作成することなくフロントとサーバー間でシームレスにデータのやりとりができる。
GraphQLがやりすぎでprismaのTypedSQLでフロント側にデータ取得の主導権を寄せて、データの更新に関してはサーバーを使うのが良さそうみたいな話がmizuchiさん発端で盛り上がっていた。
それはCQRS的な作りが前提ということであり、それを実現したいのであればデータ更新を命令するコマンドはHTTP通信的なものよりもRPC的なものの方が都合がいいとのことでかとじゅんさんが言っていた。
たしかにそうなる未来はありそうだなとは思うけど前提のサーバーがCQRSに対応してDBを構築するというのがけっこうハードル高いのではないかというのもあり、その理想型に近づいていくかは不明。
でも、フロントの人たちはみんなprisma大好きでその形を望んでいそう、な気がする。
ConnectもRPCみたいなものだから個人的にはフルスタックTS + Connectみたいな方向を探ろうかなと思う。
認証
たぶんNext使うならNextAuthを使っておけばよい
状態管理
RecoilとjotaiがあってRecoilが開発止まった?とかでjotai使う流れがあったきがするが、そもそもみんながどのくらい状態管理を使っているかはわからない。
フォーム
React Hook Formという便利なのがあるそうな
バリデーション
バリデーションといえばzodを使ってる感じがします
DB
フロントの話じゃなくなるけどRSCとかの登場でDB操作までフロントでやるようになる未来がきたりとか、フルスタックTSでサーバーもTSで書くならDB操作は不可欠でとりあえず現状prismaが最有力っぽい。まだ成熟しなさはあるけどという意見を聞く
コンポーネントカタログ
Story Bookを使い、再利用性のあるコンポーネントの作成、テスト、ドキュメント化が実現できると思っている。なんとなくTDDやAPI仕様書ファーストな開発と近しいものを感じ気になる技術。
話は微妙に変わるがデザインシステムやデザイントークンみたいない用語も聞くがこれらはアプリケーション全体で一貫性のあるUI/UXを提供するためのあらゆるデザインの集合みたいなもの。
デジタル庁のデザインシステムが公開されて話題になっていたけどデザインシステムを導入しようというのはけっこうしんどい気はする。
Story Bookに関してはデザイナーとエンジニア双方から合意を得る必要がありそうでこれも導入はけっこうめんどくさい気がする。
なんとなくわかった