Open3

package:web 1.0.0対応の話

koji-1009koji-1009

https://pub.dev/packages/web/versions/1.0.0

package:webの1.0.0がリリースされ、依存関係的に混乱が生じると思うのでメモ書いておきます。


結論としては、下記の通りの対応で良いはずです。

  1. 利用ライブラリの最新版を取得する
  2. アプリレイヤーで package:web に依存している場合には、 ^1.0.0 の指定に変えてビルドをする
  3. もしもパッケージ間で package:web のバージョン問題が起きたら、dependency_overridesで ^1.0.0 を指定する
koji-1009koji-1009

package:webpackage:html を置き換える、新たなパッケージです。JavaScript interoperability が大きく改善しており、WASMとしてビルドできるようになります。

先日、package:webのv1.0.0がリリースされました。このv1.0.0が局地的に破壊的な変更をもたらしたため、パッケージ間の依存関係が壊れる恐れがあります。
本scrapは、この状況を解説するものです。問題が生じるのも数ヶ月以内におさまると思われるので、ざっと書いたscrapとしています。


package:webの0.5.0系と1.0.0系の大きな違いは、「ブラウザごとにサポートされている状況が異なるAPIに対応しているかどうか」です。v0.5.0系では、すべてのブラウザでサポートされているAPIが実装されました。
例えば window.navigator.storage はv0.5.0系で利用できるAPIですが、(考慮すべき)すべてのブラウザでサポートされています。

https://pub.dev/documentation/web/0.5.1/web/Navigator/storage.html
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/storage

他方、ブラウザごとに実装状況が異なっているAPIもあります。例えば、次のようなAPIです。

https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getBattery#browser_compatibility
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share#browser_compatibility

これらAPIはv0.5.0系には存在しませんが、v1.0.0系にて追加されていることが確認できます。

https://pub.dev/documentation/web/1.0.0/web/Navigator/getBattery.html
https://pub.dev/documentation/web/1.0.0/web/Navigator/share.html

ここまで見れば、サポートが広がり、とても素敵な話だと言えます。


0.5.0と1.0.0はメジャーバージョンが異なります。このため、バージョンの記載に一工夫が必要です。

ややこしいのは、pacakge:webの1.0.0以上を必要とするのは、一部の「ブラウザごとにサポート状況が異なるAPIにアクセスする必要があったパッケージ」です。

それ以外のパッケージにおいては、そもそもpackage:webを更新せずとも(パッケージとしては)問題がありません [1]
対応としては、>=0.5.1 <2.0.0 と記述して2つのメジャーバージョンをサポートするか [2]^1.0.0 と記述して利用者側にアップデートを促すかになります。

「ブラウザごとにサポート状況が異なるAPIにアクセスする必要があったパッケージ」の筆頭は、plus_pluginsです。plus_pluginsは元々flutterチームが管理していたような、それなりにプラットフォームに依存するAPIを提供しています。

https://github.com/fluttercommunity/plus_plugins/issues/3093

このplus_pluginsにおいては、次の2つの対応方法があります。

  1. >=0.5.0 <2.0.0 の記載 + 従来の extension type を用いたAPIの提供で、移行期間用のバージョンをリリースする
  2. ^1.0.0 の記載 + APIを package:web が提供するものに統一する

メンテナーの方針としては、package:webのAPIを利用したいとのことで、後者の方針が取られることになりました。このため、一部のplus_pluginsにおいては package:web 1.0.0でないとビルドが失敗する 状況になっています。

https://github.com/fluttercommunity/plus_plugins/pull/3103


一部のplus_pluginsを利用する場合には 必ずpackage:web 1.0.0(以上を)利用する必要 があります。
とは言え、そもそもpackage:webのどのAPIが問題を生じさせるのか、などを調べるのは面倒です。また、メンテナーにも事情があるため、すべての web: ^0.5.0 と書いていたパッケージが web: ">=0.5.0 <2.0.0" にすぐさま更新できるとは限りません。

このため、筆者としては

  • 利用しているパッケージが package:web 1.0.0 をサポートしていなかったら、サポートを依頼するissueを立てる
  • dependency_overridesを利用して、 package:web ^1.0.0 を指定する

ことをお勧めします。もしも「package:web 1.0.0の差分を見ないと、安心できない!」という方は、changelogを確認してみると良いでしょう。

https://github.com/dart-lang/web/releases/tag/v1.0.0

脚注
  1. 問題がないので、issueが立つまで更新する必要に気づきません ↩︎

  2. https://github.com/flutter/packages/pull/7202 ↩︎

koji-1009koji-1009

今回の課題は、package:webの0.5.0リリースを急ぎすぎたことが、原因となっているでしょう。おそらく WASM IO でDart 3.3とjs_interopの対応をリリースするため、急遽package:web 0.5.0をリリースした影響が出ています。
しかし、

  1. 0.x.x系として安定しないバージョンとしてリリースしたこと
  2. package: html との差分が生じている状態でリリースしたこと
  3. ブラウザごとに実装の差があるAPIについて議論状態でリリースしたこと
  4. (たった)半年で1.0.0のstableなリリースを行ったこと

の4点については、見込みが甘すぎたのではないかと。
名目上、Flutter Webはstableな状態です。このstableな環境を破壊しうるものを「とりあえず」で出しているように見える現状は、歓迎できるものではありません。