😸

フロントエンドの消失 - または戦争が激しくなる話

2021/01/09に公開
1

React Server Components に感じたフロントエンドの消失という記事に端を発する一連の議論だが、実際この記事で書かれていることはそうだろうなと思う。話の流れとして誤ってる部分はないと思うし同意する。

この記事ではフロントエンドエンジニアとして、この件についてのの見解を書く。もちろんフロントエンド(とは?)の総意ではない。

元記事と重複する部分多いが、そこは同じ問題を取り扱う以上避けて通れないため、ご容赦いただきたい。

  • 同じ領域を取り扱ってる以上、開発戦争は激しくなる
  • 様々な理由によりユニバーサルが求められている

※この記事でいう「戦争」とは、お互いの領域を食い合う開発が、活発化することを「戦争」と称しているだけです。それ以上の意図は全くございません

領域がかぶっている

最近のフロントエンド系ユニバーサルエコシステムは、たしかに PHP や Rails の領分を侵そうとしているのは間違いがない。少なくともフルスタックフレームワークを謳うもの、たとえば blitz などは間違いなく PHP や Rails を打倒するために日々進化を続けていくはずだ。

React Server Components

ただし、React Server Components 自体はそこまで明確に PHP や Rails の領分を奪おうとはしていない。React Server Components は、React コンポーネントというコンテキストでサーバーコード(Node.js)も記述できる以外の何者でもないからだ。(もしかしたら今後の方向性が変わるかもしれないが、ないと思う)

PoC(概念実証)となる最初のデモである https://github.com/reactjs/server-components-demo では、サーバーコンポーネント上で、Web API を fetch できるように作られている。実際には PostgreSQL を叩くコードの方が有効化されていて Web API を叩くのはコメントアウトされているが……。

Facebook 社が React 開発だけではなく PHP でも有名な会社であることを思い出してほしい。すでにある資産を考えると BFF として動くことが自然ではある。

もちろん React Server Components を使ってさらに踏み込むことで、バックエンドを持たずに単体でサービスを作れるポテンシャルはあるが、それを実際にやるかどうかは React Server Components の範囲ではない。

  • React Server Components は、単に React コンポーネントというコンテキストでバックエンドと透過的に構築できるようにする技術なだけ

システムの境界

フロントエンドとバックエンドの関係を考えるということは、システムの境界について考えることだ。

ソフトウェア開発において有名なコンウェイの法則がある。

システムを設計する組織は、その構造をそっくりまねた構造の設計を生み出してしまう

たとえば、あるプロダクトに、フロントエンドチームとバックエンドチームがいるとする。このときバックエンドチームは別会社だとする。指揮系統も違えば日々の営みも違う。このような組織構造のときに、境界のないシステムを作ることは可能だろうか?「フロントエンドチームさんは〇〇を開発してほしいんですよね」「いや、〇〇はバックエンドチームさんでやってほしい」という綱引きが日々生じ、開発における様々な情報やノウハウ、コードの sync タイミングはそんなに頻繁でもない。

このような組織ではユニバーサルフレームワークを採用することは現実的ではない。どこかで境界を引く必要がある。

「フロントエンド」「バックエンド」というものが明確に分かれている、大きな理由はそのようなものだ。このようなケースでは人事採用の方法ももちろん違うだろう。

  • 組織の境界によって、システム境界が生じる

では、統合された組織では?

たとえば、あるプロダクトに数人しかおらず、組織的な壁がないとする。このとき「フロントエンド」と「バックエンド」が明確に分かれている必要性はあるのだろうか?

React で、保守性・性能・設計・デザイン・UI・UX・自動テスティング・セキュリティを気にしつつ、Rails で、保守性・性能・設計・自動テスティング・セキュリティを気にしなければいけない。それらを統合して考え、全体を設計できなければならないし、なんならスクラム開発や、アジャイルプラクティスの採用なんかもしているだろう。開発速度も蔑ろにはできない。

両方を高度に実現可能な人材は、果たしてどれくらいいるだろうか?片方に絞り込めばまだそれなりに見つけられるだろう。

React 専門家と Rails 専門家を雇ったとして、同じチームだがシステムの境界が生じることになる。それはなにか不自然ではないだろうか?

React 専門家は、Rails にあれこれ質問をしたり要望を出すだろう。Rails 専門家も React にあれこれいうはずだ。シームレスなある一つのチームが複数のシステムを抱えようとすると、支払うコストは大きくなってしまう。

そもそも React の専門スキル・経験を持っている人材は、まだ Node.js なら問題なく触れる余地はある。Rails を新たに覚えるよりは現実的だ。Rails が作成したバックエンドを直接触りたくない React は BFF を立ち上げることにする。Node.js + express なのか、Apollo Server in Node.js なのかはさておこう。

これは行き過ぎてるのか?プロダクト開発初期であれば、さすがにこういう光景にはならないかもしれないが、3 年以上開発が続いていたとしたらどうだろうか?Rails も、React も、コードが高度になっていて、専門家達はそれぞれ双方をいじるにはしんどい状態になっていたとしたら、BFF を立ち上げて、システム境界をさらに強固なものにしている、というのは、普通にありえるだろう。

そうやってチームは、システム境界によって分断されてしまう。「側」という言葉が頻出するようであれば、人の境界が存在しているサインだと考えた方がいいだろう。

どう考えても、同じ一つのシステムで実現できる方がいいに決まっている。React Server Components ができる人材がいて、その一人、もしくは複数人が、一つのシステムを開発する方が効率が良いだろう。あるいは Rails でユニバーサルを実用しようとする Hotwire でも同様だ。

これがユニバーサルフレームワークが求められる理由だ。

  • 一つの小さなチームが、複数の高度なシステムを扱うのはコストが大きすぎる

歴史が繰り返され、何度も何度もそういった試みが行われるのは当然なことだと、理解してもらえただろう。

個人

※一個人の感情なので真に受けなくていいです

たとえば、僕は、フロントエンドを触った期間よりはバックエンドをやってた期間の方が長いが、Rails に対しては思うところが色々あったり、個人的には ActiveRecord や ORM を触るよりは、SQL を直接書くほうがまだマシだと思っていたりする。

まぁこれはあくまで、僕という一個人の経験、履歴、感情そういったものに過ぎない。これを他人に押し付けるつもりはまったくないし、他人から、何かを押し付けられる類のものでもない。というか、単にそんな人間もいるんだなーへー、くらいに思っていただければ。

※一個人の感情なので真に受けなくていいです


同様に、日本中のエンジニア、世界中のエンジニアにそれぞれに事情が存在するのだ。

Haskell しか触りたくない人もいるだろう。Scala 最高って人もいるだろう。Rails がすべてという人もいるだろう。JavaScript なんて触りたくない人が一定数いるのも間違いない。

みんなの考えは全部正しい。世界には一つ一つの花があるのだ。たぶん。そして人間は感情の生き物である以上、そういった事情は無視できない要因である。

だからこそ同じようなアプローチが歴史を超えて何度も繰り返されるし、戦争はどんどん激しくなるだろう。それは間違いない。

Node.js

僕の個人的なことを言うと、Node.js でコードを書くのは苦にならないし、むしろ楽しい仕事である。

それでも Node.js と React を使う場合、システムに実際に落とし込むことを考えたときに、結構めんどくさいのが事実なのだ。

React はもはや TypeScript とセットになっている。型安全がない環境なんて触りたくもない。当然サーバー側も TypeScript で記述するし、API アクセスも型安全でなければいけない。

このとき、Node.js のコードと、React のコードが別れている状態であれば、そこを繋ぐ API アクセスは自動生成なりされなければいけない。そうでなければ、サーバー のコードと、React での API アクセスのコードは、二重メンテナンス状態になってしまう。

OpenAPI や GraphQL のコード生成などがこういったところでは利用されるが、設定がかなりめんどくさい。死ぬほどめんどくさい。

GraphQL 自体が型を持っているし、完全に自動で TypeScript の型に変換できるわけでもない。設定を頑張らなければならないのだ。OpenAPI も似たようなものだ。

もちろんこの問題だけではない。設定や設計しなければいけないものは大量にある。

React と Node.js が「完全に分離」していることは、それなりにペインなのだ。

これを解決するアプローチとして、最近の JavaScript 系フルスタックフレームワークがある。定番と呼ばれるものを全部ぶち込んでペインを隠蔽してくれるものだ。

ところが、React Server Components はそんなことをしなくても「コンポーネント指向」で混ぜ込めるということを提示したのが、最高にクールなのだ。Next.js には随時 React Server Components の技術が取り込まれていくことだろう。僕が React Server Components はウェブ開発を変えるゲームチェンジングな技術である という記事を書いた理由はこれだ。

フロントエンド領域の人間が BFF を書くのは苦痛なのか?

"Web フロントエンド"の悲しみと明るい未来という記事に書かれているような

ここまでしないとフロントの人がサーバー側を書いてくれないという現実

はあるかもしれないし、ないかもしれない。人によるとしか言えない。

もしかしたら、書きたくない人の多くは、実は単に僕と同じように、設定などがめんどくさい、あるいはコードの二重管理状態が嫌だ と思ってる人なのかもしれないし、違うのかもしれない。

ただ、バックエンドからフロントエンドに転向する人間は、バックエンドのコードを書くこと自体は苦にはならないはずだ。そして、今後はそのような人間が増えると、個人的には予測している。

技術の螺旋

ソフトウェア技術に限らずだが、技術は度々、振り子のように揺り戻しがある。単体実行 vs 並列実行 vs 並行実行、シリアル vs パラレル、密結合 vs 疎結合。ウェブ技術におけるバックエンドとフロントエンドの関係もそうだ。

でも「同じことを繰り返してるんじゃねーの?」と思ったら、それはそういうものだと思っていい。もちろん繰り返すのには理由があるし、ほんとうの意味で同じことを繰り返しているのではなく、少しずつ進化している。

参考: 技術選定の審美眼。時代を超えて生き続ける技術と、破壊的な変化をもたらす技術を見極める(前編)。デブサミ 2018 - Publickey

技術は振り子運動をしているのではなく、螺旋状に進化し続けているのだ。

まとめ

ユニバーサルという流れが登場するのは自然だし、同じ領域について取り扱うためには、それがサーバー側由来の技術で持つのか、JavaScript エコシステムで持つのかで、戦争は激しくなるよねという結論になる。

React core チーム(Facebook 社)が React Server Components を打ち出したり、Next.js(Vercel)と仲良くしている以上、今後 React エコシステムが少なくとも BFF にまでは侵食していくことはもう確定している。

Rails の DHH の考えについても言うまでもないだろう。

個人的な予測

※一個人の予測なので真に受けなくていいです

個人的な予測だが、JavaScript エコシステムによるユニバーサルが一番勢いがあって、少なくとも 5 年単位では優勢だと思っている。wasm 系エコシステムが育つにはまだまだ時間がかかるだろうし。

これが単なる BFF で終わるのか、もっと踏み込んでバックエンド全域で JavaScript エコシステムが盛況になるかは戦況次第だが、バックエンドからフロントエンドへ転向する人間が増えれば増えるほどこの流れは加速するはず。JavaScript エコシステムの領域が広がれば広がるほど転向する人間が増えるはずなので、状況は加速度的に移りゆくと予測している。

バックエンド JavaScript エコシステムが盛況になったとして、完全なる統合フレームワークになるか、React Server Components(Next.js)+ Node.js backend という構造になるかはまた別の話だ。もしかしたらモジュラモノリスという方向かもしれないし、そうじゃないかもしれない。

React Server Componets という次なるキー技術を受けて、JavaScript ユニバーサルが大きく見直されるとは思っている。そういった JavaScript ユニバーサルがどういう形になるのかという話は、何か考えがまとまったら記事を書きたい。

※一個人の予測なので真に受けなくていいです

Discussion

kodukikoduki

完全に同意な記事でした。
今見たいにJS層が厚くない頃にPHPのフロントエンドとJavaのAPIで開発してたことがあるので、システムの境界の話はとても良く分かります!