目次

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'

これにより、開発者は 2 回目の移行を必要とせずに、すでに 2.12 Null セーフティをサポートしているパッケージで Dart 3 の健全な Null セーフティを使用できます。ただし、コードが他の Dart 3 の変更の影響を受けていない場合を除きます。

影響をテストする

#

ソースコードが 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.

言語バージョンコメントを使用して Null セーフティをオプトアウトし、2.12 より低い言語バージョンを選択するライブラリは、分析またはコンパイルエラーを引き起こします。

$ 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 とマークされない限り、ミックスインとして使用できません。この制限は、後者のライブラリの言語バージョンに関係なく、クラスをミックスインとして使用しようとする任意のライブラリのコードに適用されます。

範囲

#

これは、言語バージョン 3.0 以降にのみ適用される バージョン管理された変更です。

症状

#

次のような分析エラー

Mixin can only be applied to class.

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

移行

#

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

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

switch

#

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

範囲

#

これは、言語バージョン 3.0 以降にのみ適用される バージョン管理された変更です。

症状

#

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

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

移行

#

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

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

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

continue

#

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

範囲

#

これは、言語バージョン 3.0 以降にのみ適用される バージョン管理された変更です。

症状

#

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

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

移行

#

動作の変更が許容できる場合は、continuefordo、または 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.parse の非推奨となっていた onError 引数が削除されました。代わりに 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 を使用してください。
  • 非推奨となっていた Metrics, Metric, Counter, および Gauge クラスは、Dart 2.0 以降壊れていたため削除されました。

dart:html

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

dart:math

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

dart:io

#
  • vm_service:11.0.0 で導入された新しい String ID に対応するように NetworkProfiling を更新します。

症状

#

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 型は、実装、拡張、またはミックスインできなくなりました。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 に置き換えられました #1153
  • Dart Web コンパイラ用に SDK にバンドルされているスナップショットファイルがクリーンアップされました #50700
  • 一部のコードについて、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 コードに適用される バージョン管理されていない変更です。