メインコンテンツにスキップ

Dart 3 移行ガイド

Dart 3 は、Dart に新しいコア機能である レコードパターン、および クラス修飾子 を導入するメジャーリリースです。

これらの新機能と並行して、Dart 3 には既存のコードを破壊する可能性のある多くの変更が含まれています。

このガイドは、Dart 3 にアップグレードした後に発生する可能性のある移行の問題を解決するのに役立ちます。

はじめに

#

バージョン指定なしの変更とバージョン指定ありの変更

#

以下にリストされている、潜在的に破壊的な変更は、次の 2 つのカテゴリのいずれかに分類されます。

  • バージョン指定なしの変更: これらの変更は、Dart 3.0 SDK 以降にアップグレードした Dart コードすべてに影響します。これらの変更を「オフにする」方法はありません。

  • バージョン指定ありの変更: これらの変更は、パッケージまたはアプリの言語バージョンが Dart 3.0 以上に設定されている場合にのみ適用されます。言語バージョンは、pubspec.yaml ファイルsdk の下限から導出されます。このような SDK 制約は、Dart 3 のバージョン指定ありの変更を適用しません。

    yaml
    environment:
      sdk: '>=2.14.0 <3.0.0'

    ただし、このような SDK 制約は適用します。

    yaml
    environment:
      sdk: '>=3.0.0 <4.0.0'

新しい Dart 3 の機能を使用するには、言語バージョンを 3.0 に更新する必要があります。これにより、Dart 3 のバージョン指定ありの変更も同時に適用されます。

Dart 3 の後方互換性

#

Dart 2.12 以降で null 安全性を使用していた多くのパッケージやアプリは、Dart 3 と後方互換性がある可能性が高いです。これは、SDK 制約の下限が 2.12.0 以上であるパッケージであれば可能です。

Dart の pub ツールは、上限が 3.0.0 未満に制限されている場合でも解決を許可します。たとえば、次の制約を持つパッケージは、Dart 3.x SDK で解決できます。これは、下限が 2.12 以上の場合、pub が上限 <3.0.0<4.0.0 に再解釈するためです。

yaml
environment:
  sdk: '>=2.14.0 <3.0.0'           # This is interpreted as '>=2.14.0 <4.0.0'

これにより、開発者は、コードが他の Dart 3 の変更の影響を受けていない限り、2.12 の null 安全性をサポートするパッケージで Dart 3 のサウンド null 安全性を、2 回目の移行なしに使用できます。

影響のテスト

#

ソースコードが Dart 3 の変更の影響を受けているかどうかを判断するには、次の手順を使用します。

dart --version    # Make sure this reports 3.0.0 or higher.
dart pub get      # This should resolve without issues.
dart analyze      # This should pass without errors.

pub get ステップが失敗した場合は、依存関係をアップグレードして、より新しいバージョンが Dart 3 をサポートしているかどうかを確認してください。

dart pub upgrade
dart analyze      # This should pass without errors.

または、必要に応じて、メジャーバージョンのアップグレードも追加してください。

dart pub upgrade --major-versions
dart analyze      # This should pass without errors.

Dart 3 の言語変更

#

100% のサウンド null 安全性

#

Dart 2.12 は 2 年以上前に null 安全性を導入しました。Dart 2.12 では、ユーザーは pubspec 設定で null 安全性を有効にする必要がありました。Dart 3 では、null 安全性は組み込まれており、オフにすることはできません。

スコープ

#

これはバージョン指定なしの変更であり、すべての Dart 3 コードに適用されます。

症状

#

null 安全性をサポートせずに開発されたパッケージは、pub get で依存関係を解決する際に問題を引き起こします。

dart pub get

Because pkg1 doesn't support null safety, version solving failed.
The lower bound of "sdk: '>=2.9.0 <3.0.0'" must be 2.12.0 or higher to enable null safety.

言語バージョンコメントで 2.12 未満の言語バージョンを選択して null 安全性をオプトアウトするライブラリは、分析またはコンパイルエラーを引き起こします。

dart analyze .
Analyzing ....                         0.6s

  error • lib/pkg1.dart:1:1 • The language version must be >=2.12.0. 
  Try removing the language version override and migrating the code.
  • illegal_language_version_override
dart run bin/my_app.dart
../pkg1/lib/pkg1.dart:1:1: Error: Library doesn't support null safety.
// @dart=2.9
^^^^^^^^^^^^

移行

#

Dart 3 への移行を開始する前に、アプリまたはパッケージが 100% null 安全性に移行されていることを確認してください。これには Dart 3 SDK ではなく Dart 2.19 SDK が必要です。アプリまたはパッケージを null 安全性をサポートするように最初に移行する方法については、null 安全性移行ガイドを確認してください。

デフォルト値のコロン構文

#

歴史的な理由から、名前付きオプションパラメータは : または = のいずれかを使用してデフォルト値を指定できました。Dart 3 では、= 構文のみが許可されます。

スコープ

#

これはバージョン指定ありの変更であり、言語バージョン 3.0 以降にのみ適用されます。

症状

#

Dart の分析では、次のようなエラーが発生します。

line 2 • Using a colon as a separator before a default value is no longer supported.

移行

#

コロンの使用からの変更

dart
int someInt({int x: 0}) => x;

イコールを使用するように

dart
int someInt({int x = 0}) => x;

この移行は手動で行うことも、dart fix で自動化することもできます。

dart fix --apply --code=obsolete_colon_for_default_value

mixin

#

Dart 3 より前は、コンストラクタがなく、Object 以外のスーパークラスがない限り、任意の classmixin として使用できました。

Dart 3 では、言語バージョン 3.0 以降のライブラリで宣言されたクラスは、mixin としてマークされていない限り、mixin として使用できなくなりました。この制限は、クラスの言語バージョンに関係なく、クラスを mixin として使用しようとする任意のライブラリのコードに適用されます。

スコープ

#

これはバージョン指定ありの変更であり、言語バージョン 3.0 以降にのみ適用されます。

症状

#

次のような分析エラー

Mixin can only be applied to class.

アナライザーは、mixin class でも mixin でもないクラスが with 句で使用されている場合に、この診断を生成します。

移行

#

クラスが mixin として使用されることを意図しているかどうかを判断します。

クラスがインターフェースを定義している場合は、implements の使用を検討してください。

switch

#

Dart 3.0 は、switch ケースを定数式ではなく パターンとして解釈します。

スコープ

#

これはバージョン指定ありの変更であり、言語バージョン 3.0 以降にのみ適用されます。

症状

#

switch ケースで見つかったほとんどの定数式は、同じ意味を持つ有効なパターンです(名前付き定数、リテラルなど)。これらは同じように動作し、症状は発生しません。

有効なパターンではない定数式は、invalid_case_patterns lint をトリガーします。

移行

#

ケースパターンに const をプレフィックスとして付けることで、元の動作に戻すことができます。これにより、パターンとして解釈されなくなります。

dart
case const [1, 2]:
case const {'k': 'v'}:
case const {1, 2}:
case const Point(1, 2):

dart fix を使用するか、IDE からこの破壊的変更のクイックフィックスを実行できます。

continue

#

Dart 3 は、continue ステートメントがループ(fordo、および while ステートメント)または switch メンバーではないラベルをターゲットとしている場合、コンパイル時エラーを報告します。

スコープ

#

これはバージョン指定ありの変更であり、言語バージョン 3.0 以降にのみ適用されます。

症状

#

次のようなエラーが表示されます。

The label used in a 'continue' statement must be defined on either a loop or a switch member.

移行

#

動作の変更が許容される場合は、continue を、fordo、または while ステートメントにアタッチされた有効なラベル付きステートメントをターゲットするように変更します。

動作を維持したい場合は、continue ステートメントを break ステートメントに変更します。Dart の以前のバージョンでは、ループまたは switch メンバーをターゲットとしていない continue ステートメントは break のように動作していました。

Dart 3 のコアライブラリの変更

#

削除された API

#

破壊的変更 #49529: 数年間非推奨となっていた API を削除するために、コアライブラリが整理されました。以下の API は Dart コアライブラリに存在しなくなりました。

スコープ

#

これはバージョン指定なしの変更であり、すべての Dart 3 コードに適用されます。

dart:core

#
  • 非推奨の List コンストラクタは、null 安全ではなかったため削除されました。リストリテラル(例: 空のリストの場合は []、型指定された空のリストの場合は <int>[])または List.filled を使用してください。これは null 安全でないコードにのみ影響します。null 安全なコードでは、このコンストラクタはすでに使用できませんでした。
  • int.parsedouble.parse、および num.parseonError 引数の非推奨が解除されました。代わりに tryParse メソッドを使用してください。
  • 非推奨の proxy および Provisional アノテーションが削除されました。元の proxy アノテーションは Dart 2 では効果がなく、Provisional 型と provisional 定数は、Dart 2.0 の開発プロセス中に内部的にのみ使用されていました。
  • 非推奨の Deprecated.expires ゲッターが削除されました。代わりに Deprecated.message を使用してください。
  • 非推奨の CastError エラーが削除されました。代わりに TypeError を使用してください。
  • 非推奨の FallThroughError エラーが削除されました。このエラーを発生させていたフォールスルーの種類のコンパイル時エラーは、Dart 2.0 で導入されました。
  • 非推奨の NullThrownError エラーが削除されました。このエラーは null 安全なコードからは決してスローされません。
  • 非推奨の AbstractClassInstantiationError エラーが削除されました。抽象クラスのコンストラクタを呼び出すことは、Dart 2.0 でコンパイル時エラーになりました。
  • 非推奨の CyclicInitializationError が削除されました。循環依存関係は、null 安全なコードでは実行時に検出されなくなりました。そのようなコードは、StackOverflowError など、別の方法で失敗する可能性があります。
  • 非推奨の NoSuchMethodError のデフォルトコンストラクタが削除されました。代わりに NoSuchMethodError.withInvocation 名前付きコンストラクタを使用してください。
  • 非推奨の BidirectionalIterator クラスが削除されました。既存の双方向イテレータは引き続き機能しますが、後方移動の特定の名前でロックする共通のスーパタイプがなくなりました。

dart:async

#
  • 非推奨の DeferredLibrary クラスが削除されました。代わりに deferred as インポート構文を使用してください。

dart:developer

#
  • 非推奨の MAX_USER_TAGS 定数が削除されました。代わりに maxUserTags を使用してください。
  • 非推奨の MetricsMetricCounter、および Gauge クラスは、Dart 2.0 以降壊れていたため削除されました。

dart:html

#
  • 以前に発表されたとおり、Document および HtmlDocument の非推奨の registerElement および registerElement2 メソッドが削除されました。詳細については、#49536 を参照してください。

dart:math

#
  • Random インターフェースは、実装のみ可能で、拡張はできません。

dart:io

#
  • NetworkProfiling を更新して、vm_service:11.0.0 で導入された新しい String ID に対応させてください。

症状

#

Dart の分析(IDE や dart analyze/flutter analyze など)は、次のようなエラーで失敗します。

error line 2 • Undefined class 'CyclicInitializationError'.

移行

#

これらの API の使用から手動で移行してください。

extends & implements

#

Dart 3 は、クラスの機能を制限できる新しい クラス修飾子をサポートしています。これらは、コアライブラリの多くのクラスに適用されています。

スコープ

#

これはバージョン指定ありの変更であり、言語バージョン 3.0 以降にのみ適用されます。

dart:async

#
  • 以下の宣言は、拡張できず、実装のみ可能です。

    • StreamConsumer
    • StreamIterator
    • StreamTransformer
    • MultiStreamController

    これらの宣言には、継承できる実装は含まれていませんでした。これらは、インターフェースとしてのみ意図されていることを示すために interface としてマークされています。

dart:core

#
  • Function 型は、実装、拡張、または mixin として使用できなくなりました。Dart 2.0 以降、後方互換性のために implements Function を記述することは許可されていましたが、効果はありませんでした。Dart 3.0 では、Function 型は final であり、サブタイプ化できないため、コードが誤って動作すると想定することを防ぎます。

  • 以下の宣言は、拡張できず、実装のみ可能です。

    • Comparable
    • Exception
    • Iterator
    • Pattern
    • Match
    • RegExp
    • RegExpMatch
    • StackTrace
    • StringSink

    これらの宣言には、継承できる実装は含まれていませんでした。これらは、インターフェースとしてのみ意図されていることを示すために interface としてマークされています。

  • 以下の宣言は、実装または拡張できなくなりました。

    • MapEntry
    • OutOfMemoryError
    • StackOverflowError
    • Expando
    • WeakReference
    • Finalizer

    MapEntry 値クラスは、後続の最適化を可能にするために制限されています。残りのクラスはプラットフォームに密接に関連しており、サブクラス化または実装を意図していません。

dart:collection

#
  • 以下のインターフェースは、拡張できなくなり、実装のみ可能になりました。

    • Queue
  • 以下の実装クラスは、実装できなくなりました。

    • LinkedList
    • LinkedListEntry
  • 以下の実装クラスは、実装または拡張できなくなりました。

    • HasNextIterator(非推奨でもあります。)
    • HashMap
    • LinkedHashMap
    • HashSet
    • LinkedHashSet
    • DoubleLinkedQueue
    • ListQueue
    • SplayTreeMap
    • SplayTreeSet

Dart 3 のツール変更

#

削除されたツール

#

歴史的に Dart チームは、コードのフォーマット(dartfmt)、コードの分析(dartanalyzer)などのための小規模な開発者ツールをいくつか提供してきました。Dart 2.10(2020 年 10 月)で、新しい統合された Dart 開発者ツールである dart ツールを導入しました。

スコープ

#

これはバージョン指定なしの変更であり、すべての Dart 3 コードに適用されます。

症状

#

Dart 3 では、これらの小規模なツールは存在せず、新しい統合された dart ツールに置き換えられました。

移行

#

dart ツールで利用可能な新しいサブコマンドを使用してください。

旧ツールdart の置き換え非推奨廃止
stagehanddart create2.142.14*
dartfmtdart format2.142.15
dart2nativedart compile exe2.142.15
dart2jsdart compile js2.172.18
dartdevcwebdev2.172.18
dartanalyzerdart analyze2.162.18
dartdocdart doc2.162.17
pubdart pub2.152.17

null 安全性移行ツール

#

Dart 3 は null 安全性がないコードをサポートしていないため、以下の null 安全性移行コマンドが削除されました。

  • dart migrate
  • dart pub upgrade --null-safety
  • dart pub outdated --mode=null-safety

スコープ

#

これはバージョン指定なしの変更であり、すべての Dart 3 コードに適用されます。

症状

#

これらのコマンドは失敗します。

移行

#

Dart 2.19 を使用して null 安全性に移行してください。

アナライザーの設定

#

アナライザーの設定オプションで、より厳密なチェックを有効にするためのオプションが変更されました。

スコープ

#

これはバージョン指定なしの変更であり、すべての Dart 3 コードに適用されます。

症状

#

以前の設定オプションは、次のような警告で失敗します。

The option 'implicit-casts' is no longer supported.
Try using the new 'strict-casts' option.

移行

#

アナライザー設定のこの部分を置き換える

yaml
analyzer:
  strong-mode:
    implicit-casts: false
    implicit-dynamic: false

次のように

yaml
analyzer:
  language:
    strict-casts: true
    strict-raw-types: true

その他のツールの変更

#
  • 非推奨の Observatory はデフォルトで非表示になりました。DevTools の使用をお勧めします。
  • コマンド dart format fix は、dart fix に置き換えられました。
  • Dart Web コンパイラーの SDK にバンドルされているスナップショットファイルが整理されました。
  • dart format の出力は、一部のコードで少し変更されました。
  • Windows 上の古い pub-cache の場所に対する後方互換性が終了しました。Dart 3 より前は、%APPDATA%\Pub\Cache が pub-cache のフォールバック場所でした。Dart 3 以降、デフォルトの pub-cache は %LOCALAPPDATA%\Pub\Cache にあります。グローバルにアクティベートされたパッケージを PATH に追加している場合は、PATH%LOCALAPPDATA%\Pub\Cache\bin を含むように更新することを検討してください。

スコープ

#

これはバージョン指定なしの変更であり、すべての Dart 3 コードに適用されます。