Remote.vue #1 に行ってきた #remote_vue

先日、Remote.vue #1 に参加しました。オンライン開催。簡単に所感をまとめます。

lapras.connpass.com

所感

アーキテクチャから API までいろいろ知見のある内容でした。特に、アーキテクチャではどういう判断基準があってその構成になったのかを聴けるのはとても参考になります。今回、初めて知ることもいろいろ...。Vue.config.errorHandler とか。

あと、SSR もまともにやったことがなくて、恥ずかしながら初めて hydration を知りました。ただ、こういうのをまったく知らずに引き出しもない状態だとハマったときに抜け出せなくなるので、知見として話を聴いておくことができてよかった。

最近、Vue をがっつり使った開発から少し離れてしまっているけど、ちゃんとキャッチアップしておかないと...。とりあえず、このあたりから調べようかと。

  • Vue 3 (Composition API, ...)
  • Nuxt.js
  • TypeScript

YouTube の URL はこちら。

https://youtu.be/rx249I9JmNUyoutu.be

以下、メモから抜粋。

超高速devサーバーvite

  • Native-ESM powered web dev build tool
  • 開発ビルドツール
    • dev: ネイティブ ES モジュールに最適化
    • prod: rollup を使ってビルド
  • vue-loader がサポートしているものはサポートしている
  • VuePress
    • サーバーの起動が遅い
    • ES モジュールの HMR
    • SFC を ES モジュールで動かしたい
    • ES モジュールに最適化されたバンドラがない
  • Snowpack
  • サーバーの起動が速い
  • オンデマンドコンパイル
  • HMR (他のバンドラより速い)
  • 開発モードのときはバンドルしない?
  • esbuild
    • 他のバンドラより速い
  • HTTP リクエストごとにコンパイル
  • HMR は画面単位で動く
  • キャッシュ
    • 変更がないものは304で返す
    • Service Worker
      • サーバー側のキャッシュを破棄するのに Service Worker を使ってたり
  • Koa
    • Express より高速な HTTP サーバー
  • プラグインアーキテクチャ
  • Module Rewrite Server Plugin
    • 相対パスから絶対パスに書き替える
    • import のパスに timestamp が付く
    • import しているモジュールのsグラフを持っている
  • HTML Rewrite Server Plugin
  • Vue Server Plugin
  • HMR Server Plugin
    • サーバー側の変更が WebSocket を経由して通知される
    • dynamic import で変更されたモジュールをダウンロード
    • HMR グラフを解析
    • 木構造を遡って対象を探す
    • HMR 対象のファイルが見つからない場合は index.html をリロード
  • VitePress?React?Preact?

ぼくのかんがえたさいきょうのVueあーきてくちゃ

  • ディレクションの知識
  • コンポーネント150個&API100個以上の規模の事例
  • フロントの責務 > 遷移と参照☆
    • Vue Router
    • 一覧の処理 ⇒ ロジックとして共通化する
    • 詳細 ⇒ 愚直に作り込む (共通化の余地がない?)
  • フロントの責務 > 権限と操作☆
    • 権限は参照/操作における DOM 表示とAPIリクエストに関わる
    • バリデーションも権限のひとつと言える?
  • 見通しのよい構成☆
    • SetupContext (this が持っているコンテキスト?)
      • これに依存する処理は切り出す
  • ディレクトリ構成☆
  • enums
    • 定数が扱えるなら enum でも union でもいい
    • namespace をオーバーライドしてメソッドを生やせる☆
    • 文字列で扱えばデシリアライズしなくても比較できる
  • models (BaseModel)
    • APIクライアント
    • Vuex の store の action に API リクエストを入れない
    • BaseModel は基本的な CRUD のメソッド
    • レスポンスはデシリアライズを通す
    • extend したクラスでは CRUD は書かない
  • modules
  • mixins
    • SetupContext を利用した処理
    • Composition API の SetupContext を切り出したロジック
    • ビジネスロジックに近いけど SetupContext がないと処理しづらいもの
    • emit, $router, $store はここで呼ぶ
    • 一覧系の共通ロジックを入れたり
  • views のコンポーネントは画面と1対1に
  • 汎用的なコンポーネントは components に
  • ドメインビジネスロジックを持つコンポーネントは templates に
  • Vuex に API クライアントの責務は持たせない
    • 画面共通リソースとの store, およびその永続化に留める☆
    • ログインユーザー情報, 権限, など
  • moment.js のロケールファイルを除去してファイルサイズ縮小
    • day.js がよさそう?
  • v-bind.sync☆
  • 部分型☆

Vue.observable で状態を管理する

  • Nuxt.js + TypeScript
  • ページをまたいでグローバルな状態を管理したい
  • Vuex (モジュールモード)
    • ディレクトリ構成に対応するプロパティが動的に生える
    • TypeScript と相性がわるい
  • Vue.observable☆
    • Vue 2.6+
    • js のオブジェクトをリアクティブにできる
    • Vue の data 関数の仕組みも同様
    • Composition API の reactive 関数とほぼ同じ?
  • Vue.config.errorHandler☆
    • 例外発生時に登録した関数が呼ばれる
  • エラー状態を Vue.observable で定義
  • Vue.config.errorHandler の関数でエラー状態を変更する
  • SSR の場合、Vue.observable だけでは hydration できない?☆
  • Vue.observable は状態を変更する口が少なくなる
    • 見通しがよくなる

NuxtでSSRしている時でもGoogle Optimize(ABテスト)を動かしたい

  • Google Optimize
    • A/Bテスト, GUIでテストの設定ができる
    • GAなどの連携
  • Nuxt で SSR しているサイトで Optimize を使いたい
  • hydration☆
    • 場合によっては DOM を破棄して再構築する
  • hydration が終わってからテストを起動/実行する
    • app.mounted (Vue)
    • window.onNuxtReady (Nuxt) ※ドキュメントに書いてない...
  • vue-server-renderer

終わりゆく Vue 2.x 時代の状態設計の答えと Vue 3 の Provider への期待

  • Inject を軸に構成する
    • Vuex への依存は抑える
    • HTTP 通信など SPA 外部への依存は Inject を通して DI 的に実装する
  • モーダルのフラグ > portal-vue, Teleport (Vue3)
    • 仮想 DOM 上の親子ツリーとは別のところに状態をマウントできる?
  • Vuex を使わないだけライフサイクルフックに乗れる☆
  • ストア使いたいけど Vuex じゃなくてもいい
  • Inject☆
    • Nuxt.js の Plugin に同梱されるオブジェクト注入の機能
    • アプリケーションの this に生える依存を DI できる
    • vue-test-utils でモック化しやすい
    • TypeScript の型定義を追加する余地がある
  • 必要最小限の API と依存で状態が管理できる
  • inject 関数の第2引数に入れているもの以外は外に露出しない
  • Recoil
  • Vuex の型定義 (Vuex.Store<any>)
    • 次期バージョンから改善される
  • vue-test-utils と相性がよい
    • this に依存が生えるので mocks が使える
  • Inject は粒度が小さいものになるので取り回しやすい☆
  • Vuex を HTTP リクエストのキャッシュに使わない
    • HTTP キャッシュ or Inject でオンメモリ
  • Prototype 拡張や provide / inject は Vue 2.x 自体にある
    • provide / inject は Vue 3 でより扱いやすくなる
    • Composition API と合わせて使う
    • React のカスタムフックみたいな
  • Vue.observable + Inject で Composition API に近い書き方になる☆
  • inject の粒度を考えて使わないと $ が煩雑になりそう
  • スコープを狭めることを自分で考える☆
    • Vuex では仕組みとして提供されている部分?
    • state を直接いじらないとか mutation を通すとか...