Flutter專案遷移到Null Safety空安全

xmb發表於2021-08-06

相關文章:


1. 建立分支命名為flutter2_null-safety,並切換到新分支。
2. 專案中使用了fvm,執行fvm use stable,使用Flutter最新的stable分支。
3. 執行flutter doctor
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.5.1 20G80 darwin-x64, locale zh-Hans-CN)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] Connected device (2 available)

• No issues found!

複製程式碼
4. 檢視dart版本,是否為2.12或更高
$ dart --version
fvm: running Dart from Flutter "stable"

Dart SDK version: 2.13.4 (stable) (Wed Jun 23 13:08:41 2021 +0200) on "macos_x64"
複製程式碼
5. 檢查所有依賴的遷移狀態
$ dart pub outdated --mode=null-safety
fvm: running Dart from Flutter "stable"

Showing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.

Package Name                     Current        Upgradable  Resolvable  Latest                 

direct dependencies:            
amap_location                    ✗0.2.0 (git)   -           -           ✗0.2.0 (git)           
audioplayers                     ✗0.17.4 (git)  -           -           ✗0.17.4 (git)          
azlistview                       ✗0.1.2         -           -           ✓2.0.0-nullsafety.0    
badges                           ✗1.2.0         -           -           ✓2.0.1                 
barcode_scan                     ✗2.0.2         -           -           ✗3.0.1                 
cached_network_image             ✗2.5.1         -           -           ✓3.1.0                 
chewie                           ✗0.12.2        -           -           ✓1.2.2                 
connectivity                     ✗2.0.2         -           -           ✓3.0.6                 
date_range_picker                ✗1.0.7         -           -           ✗1.0.7                 
device_info                      ✗1.0.0         -           -           ✓2.0.2                 
dio                              ✗3.0.10        -           -           ✓4.0.0                 
event_bus                        ✗1.1.1         -           -           ✓2.0.0                 
exifdart                         ✗0.7.0+3       -           -           ✓0.8.0-dev.2           
fdottedline                      ✗1.0.1         -           -           ✗1.0.1                 
flutter_app_badger               ✗1.1.2         -           -           ✓1.2.0                 
...
...
...     

dev_dependencies:               
build_runner                     ✗1.11.1        -           -           ✓2.0.6                 
No resolution was found. Try running `dart pub upgrade --null-safety --dry-run` to explore why.
複製程式碼
6. 依賴遷移優先順序

A依賴B,B依賴C,遷移順序為:C > B > A。

7. 對本地引入的庫分析是否具備遷移條件

① 幾個自己定義的外掛庫庫已經建立了null-safety分支做了遷移支援。 ② 其他三方的庫也都找到了可替換了null-safety庫。 ③ 本地引入的外掛,替換為git方式引入,建立null-safety分支,做遷移支援。

以上所有外掛,保證都具備遷移條件。

如果外掛還沒遷移,使用以下第⑧條的方法先將外掛遷移,遷移完之後,使用null-safety分支。

  talkingdata_appanalytics_plugin:
    git:
      url: http://*******/*******/app_analytics_sdk_flutter.git
      ref: null-safety
複製程式碼
8. 開始遷移
fvm use stable
dart --version確保使用的dart為最新版本
③ 執行 dart pub outdated --mode=null-safety 以確保所有依賴為最新且空安全。
$ dart pub outdated --mode=null-safety
fvm: running Dart from Flutter "stable"

Showing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.

All your dependencies declare support for null-safety.
複製程式碼

如果依賴沒有更新到最新版本,比如以下:

$ dart pub outdated --mode=null-safety
fvm: running Dart from Flutter "stable"

Showing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.

Package Name   Current  Upgradable  Resolvable  Latest   

direct dependencies:
path_provider  ✗1.6.22  -           ✓2.0.2      ✓2.0.2   
uuid           ✗2.2.2   -           ✓3.0.4      ✓3.0.4   

dev_dependencies:
http           ✗0.12.2  -           ✓0.13.3     ✓0.13.3  
No resolution was found. Try running `dart pub upgrade --null-safety --dry-run` to explore why.

3  dependencies are constrained to versions that are older than a resolvable version.
To update these dependencies, edit pubspec.yaml, or run `dart pub upgrade --null-safety`.
複製程式碼

執行 dart pub upgrade --null-safety 將依賴升級至支援空安全的最新版本。 注意: 該命令會更改你的 pubspec.yaml 檔案。

④ 在包含 pubspec.yaml 的目錄下,執行 dart migrate 命令,啟動遷移工具。
$ dart migrate 
fvm: running Dart from Flutter "stable"

Migrating /Users/yuanzhiying/Desktop/app_analytics_sdk_flutter

See https://dart.dev/go/null-safety-migration for a migration guide.

Note: more than one project found; migrating the top-level project.

Analyzing project...
No analysis issues found.

Generating migration suggestions...
Compiling instrumentation information...
View the migration suggestions by visiting:

  http://127.0.0.1:52996/Users/yuanzhiying/Desktop/app_analytics_sdk_flutter?authToken=zbeBO82KY54%3D

Use this interactive web view to review, improve, or apply the results.
When finished with the preview, hit ctrl-c to terminate this process.

If you make edits outside of the web view (in your IDE), use the 'Rerun from
sources' action.
複製程式碼
⑤ 訪問http://127.0.0.1:52996/Users/yuanzhiying/Desktop/app_analytics_sdk_flutter?authToken=zbeBO82KY54%3D瀏覽器開啟,根據提示或具體情況處理程式碼。

image.png

工具給推薦了預設的處理方法,點選程式碼,可以看到右側Proposed Edits裡有具體的說明。在遷移工具的 Edit Details 窗格中,你可以通過 Add /*?*/ hintAdd /*!*/ hint 按鈕來新增提示標記。

按下這些按鈕,相應的標記會立刻新增到程式碼中,並且 無法撤銷。如果你想刪除標記,可以和平常一樣使用程式碼編輯器刪除它。

就算遷移工具正在執行,你也可以使用編輯器新增提示標記。由於你的程式碼還未遷移到空安全,所以無法使用空安全的新特性。但是你可以進行與空安全無關的改動,例如重構。

當你完成編輯後,點選 Rerun from sources 進行更改。

image.png

⑥ 只進行部分檔案的遷移

儘管我們希望你能一次性完成遷移工作,但對於大體量的應用或 package 而言並不是簡單的事。如果你想只遷移部分檔案,請將暫時不遷移的檔案前方的綠色勾選框取消勾選。稍後應用遷移更改時,這些檔案會加上 Dart 2.9 [版本註釋][version comment],其他內容保持不變。

更多有關漸進遷移空安全的內容,請閱讀 非健全的空安全

⑦ 處理完之後,再次執行dart migrate
$ dart migrate
fvm: running Dart from Flutter "stable"

Migrating /Users/yuanzhiying/Desktop/app_analytics_sdk_flutter

See https://dart.dev/go/null-safety-migration for a migration guide.

Note: more than one project found; migrating the top-level project.

Analyzing project...
All sources appear to be already migrated.  Nothing to do.
複製程式碼
9、遷移完成

非健全的空安全

一個 Dart 程式可以同時包含已經是 空安全 和未遷移至空安全的庫。這些 混合模式的程式 會執行在 非健全的空安全 下。

為了在保持與傳統庫執行時的相容性的同時,能為健全的空安全程式提供健全性, Dart 工具提供了以下兩種模式的支援:

  • 以 非健全的空安全 執行的混合模式的程式。在執行時有可能出現 null 引用錯誤,但這只是因為一些 null 值和可空型別在非空安全的庫中汙染了空安全的程式碼。
  • 當程式完全遷移至空安全,且它所依賴的庫 全部 都遷移完成後,它就在以 健全的空安全 執行,擁有所有由健全性帶來的保證和編譯優化。
逐步遷移

因為 Dart 支援混合模式的空安全,所以你可以一個個遷移你的庫(通常是一個檔案),同時能正常執行程式和測試。 我們推薦你 優先遷移最下層的庫 —— 指的是沒有匯入其他包的庫。接著遷移直接依賴了下層庫的依賴庫。最後再遷移依賴項最多的庫。 舉個例子,假設你的 lib/src/util.dart 匯入了其他(空安全)的軟體包和核心庫,但它沒有包含任何 import '<本地路徑>' 的引用。那麼你應當優先考慮遷移 util.dart,然後遷移依賴了 util.dart 的檔案。如果有一些迴圈引用的庫(例如 A 引用了 BB 引用了 CC 引用了 A),建議同時對它們進行遷移。

使用遷移工具

你可以使用 遷移工具 進行漸進遷移。如果你需要排除部分檔案或資料夾,勾選綠色的勾選框。下方的截圖中,bin 資料夾的所有檔案都已被排除。

image.png

每個不遷移的檔案都會加上 2.9 語言版本的註釋。你可以之後再次執行 dart migrate 繼續遷移。已遷移的檔案將顯示為禁用的勾選框,它們無法撤銷遷移更改。

測試或執行混合版本的程式

想要測試或執行混合版本的程式碼,你需要禁用健全的空安全。有兩種方式可以進行操作:

  • dartflutter 命令裡,加入 --no-sound-null-safety 標記禁用。例如:
$ dart --no-sound-null-safety run
$ flutter run --no-sound-null-safety
複製程式碼
  • 或者,設定程式入口的語言版本 —— 包含 main() 函式的檔案 —— 設定為 2.9。在 Flutter 應用中,一般是 lib/main.dart。在命令列應用中,一般是 bin/<package 名稱>.dart。同時你也可以設定test下的檔案,因為它們也包含程式入口。例如
// @dart=2.9
import 'src/my_app.dart';

main() {
  //...
}
複製程式碼

以上兩種方式的規避,對於 正在 增量遷移的過程非常有用,但這樣做意味著你並未在完全啟用空安全的情況下測試你的程式碼。當你完成增量遷移後,也請記得將測試程式碼 重新 遷移至空安全。

相關文章