明日の下書き --- ## これはなに - 高円寺.dev #3 用の資料 https://koenji.connpass.com/event/160886/ - フロントエンド専門じゃない人向けの、フロントエンドの最先端〜やや未来の話です - このレイヤーでは Node.js を使うべき/使うと強いという部分がありますが、他言語を否定しているわけではありません。むしろ他言語でこのアーキテクチャを模倣してほしいという話です。 --- # 10 年代のフロントエンドのポストモーテム --- ## 10 年代まとめ - IE が死ななかったので各種ポリフィル、メタ言語からのトランスパイルが発達。しかしモダンとレガシーの乖離が深刻に。 - node と npm エコシステムの成立 - 仮想 DOM がフロントエンドライブラリの標準的な状態管理手法に - モジュールシステム需要が ES Modules(ES2015)に結実。しかし webpack は死ねなかった。 --- ## モダンとレガシーの乖離 - IE 需要+ブラウザ自身も後方互換性を維持し続けたために、先進的な技術を使う人と、素朴なサポート水準の技術を使う人のスキルセットが完全に乖離してしまった。IE を言い訳に、最新仕様を勉強しないことへのインセンティブが強く残った。 - 2010 年代前半のモバイルアプリ需要で、若者の供給が一度途絶えて、人の入れ替わりがない時期があった。最近になって一部の Web 回帰、または Firebase や ReactNative 需要で多少盛り返した。 - 作りきりの Web 制作の文脈と、アーキテクチャのある Web アプリケーションの文脈が完全に別物になってしまい、合流しなかった。 --- ## IE (almost) Dies. - 世界シェア 3% 国内シェア 11.7% - Win7 の EOL (Win7 は Edge 非搭載) - EOL の Win7 への MS Edge の配信: Chrome Based Edge が入ってるんだから IE を使えと言えるように もはや toC では商用サポートされていないので、よほどの理由がない限り、IE を落とすことができるはず…とはいえ日本の 12%は気になるところだが… 実際には IE をサポートし続ける痛みが、現場のアーキテクチャの進化を強く阻害しているので、サポート切れを根拠になんとかして落としたい。 参考: - [Web ブラウザシェアランキング TOP10\(日本国内・世界\) \| ソフトウェアテスト・第三者検証ならウェブレッジ](https://webrage.jp/techblog/pc_browser_share/) - [新 Edge ブラウザ登場に伴う IE サポート終了についてチームのコンセンサスを得るためのシンプルなテンプレ \- Qiita](https://qiita.com/uupaa/items/ad1f0f64191dbec56889) --- ## Webpack Never Die. - Dependency Hell: Pure な ESM では、`import a from "./a.js"` と書くと、現行の仕様では、一旦サーバーからスクリプトを取得し、パースして、初めて、 `./a.js` の更に下の階層の依存が判明する。 - npm 時代のモジュールの依存は深い。とても深い。とてもではないが、深さ n(>5) のラウンドトリップに耐えうるものではない。元々の node.js 環境においては単にローカル FS の read でしかないので問題にならなかった。 - 依存を先に宣言しておいてストリームに投機的に次のデータを突っ込んでおく、という用途で期待されていた HTTP Server Push の仕様が死んでしまった https://blog.jxck.io/entries/2019-01-19/cache-digest-status.html - ESM と HTTP の話とは別に、ECMA 非標準な TypeScript の人気が増しているので、結局プリプロセッサは必要なわけで、だったら結局 Webpack 通すわけでビルドの手間は一緒じゃん、といったコミュニティの温度感がある。 一応、 https://github.com/WICG/import-maps や https://blog.jxck.io/entries/2019-11-12/webbundle.html でどうにかならないか、という試行錯誤はあるが… --- # 「フロントエンド」の領域の変化 --- ## 「フロントエンド」の領域の変化 フロントエンドは「UX のための差別化技術」から、「アプリケーション層のベストプラクティス」に。 参考: [SPA が、ウェブ開発のベストプラクティスになる時代](https://b.hatena.ne.jp/entry/s/mizchi.hatenablog.com/entry/2019/03/05/123617) --- ## 「アプリケーション層のベストプラクティス」 - next.js/nuxt.js への開発リソースの集中 (Google も支援) - 他者に配られる静的アセットから、「アセットパイプラインと連携して、それらのリンクを効率よく配る node サーバー」に昇格 - TypeScript の漸進的な型付けで,(比較的)堅牢なアーキテクチャに 重要なのこととして、 **next.js/nuxt.js 型のフロントエンドサーバーが、次世代の Rails になりつつある** --- ## next/nuxt では、なぜクラサバが同じ言語環境(node/v8)である必要があるか - (古くは)異なる言語で同じものを作っていた二重テンプレート問題 - 初期化が重い SPA の効率的な画面遷移には、 Server Side Rendering(SSR) の他に、サーバーを経由しない Client Side Routing(CSR) が必要 - => SPA じゃないとしても、アセット再取得が最小限になる CSR は、パフォーマンス上有効なことがわかった [App Shell モデル \| Web \| Google Developers](https://developers.google.com/web/fundamentals/architecture/app-shell?hl=ja) next.js の実体は webpack によるチャンク生成と node.js を緊密に連携させるように設計されたフレームワーク。 --- ## フロントエンドのアーキテクチャ上の分解点はどこになるか マイクロサービス上の、永続層を含まない、ユーザーと通信する **フロントエンドサーバー** - CDN First な設計: DC の外側にある CDN Edge とのコミュニケーション(主にインバリデーションの発行管理)という新たな領域の出現 - 永続層を含まない: Node.js は永続層周りのサポートが貧弱なので、外部に丸投げする。PaaS, DBaaS, No Code Backend  --- ## しかし人間は愚かなので 次代のスタートアップの MVP/個人 Web 制作はこうなる  - 静的アセット + PaaS の露出 (Firebase スタイル) - ほぼ JS だけで完結 - API として露出した部分の Firebase/Serverless の持つパーミッションがセキュリティ関心の中心に --- ## Next.js の出力モードから考える - 2つの出力モード - 静的モード: SSR なしで完全な静的アセットとして出力。 - 動的モード: セッションの状態を含んだ First View で出力可能。 - 現代の Google Bot の挙動 - クローラーが静的コンテンツをインデックス。その後、レンダリングキューに入る。 - n 時間後、レンダリングキューの順番が来ると、 Chrome でレンダリングされてインデックスされる。 **速報性が高く競合が多いニュースサイトは SSR が必須**。逆に言うとそれ以外では重要度が徐々に下がりつつある。 年々この n 時間は縮小傾向。 https://developers.google.com/search/docs/guides/javascript-seo-basics?hl=ja --- ## 余談: WASM で Next.js と同じアーキテクチャが可能か 状態管理の目線では、出力の冪等性のためにテンプレートが同じ言語のロジックで管理される必要があり(仮想 DOM、多重テンプレート問題等の需要)、Next.js / Nuxt.js は開発言語を node.js に制限してしまう。 ブラウザとサーバーで同じロクックで動けばいい、という点では WebAssembly で仮想 DOM アルゴリズム実装込みで出力できればよい。しかし、WASM の仕様に GC が含まれないのと、出力サイズの問題で、現実的に WASM Backend として選択可能な言語は、現実的には C/C++/Rust のみ。例えば Go を WASM 出力すると、GC のために Interpreter 一式がビルドされ、Hello World 程度でも 1.4MB になってしまう。 C/C++/Rust は(好みの問題ではあると思うが)、アプリケーション層のロジックを記述する言語としてデザインされておらず、Web 開発の現場で一般的になるのは想像し辛い。 WASM の GC が標準化され、かつそれが GC 付きの言語が現実的なサイズでビルドできるような仕様であり、かつ Rust の wasm-bindgen のような優秀な DOM API ブリッジが各言語で実装されれば、 Java, C#、Ruby,Python,Swift といった言語がウェブフロントエンドの選択肢になるかもしれない。ただ、そのエコシステムが整うのが 2020 年代前半に来るとは考えづらい。 - https://github.com/rustwasm/wasm-bindgen - https://github.com/WebAssembly/gc/blob/master/proposals/gc/Overview.md まとめると、 WASM が来るから JS 勉強しなくていい、みたいな時代は、まだ来る気配はないです。一旦諦めてください。 --- ## 実験: Blazor すでに WASM 経由の Isomorphism の実験例がある。Blazor は WebAssembry, iOS, Android の出力を持つ、MS 製の実験的なテンプレートエンジン (埋め込める言語は C#/F#)。 コード例 ```csharp