【Flutter】ライブラリ追加時にpubspec.yamlに記載される「キャレット記号: ^」 の意味を知ろう
dependencies:
- package_name: ^3.4.5 // 最新バージョン
+ package_name: ^3.1.3
"上記のように、パッケージの最新バージョンから落として定義しているのに、pubpec.lockファイルでは以前として最新のバージョンが定義されてしまっているのはなぜなんだ?"
と、pubspec.yamlに記載するライブラリのバージョン指定方法の違いを理解しておらず、ライブラリの依存関係に沼ったので、改めてバージョン指定方法の違いを調べました。
ライブラリのバージョン番号の記載について
flutter pub add package_name
の実行や、pub.devのinstallingページの記載など、ライブラリを追加した際のバージョン番号にはキャレット記号: ^ が付いて記載されます。
基本的にはこの記載で十分ですが、Flutterバージョンや他のライブラリのバージョンとの依存関係の問題で、バージョンを下げて使用したい時が一度はあるかと思います。
そういった時、以下のライブラリのバージョンの指定方法の違いを理解しているとすんなりいくかと思います。
また、"なぜデフォルトでキャレット記号: ^ が付くのか"、といったことも理解できるようになるかと思います。
1. 特定のバージョンを固定で指定
package_name: 1.0.0
固定で指定すると、バージョンロック問題が発生する可能性が高いので、バージョン固定での使用は基本的には避けたい。
※「小規模のアプリ&作りっぱで特にアプデ予定もないアプリ」だと、バージョン固定での使用でも特に問題は無いかもしれない。
2. バージョン範囲を指定
package_name: '>=2.3.5 <2.4.0'
バージョンロック問題を回避するために、バージョンの範囲を指定する(依存関係の制約を緩める)ことができる。
上記の例だと、「2.3.5以上、2.4.0未満」のバージョンを使用することができ、"pub"が自動的に上記のバージョン範囲の中で、「最新のバージョン、かつ、制約を満たすもの」を自動的に選択してくれる。
しかし、これだと現在の最新のバージョンまでしか対応していないので、今後のバージョンアップによっては、バージョンロック問題が発生する可能性がある。
3. 未来のアップデートまで含めたバージョン範囲を指定
package_name: ^2.3.5
上記のように、キャレット記号をつけることで、今後のアップデートまで含めた範囲を指定することができる。
範囲としては、「3.0.0を含まない、2.3.5から3.0.0までの全バージョン」が対象となる。
先ほどの2.と同様に、上記のバージョン範囲で「最新のバージョン、かつ、制約を満たすもの」を自動的に選択してくれる。(≒範囲内で自動でアップデート対応してくれるイメージ)
まとめ
キャレット記号付きのバージョン番号が、どういった意味を持つのかを理解していれば、冒頭に述べたような沼にハマることは無かったと思います。
今回のように、慣例のおまじないとして、意味を知らずにコードを書いてると思わぬところでハマる可能性があるなぁ、、、と再確認できました。
※備考1. バージョンロックの例
name: sample_app
dependencies:
A: ^1.1.0
B: ^1.1.0
C: 1.0.0
上記のようなパッケージを入れたアプリがあるとします。
AとBは、それぞれのライブラリの内部的に「C: ^1.0.0」に依存しているものとします。
現状だと、AとBはキャレット記号付きなので、今後ライブラリのバージョンを上げようとした際に、AとBの内部的に依存しているCのバージョンが「1.0.0」から上がってしまうと、AとBは新しいバージョンを適用できない(sample_appでは「C:1.0.0」と記載があるため、「C:1.0.0」までのバージョンしかAとBは適用できない)状態となります。
※備考2. バージョン番号"1.0.0"以下の場合のバージョン番号ルール
semantic versioning(セマンティック・バージョン)
バージョン番号の付け方のルールのこと。
バージョン番号はMAJOR.MINOR.PATCHの形式で表され、それぞれの数値は以下の特定の意味を持つ。
- MAJOR: 互換性を破る変更があった場合に増加。
- MINOR: 新機能が追加され、かつそれが後方互換性を保つ場合に増加。
- PATCH: 後方互換性のあるバグ修正が行われた場合に増加。
セマンティックバージョニングの公式なルールでは、1.0.0より前のバージョン(つまり開発初期段階のバージョン)については互換性を約束しないとされている。
Flutterにおいて、
パッケージのバージョンが"1.0.0"に達する前のバージョンについては、Dartコミュニティの慣例で、ライブラリのバージョン番号の変更は以下のルールで基本的に実施される。
- 0.1.2 → 0.2.0 への移行:変更点があることを示す。
- 0.1.2 → 0.1.3 への移行:新機能が追加されたことを示す。
- 0.1.2 → 0.1.2+1 への移行:パブリックAPIに影響を与えない変更点があることを示す。
また、分かりやすくするため、バージョンが1.0.0に達した後は+の使用を避けることが推奨されている。
※備考3. any
anyは非推奨。
※参照のドキュメントに記載あり。
参照
Discussion