🦄

TypeScriptを採用することでServerとClientのコードが共通化できるってのはほんと幻想、なのか?

2023/04/18に公開

https://twitter.com/okunokentaro/status/1647786690252263425

大枠としては同意なのだけれどツイートのコンテキストをちゃんと理解していない私のような立場からは、色々と前提というか分解する余地のある話だと思ったので書く。

筆者はTypeScript、Swift、Kotlinが好きで
https://zenn.dev/oubakiou/books/181b750dfb6838
を書く程度にはサーバーサイドTSを推している立場(そもそもTSとの馴れ初めがCloud Functions上のTS)なのでバイアスがかかっているであろう事は最初に述べておく。

サーバー/クライアントとは何を指しているか、フロントエンド/バックエンドとは異なる範囲なのか

元ツイートは、フロントエンドがNext.jsでCSR(ブラウザ)/SSR(Node.jsなどフロントエンドサーバー)、バックエンドにAPIサーバーがいる、みたいなアーキテクチャの場合にはフロントエンドとバックエンドとの間での共通化が幻想だという話だと理解している。

jQuery最盛期にもあったような、CSRで扱うviewはクライアントサイドのtsxで、SSRで扱うviewはRubyサーバーのERBでそれぞれ二重管理するみたいなのは統一された環境に対して明らかに大変だと思うのでそういう理解であってるよねたぶん。

アプリケーションコードの話なのかライブラリコードの話なのか

一般的な用法なのかは自信がないのだが、アプリケーションコードはその会社やリポジトリ固有のコードを、ライブラリコードはnpmで公開されているような固有ドメインとは距離のあるコードをさしている。

Day.jsみたいなまさにライブラリだったり、npmで実際に公開されていなかったとしてもライブラリコードに属するような性質のコードは比較的共通化され得ると思う。

アプリケーション寄りのコードであっても、例えばクライアントサイドバリデーションのためにzodスキーマを書いて、同じようなものをサーバーサイドバリデーションのために別言語でゼロから書きたくないみたいなケースはあるが、あまり数としてはないだろう。

あんまり共通化はできないとして、TypeScriptでフロントエンド/バックエンドを揃えるメリットは他にないのか

全てをTypeScriptで統一するとフロントエンドとバックエンドとでなんかよくわからないけど色々と処理を共通化できて生産性あがりまくり、みたいなのは明らかに幻想か夢まぼろしで誤った高さの期待値なので目を覚ました方が良いし、たとえTSが好きでバックエンドをTSに置き換えたいと思っても方便として使うには不誠実なのでやめたほうがいい。

じゃあ他にTSでの天下統一を訴求できる夢のようなキャッチコピーがあるかというとそんなものは無いと思うが、もし知っている人がいたらこっそり私に教えてほしい。

私は最近だとフロントエンドがTS、バックエンドがRubyの環境で仕事をする事が多いが短期間で頻繁に異種言語間を行き来する際のコンテキストスイッチコストは確実にある。テンプレートリテラルの記法違いは一生覚えられないし疑問符メソッドみたいなネーミングルール違いも自動修正が効かなくてRuboCopにしばかれ続けるし、Procやlambda周りの記法や挙動やshouldなのかexpectなのかあわわわわ。(後半は関係ない)なおコンテキストスイッチだけを問題視するなら別にTypeScriptに統一しなくても、Hotwireなんかも選択肢に入るだろうたぶん。お好みと要件に応じてどうぞ。

あとはTypeScriptで統一するメリットとして最近の流行りで言えばtRPCの存在なんかがあると思うけど、私はプロダクトの成長後も考えるとTSだけではなくSwiftやKotlinもクライアントとして扱いたい事が多いので消極的。我求識者。

避けるべき共通化の話

同一コンポーネントやモジュールの中で、isServerとかisClientとかで分岐するようなものは読んでる人間の頭がおかしくなる可能性があるので避けた方が良い。

RSCとかNext.js 13のApp Dirとかの話

元ツイートの背景の遠因になってそうな気もするけど私がまだちゃんとキャッチアップしてないので何も書けない。我求識者。(毎年4-6月の間に、できる100%TS本を改定しているのでそろそろキャッチアップを始めないといけないのだけれど)

唐突なFirestore(クライアントから直接続するリモートデータベース)の話

唐突にイレギュラーなレアケースの話になるがFirestoreの話をする。Firestoreはサーバーから接続する事も出来るが、基本的にはブラウザやスマホアプリといったクライアントからセキュリティルールを介した直接続で利用する事を主とした製品だ。

クライアントからリモートデータベースへの直接続自体が避けられるなら避けたくなる話だと私は考えているが、ワークロードなど何かしらの理由で自社サーバー経由での接続をしたくないケースもあるだろう。

またFirestoreはスキーマフリーDBなので固定化されたスキーマをDB上に持っていない。じゃあ実際にスキーマフリーに運用するかというと、コード上にスキーマ情報をもって運用する事もあるだろう。

これらのイレギュラーな条件が合致した時にはサーバーとクライアントの間でのコードとしてのスキーマ情報の共有が起こり得る。

https://zenn.dev/aldagram_tech/articles/61e064093485ff

大統一言語という幻想

私がいわゆるWeb業界に関わるようになって18年ぐらい経つが、々な言語で様々な目的、アプローチ、形態で言語統一が試みられてきた。TypeScriptエコシステムは2023年現在(Webに限って言えば)その幻想にそこそこ近付いている環境ではあるが完璧では全くないし目的とする所もかなり限定されたものだろう。

私がGraphQLスキーなのでそういう例え話をするが、例えばGraphQLサーバーがTypeScriptだったとしてもその裏側にCPUがネックになるような処理があればGoだったりRustだったりを部分的に使うだろう。(通常はあまりないが大量のノードを返すような使い方をする場合は、大量の実行時スキーマ検証なんかも発生するのでそもそもGraphQLサーバー自体がTS/Node.jsにあまり向いてない)

余談

ところで弊社ではTypeScript、Swift、Kotlin案件を10%OFFの価格でご発注いただける言語割引キャンペーンを6年ぐらいやっています。ご用命の際にはぜひキャンペーンの適用をご検討ください。

Discussion