- 長く続く製品であるほど、フロントエンドフレームワークの選定よりも、書き直しをめぐる議論に費やす時間とエネルギーのほうが大きなコストになりやすい
- 製品が5年後も生き残っていれば成功だが、その間に選んだフレームワークは時代遅れになるか、同じ名前の新バージョンで大きく変わっている可能性が高い
- より良いプロダクトチームは新しいツールに乗り換えるより、現在のフレームワークを深く理解し、ツールが業務の進捗を妨げない程度まで習熟度を高める
- 長期コストを下げるには、複雑な抽象化よりもWebプラットフォームと中核的なWeb技術に近い選択のほうが、現実的なビジネス上の折衷案になりうる
- フロントエンド生態系の複雑さは新人開発者と採用チームの双方を難しくし、Webの基礎力が弱い開発者ほど次のスタック変化に対して脆弱になる
書き直しではトレッドミルから抜け出しにくい
- 多くのフロントエンドチームは書き直しがより良い状態につながると信じているが、長く続く製品においてはフレームワーク選定そのものが最重要の技術判断ではない
- 製品が5年以上続けば成功と見なせるが、その期間のあいだに選んだフレームワークは古くなる可能性がある
- フロントエンドコミュニティは変化を中心に動き続けてきており、近い将来にそれが変わる可能性も低い
- 生き残った人気フレームワークであっても内部は完全に変わり得て、新しいバージョン番号の下で実質的に書き直されることもある
- チームが集中すべきなのは新しくてきらびやかなツールを追いかけることではなく、今使っているフレームワークを十分に習得すること
- ツールが仕事の進捗の障害にならない程度の理解と習熟が必要
- 代替ツールへ乗り換えれば問題が解決するという期待は、ほとんど罠に近い
Webプラットフォームに近いほど長期コストは下がる
- フロントエンド技術が頻繁に時代遅れになるコストを減らしたい企業なら、Webプラットフォームにより近い方向を検討できる
- 複雑な抽象化を減らし、Webが実際に何をできるのかを学び直す必要がある
- これがあらゆる問題への答えであり、無条件に優れているという意味ではない
- 長期的により多くの価値を提供し、コストを下げられるビジネス上の折衷案になりうる
- 中核的なWeb技術に近ければ、将来有能なエンジニアを採用する際に、何百万行ものコードを書き直さなければ働けないという主張に振り回されにくい
- エンジニア個人にとっても、特定のフレームワークを追い続けるより中核的なWeb技術を深く理解するほうが、長期的な市場価値により役立つ
- 短期的な採用市場での有利さの一部を手放すことにはなりうる
- 人気技術をすべて学ぼうとするやり方より、キャリアの持続性に有利
- 特定技術を知っているからといって、市況悪化のような現実から守られるわけではない
フレームワーク嗜好とチームコスト
- フレームワークへの嗜好が強いエンジニアは、その基準を求職条件に反映すべき
- すでに特定のフレームワークを使っているチームに入ったあと、自分の好むフレームワークへ切り替えさせようとすると、チームを揺るがしコストを大きく増やす
- 現在のフロントエンド生態系の複雑さは、新人開発者と企業の双方に負担を与えている
- 新人開発者は就職に十分なスキルを身につけにくく、複雑なツールに圧倒される
- 企業は一般的な開発者の採用ですら難しく感じ、正規の開発者職の参入基準も高くなる
- 現在の技術生態系を学ぶ人がWebの基礎力を学べなければ、スタックが再び変わるときに深刻な不利を被る可能性がある
- Webはソフトウェアを届けるための有能で独特なプラットフォームであり、時間とともに良くなり、高い水準の後方互換性を保ってきた
- 現在の基本ツールは十分に優れているが、フレームワーク層はプラットフォームを受け入れるよりも、それに逆らう形で動いている
1件のコメント
Hacker Newsの意見
最近、フロントエンドコードのビルドシステムを yarn から pnpm に変える作業をした。普段はバックエンドエンジニアだが、JS 周りもそれなりに経験している
フロントエンドに入るときにいちばん腹立たしいのは、本当にあらゆるものが deprecated に見えること。2022年に apollo CLI を使っていたなら、すぐに deprecated になって、graphql-client のような、まったく違う設定やオプションを持つツールを学ばなければならない。結局、古いものを維持し、pnpm の Node エンジンチェックだけをオフにして文句を言わせないようにした。何か依存関係をパッチアップグレードしようとすると型シグネチャが壊れる可能性があるので、それも固定し、いつか誰かが直してくれることを願う TODO をコードベースに残す
どうにか動くようにすると、インストール中に何百もの deprecated 警告が流れていき、ビルドが終わった瞬間に逃げ出したくなる
フロントエンド開発全体が、破壊的変更と deprecated をここまで受け入れている度合いは本当に異様に感じる。大きな Rust プロジェクトをほぼ4年やってきたが、その間サードパーティライブラリの小さな破壊的変更は何度かあったものの、アプリケーションを大きく直さなければならないような主要な変更は一度だけだった。一方 JS は、6か月も経たないうちに何かを書き直さなければならないように見える
フロントエンドの世界は、他の分野よりもソーシャルメディア、YouTube、さらには Twitch まで、はるかに積極的に取り入れてきた。こうしたインフルエンサーは relevance を保つには常に新しいネタが必要なので、コンテンツにできる新しいものを絶えず押し出してくる
そこに活発なカンファレンス文化も加わる。フロントエンドや JS のカンファレンスは、流行りの新しいテーマを発表しようとする大きな競争のように感じる
フロントエンド講座を売る市場も大きい。講座制作者は、新しい流行を学ぶ700ドルの期間限定動画講座を上司に承認させなければならないが、そのためには業界がすでに皆知っている古いものから離れさせる必要がある。だから新しいものを強く推し、古いものを deprecated にする
15年前に書いた小さな 5KLOC の純粋な JS ウェブアプリが、1行も変えないまま今でも約10人に毎日使われている。むしろ Win32 アプリケーションよりよく持ちこたえている
フロントエンドの churn の大部分は、単に政治的・組織的な失敗に近いと思う
純粋な JS/jQuery の時代に始めたころ、依存関係の管理は実質的に
.jsファイルをvendor/ディレクトリにコピーして入れる方式だった。その後 nodejs/npm が登場し、フロントエンドでは npm 以前に bower も使われ、突然、自分で作らずモジュールをダウンロードしろという助言が標準になったしかしその当時からすでに、何千行もの見えないコードを自分で所有せず、趣味でオープンソースをやっているボランティアに任せるのが正しいのか、と疑問を持つ人は多かった
今でもプロジェクトを長く維持したいなら、見えない部分を過度に肥大化させないことはできる。「このライブラリから必要なのは関数1つだけだから、ライブラリ全体に依存せず、その関数だけコードベースにコピーしてテストを付けよう」というやり方で小さな問題を処理できる
だからこれは JavaScript 自体の問題ではなく、人とプロセスの問題だと思う。こうした問題に遭遇しない JS 開発者も多いが、エコシステムの大きな部分はそうではない
「MultiselectDropdown を MultiSelectButtonDropdown に変えたらどう? API も完全に新しくしよう!」みたいな「非常に重要な」™ 破壊的変更の結果を直すために、毎日何千人時も使われている
破壊的 API の途方もないコストを理解する文化がほとんどない。Go を10年やってきた後だと特にもどかしい。Go には後方互換性の約束があり、それが Go ライブラリ開発者の互換性や破壊的変更に対する態度にも影響しているように思う。10年前に書いたコードが最新の Go でそのままコンパイルされ動作するのは、本当に良い体験だ
この JS/ウェブ地獄から抜け出そうと Flutter に移ったこともあるが、かなり合っていて、ウェブスタックの偶発的複雑さの多くを忘れることができた。だが「パッケージを壊しても構わない」という文化が Dart エコシステムにも染み込みつつあり、とても腹立たしい
正直、フロントエンドよりはるかにひどいと思う。フロントエンドはそれでも TypeScript と言語特性のおかげで、被害範囲が比較的まともな水準に制限される。Python では本当に文字どおり何でもできるし、そのためライブラリ作者たちも文字どおり何でもする。モジュールの import 方式を変えたければ変えるし、メタクラスでクラスの挙動に関するあらゆる前提を壊したければそれもできる。静的型付けが助けてくれると思っても、
Partialのような些細なものすらなく、2つのオブジェクトが同じ型だと静的に断言することもできないライブラリが変わると文句を言うのを見ると笑ってしまう。Python 2 から 3 への移行はあまりにひどく、以前の職場には Python 3 にアップグレードする計画がまったくない1億行規模の Python モノリスがあった。SqlAlchemy 1 から 2 への移行は8段階のマイグレーションで、実質的には全面書き直しであり、1つでも壊れればサイトが落ちる。それなのに React が任意で hooks を追加したと文句を言っている
不思議なのは、インターネットには「フロントエンドのトレッドミル」記事があふれているのに、その反対側について愚痴る記事はあまり見かけないことだ
「エンジニアなら、コアなWeb技術を深く理解しているほど、時間が経ってもはるかに高い市場価値を維持できる」という話については、フロントエンドをほぼ20年やってきて、いくつもの大きなパラダイム転換を経験しているので、意見を言う資格はあると思う
コアなWeb技術をすべて知っていれば、よりバランスの取れたエンジニアになるのは確かにその通り。ただ、それが採用市場でより魅力的に見せてくれるかは懐疑的。こうした知識が重要でないからではなく、採用の意思決定者はたいていパターンマッチングをするから
「市場価値」を最大化したいなら、今でもReactに非常に強い必要がある。これは入場券に近く、それ以外は素晴らしいが、その土台がないと選択肢は減る。もしかすると投稿者はそういう意味で言っていて、こちらが読み違えたのかもしれない
ただし、コンサルティングや契約社員のような役割では元コメントに同意する。大手コンサル会社で、採用したり面接対象にするかを決めたりする人たちと一緒に働いてみると、彼らが好むスタックや現在の顧客企業が使っているスタックをすでに知らない人は、ほぼ自動的に落とされる。テクニカルアーキテクトもそうなので、非技術系の採用担当者だけの問題ではない。熟練度に関係なく、技術そのものに適応する時間を望んでいない
こうした役割では、常に最新の状態を保つことが非常に重要。そうでないと、採用マネージャーがエンジニアに実力を評価させる前に、バズワードがないという理由で履歴書を捨てる
特殊な例かもしれないが、Reactを知らないことが問題になったことはなかった。「入場券」という表現は強すぎる
フロントエンドには報酬にかなりしっかりした上限がある。一定水準以上に上がると、二度とUIを作る必要がなくなる
ほとんどの会社、さらには大企業でさえ、コアな基礎を大して気にしたり検証したり、それを基準に採用したりはしない。「Reactが得意」や「Next.jsの経験が豊富」といった基準で採用する
基礎はゼロから何かを作るときには素晴らしいが、実際の会社はそういうことをほとんどしない。たいていはエコシステムが大きく、ドキュメントが充実した既製品を持ってきて使う。そうしたものに強ければ、はるかに採用されやすく、基礎はその過程で学べる
「どのフレームワークを選んでも5年後にはobsoleteになる」という話は、少し古い論法に見える
主にフロントエンド開発者というわけではないが、フロントエンドをやるときに避けているわけでもなく、この10年ほどReactを使ってきた。Svelteのほうへ一部の空気は移りつつあるが、SvelteがReactを追い越す頃には、おそらくSvelteもそれだけ長く本番環境で使われた後になっているだろう。Angularもいつか勢いが落ちるかもしれないが、Angular1とAngular2+の時代を合わせて見ると、Reactよりも古い
フロントエンド開発が速く動くのは確かだが、そこまでひどくはない。退屈な選択をすれば、退屈な結果になる
Angular1と2は、名前以外はほとんど比較できないほど違っていて、多くの開発者がここで痛い目を見た。Angular自体もかなり大きく変わっている。v1からAngular2へ移行したときほどではないが、それでも相当な再適応が必要なほどだ。すべてがstandalone component、新しいテンプレート構文、signalsなどへ移行している
Reactも似ている。関数コンポーネントとhooksの登場で、大きなパラダイム転換があった。互換性はあったが、互いに非常に異なっていた
より一般的なパラダイムでも同じ。最初はすべてサーバーサイドレンダリングだったのが、シングルページアプリへ全力疾走し、再びサーバーサイドレンダリングへ戻ってきたが、今度はhydrationを伴う部分的なサーバーサイドレンダリングになった
別のフレームワークと言ってもいいほど違うので、ニュアンスはあるが、その論理が完全に死んだわけではない
作業するのが本当にシンプル。簡単な株式配分アプリを作ったが、いちばん驚いたのはバンドルサイズだった。gzip基準で9KBで、知っているどのフレームワークよりも小さい。ある程度「反JS」に近いhtmxよりも小さい
古いフレームワークでも非常に長く動かせる。そのスタックを知っている人が存在し、必要なときに雇って作業してもらえるなら、そのスタックはobsoleteではない。「古い」や「レガシー」は当てはまるかもしれない。だが、それを扱える人が誰も残らない日が来るまではobsoleteではない
これをフロントエンドの問題と呼ぶのは興味深い。フロントエンドの問題ではなく、巨大なエコシステムに新しい参加者が入り続ける問題だ
15年前、Java がイノベーションの最前線にあったときにも、まったく同じことを見た。数年の間に数十のフレームワークと複数のビルドシステムが登場した。React 17 から 18 への変化は、Perl 5 から 6、Python 2 から 3 へ移るよりもはるかに小さい変化だ
バックエンドでは「新しいフレームワークを使おう」の代わりに「新しい言語を使おう」が出てくる。最近の流行は何かを Rust で書き直すことで、その前には Go、Haskell、Scala、F# もあった
React から Svelte のようなものへフロントエンドコードを移すのが面倒だと思うなら、VB 6 アプリを書き直してみればいい。データがコードの中にある RPC のようなものは言うまでもない
エンジニアリング慣行の不安定さが問題ではない、という意味ではない。大きな問題だ。ただし、フロントエンドだけの問題ではない
webpack も 13年になるが、ここ数年の間だけでも設定方法が劇的に変わった
Apache の設定がこれらのシステムと同じくらい頻繁に変わっていたら、誰も Apache を使わなかっただろう
以前の職場では、2年間でデータベース移行が2回あり、合計で1年分のエンジニアリング時間を費やした。一部の非中核テーブルではなく、すべてのテーブルが対象だった。何かが壊れたり、上層部からなぜこんなに遅いのかと聞かれたりすると、経験不足を理由にフロントエンドを学んでいるエンジニアたちのせいにしていた
25年以上 Java 開発者として働き、最初の10年強はフルスタック開発をしていたし、それが当時の会社では一般的な形だった。今ではフロントエンドの別チームがあるのが普通で、Web・iOS・Android の3チームがある場合も多い。私にとっては AngularJS から Angular へ移行していた時期あたりで、その変化が起きた
Java も最初の10年ほどは速く変化し、特に最初の3年は非常に速かった。だがその時期は終わった。Java 5 は大きな変化で、Java 8 にも主要な機能があったが、Java 8 は 2014年だ。私たちのチームは最近ようやく Java 11 へ移行し、今では Java 24 が出ている。私は Java 11 の機能を使ったこともなく、何なのかも知らない。10年間、新しい言語機能を一つも学んでいない
ビルドツールはこの15年間同じで、IDE はこの20年間同じだ。主に使うフレームワークも10年間同じだ。最後の職場に移ったとき、コードベースの構造は前のチームとまったく同じだった
Java で Web サービスを作ることは解決済みの問題だ。良い意味で完全に退屈で、COBOL のようなものだ
フロントエンドは90年代後半から2000年代初頭にも速く変化していたが、その後もずっと速く変化し続けてきた。数年前に作った個人の UI プロジェクトは、完全に古びてしまった
EJB 以後の時代に私が作業した Java プロジェクトなら、今日 Java 開発者を見つけて投入しても、すぐに生産性を出せるはずだ。その開発者がプロジェクトが作られた後に生まれていたとしても可能だ。学ぶべき古いライブラリがいくつかあるだけだ
ランニングマシンから降りる方法は、フロントエンドフレームワークをそもそも使わないことだ。任意の別のフレームワークを選んで、後でまた書き直すことではない
サーバーサイドレンダリング、必要なときだけ JavaScript、社内でバックエンドとフロントエンドの人員を分けないやり方が必要だ
1人のエンジニアが SSR の Web ビューに必要な正確なカラムだけを取得する SQL を書き、その Web ビューも担当できるなら、API や ORM のようなものについて1秒たりとも悩む必要はない。SQL と現代的な素の HTML/CSS/JS だけを知っていればよい。やることの大半が、ビジネスのビュー(SQL)を DOM(HTML)へ変換することになり、サーバー側プログラミングのエコシステムは後景に退く
最終形は RDBMS の中で Web コンテンツを SSR することだと思う。Oracle APEX のような方式だ。だが、ほとんどのエンジニアはまだその会話をする準備ができていない。私も実際の現場で初めて見たときはそうだった。私たちは苦しむやり方にあまりにも愛着を持ちすぎている
フロントエンドが過度に複雑になる問題を悪化させた。フロントエンドチームに人がいるので、彼らは仕事を作り続け、複雑性を足していく。Web 開発だけを知っていて他は何も知らない人が多くなりすぎたことも問題だ
サイドプロジェクトで、初期の制約の一つを、JavaScript をオフにしてもサイト全体が優雅に機能低下するようにすることにした。すると、通常なら JavaScript でやる機能を追加しようとするたびに「これは JavaScript なしでできるのか?」と問うようになったが、今のところ驚くことに答えはいつも yes だった
基本的な HTML コントロールに対するCSS セレクタだけでも、今では本当に多くのことができる。そのコードベースにはまだ JS が1行もない
プロダクト/デザインチームは、ユーザビリティ、性能、アクセシビリティ、良いエンジニアリングをまったく考慮せず、可能な限り多くの JavaScript の装飾を入れろと押し通すことがある
私はフロントエンドが得意ではなく、デザイナーもいない。バックエンドのほうがずっと得意だが、チームの他の人たちはフロントエンドデザインにおいて私より才能がある
初めてWebサイトを作ったとき、「SvelteはReactより優れている」「solid-jsが次の本命になる」といった記事を読んで、それがWeb開発の重要な部分だと思っていた
初心者はMDNを読んで、残りは無視するのがよい
人にはチュートリアルやウォークスルーが必要で、これらすべてがどう動いているのかについて内部的な理解を積み上げる必要がある
フレームワークはその部分を抽象化する助けになる
ただし最近のNext.jsとSSRへの執着はそうではないかもしれない。個人的には、これがReact側の衰退要因になる可能性もあると思っている
ここ数年で素のJSとCSSが進歩したことを考えると、そして
display: noneのアニメーションのような興味深い機能がほぼ採用段階に来ていることを考えると、サーバーでテンプレートHTMLを作り、必要な箇所にだけJSを使う方式は、これまでになく妥当に見えるReactで主に食べている人間として言っている
筆者と同じく、自分も何らかの形で20年間フロントエンドをやってきた。エコシステム、churn、フロントエンドとバックエンドの間で状態を同期する曲芸は本当に常軌を逸している
最近、Go templatesとHTMXで概念実証プロジェクトを始め、Reactのように「コンポーネント」でUIを作る感覚に近づけようとしている。まだ荒い部分は多いが、可能性はある。正直、HTMXが必要なのかもまだ確信がない。イベントリスナーを自分で管理し始めたところだが、そのほうが気に入っているように思う
興味深いことに、ユーザーのロールと権限に基づく複雑なUI状態管理は、サーバー側のほうがはるかに簡単だ。ユーザーが見られるHTMLだけを送れば終わりだからだ
ただしReactやVueなどにはものすごい推進力がある。考え方の集団的な転換がどう始まり得るのか分からない。特に、UIを作る方法としてフロントエンドフレームワークしか知らない開発者が多いことを考えるとなおさらだ
「どのフレームワークを選んでも5年後にはobsoleteになる」という話は、よく分からない
10年以上プロとしてReactを使ってきた
package.jsonに依存関係はいくつ宣言されている? チームはどのnode/npmバージョンを使っている?十分に新しいバージョンを使い、人気ライブラリを使っているなら、
npm install中に下位依存関係へのdeprecated通知が積み上がるのを見たことがあるはずだ公平に言えば、Reactのコード自体は後方互換性をかなりよく保ってきたと思う。Reactのせいではない。だが5年前に使っていたビルドシステムはすべて変わり、後方互換性を壊した。コンポーネントのライフサイクルメソッドのことも忘れていた
Reactのように適切に管理されているプロジェクトでさえ、そのエコシステムの混沌からは逃れられない
常に選べるわけではないが、最近はたいてい素のJSをビルドシステムなしでimportし、可能な限りPython/Djangoバックエンド側で処理して、JavaScriptエコシステムから完全に抜け出す方法を選んでいる。後悔したことはない
まだアプリをReact 15のままにしているのか?
React 16で動くすべてのWYSIWYGエディタは、もうサポートされていない。セキュリティ問題が見つかったら「運任せ」の状況だ。あるいは使うべきではない
React 16はまだサポートされているが、明らかにobsoleteだ
反論としては、フレームワークを採用しなければ、結局チーム外の人が理解できず、ドキュメントもたいてい貧弱で、既存のフレームワークにすでにある機能を追加し続けなければならない独自フレームワークを作ることになる、というものだ
フロントエンドには共通して必要な機能と、解決すべき共通の問題がある。何もない状態から始めるより、少なくとも何かを敷いて始めたほうがよいのではないか?
社内フレームワークを見たことがないので、すぐに生産性を出せる人を見つけるのは不可能だ。ドキュメントが非常によく整っていても、学び、身につけるには時間がかかる。長期採用なら最悪ではないが、一時的に開発者がさらに必要になったら打つ手がない
他のところでも書いたが、ほとんどの人がWebアプリを望んでいる、あるいは自分たちはWebアプリを持っていると思っているものの、実際にはたいてい動的Webサイトにすぎない。動的Webサイトを作るためにフレームワークを積み上げる必要はない
これはフロントエンドの問題ではなく、JSエコシステムの問題だ。バックエンドでも起きている
JS環境は、依存関係が数十、数百もの別の依存関係を持つ、完全な大混乱だ。たとえばFastifyベースのNodeフレームワークであるPlatformaticの依存関係グラフは次のとおりだ
https://npmgraph.js.org/?q=platformatic#zoom=h
これらの依存関係は、いつ捨てられてもおかしくない。AxiosやExpressのような巨大な依存関係でさえ、一時期放置されているように見えた
そして各依存関係は、メンテナーが正しいと考えるやり方に支配される。数日前には、本番環境で使っている依存関係の一つが、週あたり約2,500万ダウンロードを記録し、Reactが約2,600万という水準で、GitHubリポジトリ1,000万個で使われているにもかかわらず、約3年前のSafariバージョンのサポートを打ち切ってよいと判断した。Safariが米国モバイル市場シェアで50%以上を占めることを考えると、本当に狂っている