VueFes Japan 2023イベントレポート

10月28日に開催された「VueFes Japan 2023」のイベントレポートをダイジェストでお届けします。

なお、公式サイトのタイムテーブル内に、一部の講演の資料がアップロードされています。

オープニング

実行委員長・ユーザーグループ代表の川口和也氏から、挨拶がありました。

今回は4トラックでスピーカーは35名、コアチームの来日など充実した内容になっています。またオフラインでの開催は5年ぶりです(台風やコロナの影響で、2018年以来です⁠⁠。

川口氏は、フェイス・トゥ・フェイスで開催できる嬉しさやスポンサーへの感謝を述べました。

川口氏の挨拶

Evan You氏によるキーノート

基調講演はVue.jsの作者であるEvan You氏。広い会場で立ち見もでるほどの盛況でした。Evan You氏は、台風やコロナで日本に来れなかったため、久々の来日とのことです。

Evan You氏はVue.jsとVite、2つの人気OSSの作者であり、今回はVueとViteのアップデートについて話しました。

Evan You氏の発表

この数年間にVueに何が起こったか

この数年間でVueに起こったのは、Vue2→Vue3への進化です。この進化の中で、失敗と良かった点があります。

失敗(mistake)したこと

多くの⁠ちょっとしたブレイキングチェンジ

バージョンアップに伴う分離(isolation)は管理できると思いましたが、⁠多くのちょっとした変更が入ったことで結果として)大きなものになりました。教訓として一度にすべてを壊さないことです。⁠既存APIのdeprecated(非推奨化)とオプトイン(新しいAPIのオプトイン⁠⁠→その後既存APIの削除」のサイクルがあるべきでした。

また、リリース間隔が広がってしまい、分散を招きました。

エコシステムライブラリへのインパクトを見誤っていた

Vue 3の登場に伴って、アプリはともかく、ライブラリは追従が大変でした。エコシステムはフレームワークがうまくいくためのポイントです。

なお現在はEcosystem-CIを導入して、リリースの前にエコシステムのテストを行っています。あわせて、ユーザーに内部APIを使わないよう推奨してきました。これによって、エコシステムへの影響を削減できています。

すべて一緒にはリリースしなかった

Vue 3のコア部分のリリース時は他の多くのライブラリはWIPでした。Vue 3をユーザーが試してみるために必要なことだと思いましたが、これによって混乱が生じました。

新しいユーザーがVue 3は不完全だと思ってしまったことは、長期的なダメージにつながりました。大きなアップグレードは印象が大事であり、もっと完成度高めてから出せば良かったです。

うまくいったこと

TypeScript

TypeScriptの導入は大切でした。型検査はtable stakes(当たり前のもの)です。導入することで、変更しやすい、型宣言がエンドユーザーのためにしやすくなります。また、TypeScriptを適用することは大規模なチームには必須です。メンテナンス性を上げ、イテレーション(反復的な開発)の確固とした基礎になりました。

Composition API

Composition APIの導入は議論がありました。Reactっぽいなと思った人もいたでしょう。時間が経って、多くのユーザーは便利さに気づきました。ロジックの利用やリファクタリングに重要であり、大規模利用には欠かせません。

Composition APIを導入したのは、ユーザーの取り組む対象が小規模からより大規模なアプリに移って、解決すべき領域が変わったからです。

またComposition APIがあるからこそ、VueUse(Composition APIのユーティリティ集)のような強力なコミュニティのサポートがあります。多くの貢献者もいます。これは良い決断でした。

DX(開発者体験)への投資

フレームワークの外で、次の改善も入れました。これも重要です。

  • Viteの開発と導入
  • ドキュメントの改善
    • 構成を流れを保ったまま大きく改善、80%以上を書き換えました。
  • Volar(LSP)によってIDEサポートが大きく向上
    • Johnsonのおかげです。
    • VSCodeだけでなくWebStormなどの開発体験も改善しました。

Vueの現在のとこれから

Vue 3はよりよく成長しています。広がるのに思ったより時間はかかりましたが……成長しています。拡張性、パフォーマンスにも優秀です。また多くのUIライブラリもあります。

そして、これから先は安定性が鍵であり、Vue 2→3のような破壊的変更は避け、制御可能な小さな変更が中心となります。

  • シームレスリーに適用可能な改善に注目
    • Reactivity system/parserの最適化
    • Vapor mode(Solidに影響を受けた機能)のopt-inでの導入

各バージョンでは、次のように計画しています。

3.3以降の変更点

直近はViteの開発に注力していたため、あまり変更点は多くないです。委譲とコラボレーションをキーワードに開発を進めています。

P4レベルのIssueの90%を3.3.7で解決していて、さらなる修正もすぐに入るでしょう。

3.4 alpha

Reactivity systemの改善。変更点は次のものです。

  • 正確で効率的な再計算(re-compute)
  • スケジューリングやArray mutationの効率化
  • メモリ管理の最適化

Ecosystem-CIは通ったものの大きなリファクタなので、ぜひ皆さんにもテストしてほしいです。

3.4での計画

次のことを計画しています。それ以外にも、いくつかマイナーな機能を考えています。

  • deprecatedなReactivity transformの削除
  • 型の改善、修正
  • define model stailization
3.5での計画

SSR関連の改善、Suspense Lazy Hydroationなどを予定しています。

Vapor modeの状況

Solidに影響を受けた新しいコンパイルのモードである「Vapor mode」は現在まだ研究開発段階です。⁠当初想定より開発は)遅れています。残念ながら2024年の第一、第二四半期までは出てくることはないでしょう。

エコシステムと発展したVite

Viteはフロントエンドのビルドなどを行うツールで、高速さなどから人気を集めています。実際に6万以上のGitHub Stars、週間720万超のダウンロードがあります。そして現在も成長を続けています。

Viteは、Vueのためだけではないエコシステムへと発展していて、Webエコシステムにおけるイノベーションのための基礎的なピースになっています。そしてViteによって何度も同じものを作り直さず、重要なところにだけ集中できるのです。

また、Viteの哲学には「無駄がなく拡張可能なコア」⁠実践的なパフォーマンスアプローチをとる」というものがあります。

Viteの課題と⁠Rolldownの採用

今後のViteでは次の課題を解決していきます。

  • (本番における)ビルドスピードの改善
  • 開発・本番間の一貫性不足の解消
  • ネットワークオーバーヘッドの解消(unbundled ESM⁠
    • パッケージひとつひとつにリクエストを送ってしまうため遅い
  • SSRの外部的な問題
  • chunk splittingの問題

Viteはesbuild/Rollup(いずれもJavaScriptのビルドツール)に依存していますが、これらのツールは集中する方向性が違います。

そこでRollupのRust版、Rolldownの開発と採用(ViteのRolldownベースへの移行)を考えています。パフォーマンスとベストエフォートでの互換性の両立が目的であり、エンドユーザーへの影響を最小限にして、Viteの内部でこれをデフォルトに移行します。

Rolldownは現状のステータスとしては初期WIPです。Rspackで経験のある人がコントリビューターに入ってくれて、ツールや機能についてRspackチームともコラボレーションしています。OXC(Oxidation Compiler、高いパフォーマンスのJavaScript/TypeScript向けツール集)の上に構築します。

現在、RollupメンテナーのLukasと、Rollupの動作との調整についてコラボレーションしています。

Rolldown採用のロードマップについては次のようになります。

  1. 基本的なビルディング:esbuildの依存のプレバンドルを解消
  2. 発展的なビルディング:Rollupを使わなくていいようにする
    • プラグイン互換性
    • tree-shaking
  3. ビルトイントランスフォーム
    • TypeScript
    • jsx
    • minification(最小化)
    • syntax rewriting
  4. ViteのRust化
    • 一部をラスト化する現実的なアプローチ
    • 全部書くわけではなく、Rolldownから書き直す
    • 全部Rustにするわけではなく重要な部分のみRust化、少しずつ取り込んでいく。パフォーマンスに重要、安定的な部分などを重視
    • 速度は重要。部分的なRustの採用で最適化できる
    • unbundled ESMの代替としてのフルバンドルモード、数多いパッケージにはunbundledより有利

「走りながらエンジンを交換する〜大規模プロダクトを成長させつつVue 3にするには〜」

この発表では、弁護士ドットコムの篠田貴大氏が大規模なプロダクトを成長させながらVue 3に移行する方法を解説しました。篠田氏は、弁護士ドットコムが提供する電子契約サービス、クラウドサインでフロントエンドを担当しています。

発表冒頭、利用しているVueのバージョンを参加者に確認するとVue 2.6以下が少し、Vue 2.7が2割、Vue 3が3割、その他が2割ぐらいでした。

クラウドサインのVueバージョン

Vue 2系は2023年年末にEOLであり、Vue 3ではcomposition API、<script setup>、TypeScript親和性向上など魅力的な機能が多いです。

しかしクラウドサインにおけるVueは現在Vue 2.7で、今Vue 3に移行中です。これには、プロダクト成長とVue 3アップデートの対立構造がありました。

Biz
  • 成長市場でプロダクトの価値を高めるため、新規機能追加が求められる
Dev
  • 使用しているライブラリが(3系から見て)古い、マイグレーションガイド以外にもやることがたくさんある状況
  • Vue 3にするには@vue/composition-apiをはがす必要がある
  • v-modelやEvents APIの破壊的変更への対応
篠田氏の発表

Vue 3へ移行するためにしたこと

このような状況下で、プラットフォームチームをつくり、小さく始めました。プラットフォームチームはトリアージコードの修正やnpmコマンド修正など足回り改善し、他のチームは顧客への価値提供をします。

Vue 2.7を経由してVue 3へ。Vueのアップデートは、影響範囲の限定的な社内用管理画面からはじめ、変更箇所を極小に進めていきます。小さく始めて知見を得ていきます。

一括でvue/composition-apiをはがしたいですが、数百ファイルへのビッグバンリリースは避けたいです。そこで、プラットフォームチームで変更を最小化するモジュールを作成し、差分を吸収するようにしました。既存のファイルは新しく作成したモジュールを向くようにビルドを調整します。

また、2.7にないcreateAppnew Vueを使った実装に差し替え、mountの定義を変更しました。

これらの工夫で、一括で置換すると900ファイルあった変更点が5ファイルになりました。

これにより、他のチームがVueのアップデート状況を気にせずに並行して新規開発できました。かなりスピーディーにアップデートできました。

現在は2系、3系で並行ビルド中です。@vue/compatの導入、コンパイル時エラーの調査や対応を進めています。なお、Eventes APIの廃止は公式でも紹介されているmittに移行します。

「社内UIコンポーネントライブラリがエンジニアチームにもたらした本当の価値」

この発表では、ユニークビジョンの山本一将氏がUIコンポーネントライブラリの開発とエンジニアチームにもたらした変化を話しました。

ユニークビジョンはSNSマーケティングの企業で、X(Twitter)キャンペーンなどができるBelugaを提供しています。山本氏の業務はRustがメインですが、今回、UI/UXの統一、開発効率向上を目的に起こった社内UIコンポーネントライブラリ開発をおこない、フロントエンドのレベルアップにつながったそうです。

Vueの導入と⁠その後出てきた課題

2018年頃、一つのプロダクトのキャンペーン設定において入稿後のシステム設定が非常に複雑だったこと、また事業をスケールするためにユーザー側でシステムへ直接設定することが必要になったことがあり、UI/UXの向上が必要となりました。

そこでVue.jsを導入し、多くの場面でVue.jsを利用するようになりました。

山本氏の発表

フィーチャーチームでまわしていましたが、エンジニアの役割はそこまではっきりわかれていません。各チームにバラバラにフロントエンドに強いエンジニアがいるような状態でした(社内全体の割合としてはフロントエンドに強いエンジニアはあまりいませんでした⁠⁠。

こういった事情もあり、次のような問題が生じていました。

  • (チーム間・サービス間で)統一されていないデザイン
  • 使いづらいコンポーネント
    • 機能的にも未統一
  • フロントエンドの開発が長時間化
    • 毎回似たようなコンポーネントをつくっているから時間がかかる

UIコンポーネントライブラリ開発による思わぬ成果

そこで、チーム横断で社内のフロントエンドの精鋭が集まり(横軸のチームとして⁠⁠、社内UIコンポーネントライブラリ「Beluga UI」を開発しました。これにより、妥協のない高品質なものになりました。

  • Vueコンポーネントライブラリ、Vue 2/Vue 3対応
  • 24種の基本コンポーネント
  • Tailwind CSSのカスタムテーマで基本色を定義

また、Beluga UIを開発したことで、思わぬ成果が現れました。

  • Beluga UIはスタイルガイドに従った品質の高い実装、可読性も優れる
    • リファレンスとして困ったときに参照される
  • Storybookによるドキュメンテーションの導入
    • コードレビューのプロセスが進化
      • Storybookの差分が確認したくChromaticを導入
      • ツール導入で横軸のチームが活躍

チーム横断で、新しいことをBeluga UIの開発で試すことで、理想の書き方、StorybookやChromaticを導入できました。それを元チームに展開することでフロントエンドの技術力が全社的に上がりました。

コンポーネントチーム(チームを超えた、横軸のチーム)は全社の改善につながりました。

「価値を生む技術提案」

この発表では、リンクアンドモチベーションの鵜木義秀氏が、事前の発表予定タイトルをあらため「価値を生む技術提案」について話しました。鵜木氏はフロントエンド開発、UIライブラリ開発などを担っているフロントエンドエンジニアです。

リンクアンドモチベーションは組織コンサルティングの企業です。提供するサービスのモチベーションクラウドは幅広く利用されていますが、古くなってきた部分もありリライトすることにしたそうです。発案・提案→設計・実装→導入・評価に一年かけたことを挙げ、この中で発案・提案が大変だったと言います。今回、大規模なソフトウェア開発では提案の質が重要になってくることを説明しました。

提案

erb→Vue.jsにリプレイスしたいと提案しました。マネージャーレベルではいいねと言って取り上げてくれるのですが、最初はそこから大きくは進みませんでした。

  • 現状:Vue.jsとerbが混在
  • 理想:Vue.jsだけ

理想にもっていくには課題がありました。エンジニアの工数を確保する必要がありますが、そこに工数を割く理由の解像度が低くかったのです。

本来は現状・理想・課題を把握、分析して関係者に提案すべきでした。具体的には次のことを準備して提案すべきだったのです。

  • 現状
  • 理想
  • 課題とその優先度
  • 課題に対する解決策
  • 体制
  • スケジュール
  • 投資対効果

実際には、揃いきってない状態で改めて提案して、進められることになりました。

技術決定

実際の技術決定は、次の流れで進みます。

  1. 要件確認・制約条件確認
  2. 技術調査・比較
  3. 検証

事前のフェーズで課題とその優先度、投資対効果をまとめられなかったため、要件確認で大きな困難に直面しました。理想だけはあったため現状から大きく飛躍して、一気に変更しようとしてしまいました。TypeScript化やReact化のようなライブラリそのものの変更なども思いついている程度でした。

こういう状況だったので意思決定は難しかったです。また影響範囲を限定できないため、多くの開発者が改善に参加できない自体に陥りました。

そこで、課題とその優先度を設定し、完全ではないものの投資対効果も設定しました。実際の新アーキテクチャとしての大きな変更はTypeScriptの導入のみで進めることに変更しました。

検証でも問題が発生します。新アーキテクチャをあまり使ってもらえませんでした。旧アーキテクチャは生産性が低いが不確実性も低い、新アーキテクチャは生産性が高いかもしれないが不確実性が高いというかたちになっていました。問題と理想、問題解決について共有すべきでしたが、それができませんでした。⁠なぜ新アーキテクチャを使うべきかという)Whyがありませんでした。

そこで、キャッチアップ用のドキュメンテーションを改修しました。社内向けに、Vue.js Tutorialのようなユーザーが試せるドキュメントも用意しました。OSSではこういったドキュメントの整備はよくありますが、社内向けのものでも使ってもらうにはこのような工夫は重要です。

成果

定量面ではリードタイムの改善、自動テスト、UIライブラリの開発といった成果が出ました。定性面でも改善が見られました。

提案の質がソフトウェア改善において成功要因となります。

「Vue 2のEOLまで2ヶ月ですが進捗どうですか?」

この発表では、メドピアの小林和弘氏が、差し迫ってきたVue 2のEOLと、Vue 3へのアップデートについて話しました。

メドピアは医師向けのコミュニティサイトを基盤に様々な事業を展開しています。新しい言語やツールを積極的に採用し、VueやNuxt、部分的にViteを採用しています。輪読会やモブプロなども開催。VueFesはじめ、多くの技術カンファレンスでスポンサーもつとめています。

年末でEOLを迎えるVue 2

Vueの各バージョンの利用率について、会場に質問するとVue 2プロジェクトを使っている人はまだまだ多い状況でした。

Vue 2のEOLは2023年12月31日。NPMやCDNでは引き続き配信されるものの、アップデートが行われません。HeroDevsでVue2の有償サポートが行われますが、価格は非公開です。

Vue 2.7なら、<script setup>やcompositon apiがあるので、⁠ある意味で)技術的にはある程度問題ありません。ただセキュリティパッチがなく、社会的な規制や会社のポリシーに抵触する可能性もあります。したがって、使い続ける選択肢はほぼありません。

Vue 3へアップデート

自社の各サービスでのマイグレーションへの取り組みは次のような状況です。

MedPeerはRails view上にVueを載せるMPAであり、Vue-routeやVuexは未使用です。Vue 2の影響範囲を少なくしながら改善していきました。

  • eslintでVue 3向けのエラーを解消vue/vue3-recommendedを利用⁠
    • 新規ファイルの作成時にVue 3対応になるように
    • 一時的にTODOファイルを生成してそれを利用
      • エラーを解消してマイグレーションを進める
  • eslintのカスタムルールでVue 2記述をより排除できるように
    • template内のv-modelを防ぐなど種々のルールを定義
  • Vue 3のcreateAppのwrapperを作成

ヤクメドは部分的に進め、Vue 2とVue 3を共存させました。このスタイルは開発を止めずに開発を進めるのに有効かもしれません。

  • Vue2/Vue3を共存させて徐々に移行
  • package.jsonのエイリアスでVue3を個別に管理
  • Rails Viewにも紐づくエントリーポイントごとにVue3対応
  • Vue3のテストはモノレポ環境にvitest(モノレポ実現にworkspacesを利用)
小林氏の発表

TonoelはRails API/Nuxt SPAの構成で、2つのリポジトリで2つのNuxtを管理しています。マイグレーションブランチを使って解決しました。

  • Vuex 3→pinia化
    • この部分は地道にやるしかない
    • ユニットテストによる確実な移行が有効
  • Nuxt3のmigrationブランチ(移行ブランチ)を作成
    • migrationブランチを作成し、ガイドに沿って変更に対応。
    • テストケースで見つかった細かい考慮漏れを対応。

やくばとは、Rails API/Nuxt SPAの構成で、Nuxt bridge後(に開発開始)のサービスでpiniaやcompositon apiを初期から利用しています。ここでは気合で一気に進めることで、解決しました。

  • 開発の合間に一気にNuxt 3化
  • 非対応モジュールは自前で書き直す
  • 壊れているところを手分けして直す
    • warning/error log対応
    • テスト
    • storybook vue対応

「Nuxt to the edge.」

この発表では、NuxtLabs CEOのSebastien Chopin氏がNuxtのEdgeでの展開を解説しました。

現在のNuxt

Nuxt.jsはFull stack web application with Vueです。ECサイトはじめ5万以上のプロジェクトに採用されています。

Nuxt 3は公開から11ヶ月でnpmで100万ダウンロードを達成。現在のダウンロード数ベースで3系が2系を上回りました(Nuxt 2のEOLは2024年6月の予定です⁠⁠。また11ヶ月で2,730のIssuesのうち80%クローズし、1,850のプルリクエストのうち98%が解決済みです。

Nuxtは画像最適化も導入しています。コンテンツ作成を簡単にするNuxt Contentもあり、Dev Toolsもあります。UIライブライもリリースしていて、160のモジュールがコミュニティによってつくられています。

Nuxtにベンダーロックインはもうありません。どこへでもデプロイできます。

Nuxt 3はハイブリッドレンダリングが可能です(ビルド時に解決⁠⁠。nuxt.config.ts(routeRules)で簡単に設定、利用できます。ルートはオンデマンドに生成可能です。最近はルートルールをページ側で定義できるようになり、より汎用性が高まっています。ロジックもページレベルでキープできます。

Edgeとunenv

EdgeはCloudflare workersが生み出したものです。機能的に限定されたJavaScriptをEdgeのサーバーで動作させることができます。

Edgeのメリットとしては、レンダーが速い、ホストが安い、エンドユーザーから見て数ミリ秒で動く、0msコールドスタート、サーバーメンテナンス不要、オートスケーリングといった点があります。

プロバイダーは多数あります。Cloudflare、Deno Deploy、Lagon.app、Vercel、Edge function、netlify edge functionなどです。

これらのEdge runtimeには限界があります。Nodeやブラウザーとは違います。Windowオブジェクトなどは使えないし、スクリプトのサイズはトータル5MBまでといった制限があります。

Nuxt.jsではnode/browserとの互換性のために、プラットフォーム依存のないJavaScriptを生成するunenvを開発・導入して解決しました。プラットフォーム非依存のWebサーバーNitroも活用しています。

Sebastien Chopin氏の発表

Nuxtプロジェクトのデモ

現在ではデータベースもEdgeに来ています。あわせてNuxtのデモをおこないました。

簡単なサイトを作成し、nuxt buildを走らせます。outputのディレクトリに生成され、これはnodeからでも起動可能です。また、生成したプロジェクトのサイズはミニマルに保たれています。NitroによってNuxtをEdgeにできるようになり、wranglerでデプロイできます。

地域ごとにパフォーマンスを確認すると(Key CDNを利用⁠⁠、Edgeを利用することでどこからも高速にアクセスできることが確認できました。Edgeを使えば1ヶ月1$未満で世界中に展開できるのです。

Nuxtの持続性

Nuxtにはスポンサーが多くいます。1人がフルタイムで働いているが大丈夫そうです。Backerの皆さんはありがとうございます。

NuxtLabsはソリューションの営業も行っています。またNuxt Contentのプロバージョン(有料版⁠⁠、Nuxt Studioもあります。また、Nuxt UI(Nuxtの公式UIライブラリ)について、有料版のui.nuxt.com/proも準備しています。

「A new Nuxt.」

この発表では、Nuxt teamのコアメンバー、Daniel Roe氏が新しいNuxtについて話しました。

発表冒頭、Daniel氏自身についてイングランドで家族と3匹の猫と暮らしていること、roe.devというサイトのほか、各種SNSどこからでも、遠慮なく連絡してほしいと述べていました。

Nuxt 3への道のり

3年ぐらい前からコアチームに参加し、Nuxt 3の改修に参加しました。Sebastienだけだったメンバーも徐々に増えていきました。

NuxtはVue上のフレームワークですが、サーバーレスや多様なアーキテクチャに対応してきました。まだ道半ばな部分もありますが、新しく書き直すことにも取り組んできました。Viteへの移行や、Nitroへの移行、ほかにもいろいろなことをおこないました。

この改修はやらないこと、やるべきことを学んできた大きな旅でした。

スコープと時間
両方を満足させることはできません。野心的なプロジェクトは時間がかかります。締切を守りたいならインクリメントに改善していくしかありません。
エコシステムの重要性
NuxtをNuxtたらしめるのはエコシステムです。多くの人がモジュールをつくってくれます。Nuxt 3は大きな変更があり、これらのメンテナンスに課題がありました。内部への依存をNuxt 3ではよりシームレスに解決できるようにしたいと考えています。
人の貢献が大切
車を動かしながら、さらにそれを修理するのは大変ですよね。今回のような大規模な変更には人がついてくるのが大変でした。繰り返さないようにしたいと考えています。

Nuxt bridge

Nuxt 3への移行のプロセスのためにNuxt bridgeに注力してきました。2→3への移行を助けるツールです(2系のEOLは2024年6月末です⁠⁠。前方互換性を維持し、options-apiの変換、Webpack→Vite化などができます。

この開発ではRyota Watanabe(wattanx)が活躍してくれました。

※著者注:このときNuxt 3を使っているかを会場に問いかけたところ、半分程度の人が利用していました。

Nuxtの改善に当たって

重視したのは高速に動作し、新機能を追加しながら、安定性を失わないことです。

開発では次のことに取り組みました。

  • Ecosystem-CIの導入
  • リリーススケジュールの新設定
    • 特定の期間ごとにリリースするようインクリメンタルに進めるようにした。
  • きちんと動作することを確認する

バランスを維持しながら、同時にイノベーションを起こします。

View Transitons APIを2週間で取り込み、zero-js/zero-vueモードの導入にも取り組んでいます(著者注:zero-vueについては説明がありませんでした⁠⁠。inlineRouteRules、server componentsなど多くを利用できるようにしました。

Ecosystem-CIとのコラボレーション、feedback+testingのinvitation、future/featuresのネームスペースを導入し、今後の動きや実験的なものを配置できるようにもしました。

また、nuxt/telemetryをopt-inで導入し、利用情報やusage statsなどを早期に獲得可能にしました。

リリースしたばかりのNuxt v3.8にも多くの改善があります。

  • CLIでのモジュール追加サポート
  • ビルトインのNuxt DevTools
  • App Manifestサポート
  • Data Fetchingの改善(caching)

例えば次のようなものです。

最小の哲学
Nuxtを可能な限り最小限にし、新しいものをコンポーザブルに使えるようにします。皆さんのやりたいことの粒度に合わせて、導入や利用に摩擦がないように。コンポーネントをよりインタラクティブにできるようにします。
DXフォーカス
Nuxtは開発ツールに集中しています。CLI/DevToolsなど。開発中にfriction(摩擦)がなくせるように安定的にうまく使えるようにしています。
@nuxt/test-utils
プロダクションに使えるよう、first-clas-testing story for Nuxtとして開発されています。vitestチームとも協業しています。
Nuxt Content
Nuxt ContentはCMSアプリです。いいものができています。MDC(Markdown Components)サポートも実装しています。
Nuxt Image
Nuxt Imageはイメージを最適化します。23のプロバイダーと連携でき、ソースセットにマッチしたものが使えます。最近v1.0.0もリリースされました。
UIライブラリの爆発
Nuxtで使えるUIライブラリはかなり増えてきています。いろいろ選択肢があるのはいいことです。
Daniel Roe氏の発表

ベストプラクティスをビルトインにする

config-zeroでup and running(活発に動くよう)にしたいと考えています。そのために、いろいろなものの開発を進めています(筆者注:開発中のものが多くロードマップ紹介のようです⁠⁠。

  • Accessibility
    • out of boxでAccessibilityのヒントを与えます。
  • Auth
    • 導入すると、認証の基礎的な機能が利用でき、またAuthの上に独自のものを組み込みやすくなります。
    • すでにAuth相当のことを実現するための機能はNuxtにありますが、コアモジュールとして取り込むことでより課題に取り組みやすくなります。
  • Assets and Scripts
    • Harlanが作成してくれました。Chrome Auroraチームと協力していて、導入でアプリケーションのパフォーマンス向上が期待できます。
  • Fonts
    • ゼロコンフィグでフォント設定ができるようになります。

コミュニティとNuxt 4への道のり

コミュニティは歓迎的です。自身がNuxtの開発に参加したときも、コミュニティが暖かく迎え入れてくれました。

コミュニティとして、新しいWebサイトAre you a Nuxter?を作りました。DiscordやGitHubでもコミュニケーションできます。Nuxtへの貢献方法に触れた記事も読んでみてください。

Nuxt 4への道のりですが、大きな変更はしません。通常の変更を、頻繁にします。みなさんのプロジェクトが(いい意味で)Nuxtに依存できるようにします。

Nuxtそのものがblazing fastに動くということをぜひ体験してほしいです!

「Vue Language Serverから生まれたVolar.jsとその可能性」

この発表では、mizdra氏がVue Language Serverから誕生したVolar.jsについて解説しました。

mizdra氏は、はてな所属で、Webアプリケーションエンジニア、フロントエンドエキスパート。Vue.jsの経験は趣味で1年くらいありますが、それも5年ほど前という話です。

エディタの言語機能とLSP

エディタの言語機能とは、コーディングを補助するエディタの機能、補完定義元への移動、Symbols(アウトライン表示)などです。

近年は言語機能はLSP(Language Server Protocol)に則った方法で実装するのが主流です。LSPは2016年にMicrosoftが発表した、エディタに言語機能を載せるためのプロトコルです。

つまり、エディタとは別にLanguage Serverがあり、これが言語機能を実装し、エディタはLanguage Serverを介してユーザーに言語機能を与えます。LSPはエディタとLanguage Server間の通信の仕様(Protocol)を定めたものになります。

これにさえ従っていれば動くので、例えばJavaScriptのLanguage ServerはVSCode/Vim/emacsで動きます。LSP対応エディタはどのLanguage Serverも使えます。

mizdra氏の発表

VueにおけるVolar

.vueは(HTMLともJavaScriptとも違う)独自のファイル形式です。このため、Vueには独自のLanguage Serverが必要で、VueではVolar、Vue Language Featuresが使われています。古くはVueのためにVeturというLanguage Serverもありました(筆者注:現在ではVolar/Vue Language Featuresが主流。Veturは2023年末にEOL⁠。

VueのLanguage Server実装は特殊です。<template><script><style>のタグはそれぞれHTML、JavaScript、CSSが書けます。すると3言語分の言語機能提供が必要になります。.html/.astro/.svelteにも似たようなニーズがありますね(.astroはAstro、.svelteはSvelteの独自ファイル形式⁠⁠。

こういったある言語の中に組み込まれている言語をembedded (programming) languageと呼びます。日本語では、組み込み言語と呼ぶことにします。

実は、組み込み言語についてもVSCode公式サイトでLanguage Serverの作り方が解説されています。2つの実装アプローチを紹介していて、VueはLanguage Servicesという次のようなアプローチを採用しています。

  1. ファイルを組み込み言語ごとのブロックに分け、仮想ファイルとして処理
  2. 仮想ファイルを各言語向けのServiceで処理
    • ServiceはLanguage Serverのコアを抽出したライブラリの俗称。言語機能のロジックのみ提供でLSPは喋らない(処理しない⁠⁠。vscode-html-languageserviceなど。

これでVue Language featuresをつくれるのか —⁠— .vueの深淵

Language Servicesを使えば簡単に全部解決するかというと、難しいポイントがいくつかあります。

.vueはtemplate内にJavaScriptの式が書けます。これもServiceで処理しなくてはいけません。template内では処理できる変数が限られているため、それをコード補完の候補に出してほしいところです。ただし、定義元はscript、つまり別の仮想ファイルなのでデータ共有が必要になります。ここは実装の難易度が高いです。他にも色々と難しい部分はあります。

それでも、コミュニティの努力で、年々補完や自動挿入・型チェックが進化してきました。

Veturとは別実装のVue Language Featuresが2020年に(開発版)リリース、2023年2月に正式リリースされました。このコアはVolar.jsとしてOSSに切り出されます。

Vue以外の領域でも貢献するVolar.js

Volar.jsは組み込み言語のツールを作るためのフレームワークです。少ないコードで高機能・高品質のLanguage Serverが作れます。

組み込み言語共通の課題があることを、開発者はVeturで体験しました。この問題があるのはAstroやSvelteでも同様でしょう。Vueはこの問題を解決できましたが、他もできるわけではありません。

そこで、Volar.jsはその領域の問題の解決を手助けし、面倒な作業を肩代わりします。これによってフレームワーク開発者は重要なことだけに集中し、ユーザーは豊富な言語機能にアクセスできるようにします。checkerやformatterにも使えます。

Vueコミュニティ発のOSSがコミュニティを超えて発展しています。AstroはVolar.jsの活用によって、1万行の削減を達成したそうです。また、ByteDanceは社内フレームワーク向けの言語をVolar.jsで実装していると言います。

「Deep dive to UnJS and Nuxt 3」

この発表では、グローバル・ブレインのNozomu Ikuta氏がUnJSについて解説しました。

Ikuta氏はNuxt Contributorで、content module(v1系)を経て、現在はNuxtのCoreなどを主に担当しています。同時に、UnJSチームメンバーでもあります。

Nuxt 3でかなり大きな変化がありました。Vue 2->Vue 3, Webpack -> Vite/Webpack, 対象ブラウザーの変化(レガシーブラウザーを排除⁠⁠、Good DX->Elegant DX(かなりいいDX)への変化、Node->Node/Deno/Bun/Worker(Edge)と動作対象が広がりました。

UnJSはJavaScriptユーティリティの集まり

UnJSはOrganizationの名前であり、エコシステムの名前でもあります。高品質で、シングルパーパス(単一目的)なJavaScriptユーティリティの集まりです。

NodeやBunで同じふるまいのパッケージを提供します。どちらかでしか使えないものは提供しません。調和的に(in harmony⁠⁠、一貫性のある独立したパッケージが動作します。

Nuxtと関係の深いプロジェクトですが、独立した開発をしていて、多くのところに利益を与えることを目指します。

UnJSは50以上のプロジェクトがあり、それぞれがプロジェクトを象徴するアイコン・絵文字(たとえばcittyなら街並み🌆)があります。プロジェクト内ではNitro Engineが特に有名です。

UnJSの歴史

Sebastien(NuxtLabs CEO)らがNuxtの開発をスタートしたところから話はスタートします。

Pooya Parsapi0氏はNuxtの前からツール集をつくっていました。PooyaはNuxtにジョインしたあと、さらに個別に必要なツールを作ります。

その中でSigma、現在のNitroをNuxt用に作成しました。これはNuxt内で使う予定でしたが、リリース直前に別途OSSとして切り出すことを決定します。

こういった各種ツールやNitroをまとめてUnJSに集約させていきました。現在は第三者のパッケージを招待することも進めていて、unpdfなどがジョインしました。

UnJSはNuxtとは独立した開発ですが、Nuxtとかなり緊密にコラボレートしています。PooyaはNuxtの開発でも活躍していましたが、現在はDaniel(Daniel Roe)に譲って、UnJSを精力的に開発しています。

Nozomu Ikuta氏の発表

Nuxtの中でUnjsはどう使われているか

Nuxtの中で、UnjsはCLI、Configuration、Server Engine、Data Fetching、SEOに使われています。

cittyはNuxt CLIのコア、PLUGGABLE COMPOSABLEなAPIです。Lazy and async commands. 精力的に開発中です(まだstableではない⁠⁠。NuxtがもともとテーラーメイドなCLIだったのをこちらで置き換えました。

c12は設定管理ツールです。ConfigurationのC以降が12文字なのでこの名前です。設定ファイルを統一的に管理できます。Nuxt LayersやNitroのプリセットに利用。多くのフォーマット形式に対応し、sourcesのマージ、gigetによるリモートレイヤーの取得も可能です。

Nitroはどこでも動くWebサーバーです。Nuxt 3の重要な機能、メインエンジンです。Nuxtとは独立して利用可能です。ベンダーロックインなしでどこでも動くのが特徴で、設定がビルトインで提供されています。キャッシュ管理やアセット処理、Hooksなど多数の機能を備えています。nitro build一発でビルドに使えます。UnJSの中でもPooyaが特に注力しているプロジェクトです。

h3は、ミニマルなHTTPフレームワークです。ExpressやKoaの代替で、Nuxt 3ではサーバールートとして利用しています。超高速なルートマッチングが特徴です。必要なものだけを最終的に取り入れる、composableなユーティリティを提供します。

ofetchはbetter fetch APIです。Nuxtではフェッチャーとして利用します。responseをパースし、エラーハンドリングやオートリトライを提供します。interceptorをサポートしています。

unhead<head />のマネージャーです。ヘッド操作(SEO改善)に使われます。フレームワーク非依存、SSR/CSR両方のサポート、フック可能といった特徴があります。

cittyによってCLIをruntimeからはがせるなど、UnJSがNuxt3の発展に大きく寄与しました。

UnJSはエコシステムです。それぞれは一つの問題解決に注力し、Working with harmony(協調・調和して動く)を目指しています。NuxtはUnJSエコシステム上に構築されています。UnJSの進化がNuxtの進化に直結します。

「マルチスレッドフレンドリーなJavaScriptを求めて」

この発表では、翠(sapphi-red)氏がマルチスレッドフレンドリーなJavaScriptについて解説しました。

翠氏は、Viteコアチームメンバー、東工大デジタル創作同好会traP、ポケットサインに所属しています。ViteではPRのレビュー、Issueトリアージ、バグ修正、使いやすさの改善、flakeyなテストの修正をしています。Vite 5ではRollup 4対応を進め、Rollup側の修正も担当しました。

マルチスレッドフレンドリーなJavaScript

シングルスレッドだと順に実行されるますが、マルチスレッドだと複数の計算を同時にできるなど時間的に有利になることがあります。

翠(sapphi-red)氏の発表

マルチスレッドで処理を同時に実行できる数はCPU依存です。4〜16程度が近年のCPUだと一般的でしょうか。マルチスレッドは必ずしもコア数で実行速度がそのまま決まるわけではないのですが、そのポテンシャルはあります。

JavaScriptはシングルスレッドで実行されます。マルチスレッドで気にする値の変化などは、JavaScriptで注意することはありません。

このため、JavaScriptでマルチスレッドを実現したければ何らかの回避策が必要です。

  1. JavaScriptエンジン外でマルチスレッドにしたい処理を実行
  2. 複数のJavaScriptエンジンのインスタンスを実行
    • 単純に別プロセスを実行する
      • Jest/Vitest(プールオプションにforkを指定すると利用化)
    • Node.js cluster
    • Node.js Worker threads
      • Vitest(default)
      • Jest(experimental support, option)
      • pnpm
    • ブラウザ/Deno/Bun: Web worker threds(に似た仕組み)を用いる

例えば、fetchはJavaScriptエンジン外でネットワーク処理をし、別スレッドに処理を委譲できます(エンジン外で実行に該当⁠⁠。

複数インスタンスでの実行と課題

複数インスタンスを起動する場合、基本的に参照の共有はできません。そのため、次の課題が生じます。

  1. 値のコピーを行うことになる
    • スレッド間のやり取りのたびにコピーによるオーバーヘッドが発生。これによってマルチスレッドのほうが遅いということも起こりうる。
  2. スレッド境界をこえたあとでは参照での比較ができない
  3. コピーできないもの(関数やクラスの情報)はやり取りできない
    • メインスレッドの関数の参照を直接別スレットのエントリーポイントにできない。
    • 文字列やファイルパスとしてコードを与える必要がある。
  4. コピーせず移動・共有できるArrayBufferやsharedArrayBufferはバイト列しか扱えない
    • 利用するにはバイト列に対する操作に書き換える必要がある。実際には文字列などの長さが決まっていないものも扱わなくてはならず、結構大変。ArrayBuffer向けにbuffer-backed-objectというライブラリもあるが、可変長には未対応。

マルチスレッドを活用しやすい理想的な設計

マルチスレッドを活用するためには、スレッド間の依存関係を減らすことが重要です。

  1. グローバルで共有する状態への依存を減らす
    • 例えば、TypeScriptのdeclaration mergingではファイルに対する処理がグローバルなインターフェース情報一覧テーブルに依存しています。これだとテーブルがあるために処理がわけにくいです。
  2. 関数をもつオブジェクトへの依存を減らす
    • 関数をオブジェクトに持たせるとオブジェクト内部の関数は別スレッドに移せません。
  3. 参照への依存を減らす
    • 別スレッドだと参照できない場合、常にある値がfalseになってしまいます。

既存プロジェクトへの適用箇所

既存プロジェクトへの適用にあたっては、依存関係に注目してマルチスレッドにする箇所を選択すること、依存関係が少なく処理が多い箇所を見つけることが重要になってきます。

Worker threadsを利用して別スレッドを呼び出すように書き換えるのは、素朴にやるとかなりやることが多くなります。そこで、artichokieというライブラリを作成しました。okieベースです。このライブラリがマルチスレッド化を簡単にしてくれるため、変更の試行回数を増やせます。必ずしもマルチスレッドが速くなるわけではないので、そういった試行回数の確保は重要になってきます。

Viteへのプルリクエスト(vite#13584)で、この成果を元にCSSプリプロセッサを別スレッドで実効するように変更しました。たとえば、less(CSSプリプロセッサ)ではlessを実行する部分がマルチスレッド化され、実装の結果高速化を実現できています。

これらについてはVite 5.1での導入を目指しています。

マルチスレッドの活用は高速化に必須です。その活用のためにはスレッド間の依存を減らすことが大切です。ぜひartichokieをつかってください。

「eslint-plugin-vueの現状と今後」

この発表では、フューチャーの太田洋介(ota-meshi)氏がeslint-plugin-vueの現状、今後について解説しました。

太田氏はシニアアーキテクトを勤めており、eslint-plugin-vueのメンテナーのほか、SvelteやESLintのコミッターでもあります。

ESLintの特徴とeslint-plugin-vue

ESLintはJavaScriptのリンターです。次の特徴があります。

  • 問題やスタイル違反を見つけ、自動的に修正可能
  • すべての検証ルールはON/OFF可能で、レポート内容をオプションで変更可能
  • プラグインによって検証ルール追加可能
  • JavaScript以外もチェック可能

eslint-plugin-vueはVue.js公式のESLintプラグインで、linter, formatter, migration tool(移行ツール)としてVueを強力にサポートしてきました。*.vueファイルを解析可能にし、特化ルールも追加しています。230ものルールがあります。

ESLintはフォーマット機能を減らしていく方向性ですが、eslint-plugin-vueでは残していく予定です。

eslint-plugin-vueの変遷

2013年にESLint、2014年にVue.jsが登場しました。2016年にVue.js v2とeslint-plugin-vue v1.0.0が登場します。このeslint-plugin-vueは現在のものとは仕組みが全く別物で、templateブロックのチェックなどはできませんでした。

後のeslint-plugin-vue v3はカスタムパーサーを使用した全く新しい仕組みで実装されました。templateも読めるようになりました。

2017年、vue-eslint-parserの登場で、ESLintと互換性のあるASTを生成できるようになりました。Vue専用カスタムパーサーの登場は当時とても注目しました。これがeslint-plugin-vuejs-accesibilityやeslit-plugin-vue-i18nなどの登場につながります。

2018年、prettier v1.10が.vueを部分的にサポートします。eslint-plugin-vue v4ではスタイルガイドをフォローするための多くのルールが追加されました。この年にメンテナーとして参加しています。

フォーマッターとしてのeslint-plugin-vue

Vueは実は公式のスタイルガイドが存在しています。それに従っているかどうかをeslint-plugin-vueでチェックできます。

eslint-plugin-vueはフォーマットをフルサポートしています。現在はprettierをフォーマットに使っている人が多いでしょうが、2018年当時は.vueをサポートしていなかったため優位性がありました。

2019年以降の歴史とこれから

2019年以降の歴史をまとめると、次のようになります。

  • 2019年
    • typescript-eslintが登場
    • eslint-plugin-vue v5
    • vue.js v2.6
    • eslint-plugin-vue6.0の登場
      • v2.6のサポート
      • v-slotへの移行を助けるルール
      • 一部のルールがnuxtをサポート
    • eslint-pluging-vue-i18n登場
  • 2019-2020年
    • 移行ツールとしてのeslint-plugin-vue
      • 廃止機能のチェックや、自動修正・提案が可能。3へのバージョン移行を助ける。
      • vuetifyの移行を助けるeslint-plugin-vuetifyもある。
  • 2021年
    • eslint-plugin-vue v7.11
      • Vue 3.1のサポート
  • 2022年
    • eslint-vue vue2用プリセットの大幅な改善や<script setup>の考慮
  • 2023年
    • Vue.js v3の変化にeslint-plugin-vueも追随

現在はv10のリリースを計画中です。Nuxtサポートも強化する予定です。

太田氏の発表

将来的な機能構想

TypeScriptの型情報を使用したチェックを考えています。現状のeslint-plugin-vueは型情報を使用したルールとの組み合わせに弱いです。template内では型を捨てるなどしてしまいます。

型情報を利用したeslintカスタムルールを作れればチェックできることが増えます。

現状、⁠template、script、styleなどの各ブロックを)別々にパースしているため、templateの中のブロック内のディレクティブのスクリプトは型情報を取ったところで意味がありません。使える型情報になっていません。

このバラバラのパースを、1つの理解できる形でくっつけて、パースした結果を構築し直してASTをつくればいいというアイディアを思いつきました。これでtemlpate内のディレクティブも正しい型情報が得られます。

実際に、eslint-plugin-svelteで試してみたらうまくいってそうで、信頼度も高そうです。

このアイディアをeslint-plugin-vueにも取り込むことが次の目標です。ほかにもいろいろアイディアがあるので、うまくいったものは取り込みたいです。

(このような抜本的な変化を加えるとなると)おそらくほぼすべてのルールが書き直しになります。しかし型情報が得られるので使いたいです。

他のトピックとしては、Project-awareも検討しています。これは、プロジェクト全体の情報を読み取ってlintに活かす機能です。typescript-eslintなどが実現した機能を取り込みたいです。実現すると、ルート情報の収集など、lintが大きく改善するかもしれません。

ESLint自体の進化がもたらすプロジェクト情報の事前収集などによる強力なチェックを活用できるようにしていきます。

アフターパーティー

アフターパーティーでは、川口和也氏とEvan You氏が挨拶をおこない、Vue Fes Japan 2023来場者やコミュニティへの謝意を述べました。そして大盛況のうちに閉会となりました。

登壇するEvan You氏と川口氏
集合写真

会場の模様

会場では、クリエイティブウォールやタトゥーシールスペース、グッズストアの展開などまさしくFesの盛り上がりようでした。

会場受付
個人や企業が書き込んだVue Fes Japan 2023ウォール
Vue Fes Store
Vue Fes Storeで売られていたTシャツ

筆者が気になったのは、海外の開発者の多くがArc Browserを使ってデモをしていたことです。海外のWeb開発者の間で人気があるのでしょうか?

※今回の記事で掲載した写真は、公式写真を使わせていただきました。

おすすめ記事

記事・ニュース一覧