【文章翻譯】Announcing Dart 3.13

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

原文:https://dart.dev/blog/announcing-dart-3-13

隆重推出 Dart 3.13

讓 Dart 程式碼庫、工具和平台更加簡潔易用。

Connie Ooi ・ 2026 年 8 月 12 日 ・ 閱讀時間 9 分鐘

Dart 3.13 release banner animation with the Dart logo.
隆重推出 Dart 3.13

我們很高興地宣布 Dart 3.13!

在此版本中,我們慶祝每個開發者都喜歡的主題:簡潔輕巧的程式碼。Dart 3.13 將此重點帶入開發者體驗的每個層面。在語言方面,主要建構函數消除了重複的樣板程式碼,因此您可以在一行程式碼中定義類別。在開發者工具中,dart format 的改進讓您的程式碼根據 Effective Dart 風格規則 保持整潔,而 dart pub 引入了新的工作區命令,以保持 monorepos 的整潔。在 pub.dev 上,更豐富的文件功能,如 <callout-box> 標籤和 {@example} 指令,使套件文件更易於閱讀。在幕後,原生函式庫樹狀結構刪除 (@RecordUse) 和 WebAssembly 延遲載入有助於讓您的編譯應用程式二進位檔盡可能緊湊。

因此,更新 Dart 或運行 flutter upgrade 並跟隨我們探索 Dart 3.13 中的新功能!

語言更新

主要建構函式

繼 Dart 3.12 的實驗性預覽之後,主要建構函式現在在 Dart 3.13 中正式穩定!

主要建構函式是類別簡潔性方面的一大進步。我們從開發人員那裡聽說,在類別主體和參數列表中重複欄位名稱和類型可能會感到乏味。主要建構函式消除了這種重複,讓您可以在一行程式碼中定義,例如,一個具有兩個欄位和一個建構函式的 Point 類別:

1
class Point(final int x, final int y);

此功能還包括使用 newfactory 關鍵字的 建構函式簡潔語法,允許空宣告主體以 ; 結尾。

為了幫助您採用主要建構函式並在整個程式碼庫中保持一致的風格,我們引入了幾個新的 lint,並帶有自動修復功能:

除了這些 lint 之外,我們還添加了新的 IDE 重構功能來自動化您的程式碼遷移:

  • 轉換為主要建構函式:將合格的內部建構函式轉換為主要建構函式。
  • 轉換為內部建構函式:將主要建構函式轉換為內部建構函式。
  • 轉換為宣告參數:將主要建構函式中的非宣告參數轉換為宣告參數。
  • 將初始化移至欄位宣告:將欄位初始化從建構函式初始化列表移至欄位宣告。

了解更多: 主要建構函式文件

網路平台更新

WebAssembly 延遲載入預覽

我們一直在努力擴展 Dart 在網路上的 WebAssembly 功能。在 Dart 3.13 中,我們很高興地分享使用 dart2wasm 編譯時對延遲載入支援的早期預覽。您今天可以使用實驗性編譯器標誌啟用它:

1
dart compile wasm -O2 --enable-deferred-loading

在採用延遲載入的大型應用程式中,dart2wasmdart2js 相比,可以顯著改善初始頁面載入 (IPL) 時間,這對 Flutter 網頁應用程式和基於 DOM 的網頁應用程式都有益。

提醒一下,dart:htmlpackage:js 等舊版網頁函式庫在 dart2wasm 中不受支援,並在 Dart 3.7 中已棄用(將來在 dart2js 中也將停止工作)。許多套件已經遷移,因此升級您的套件相依性通常會自動解決問題。但是,如果您的程式碼直接使用這些舊版函式庫,請查看我們的遷移指南以立即採用支援的 dart:js_interoppackage:web 函式庫。

了解更多: WebAssembly 文件

核心引擎和運行時更新

工程亮點

除了我們的 Web 平台進展之外,我們的團隊還在不斷改進 Dart 的基礎。以下是我們過去三個月在幕後工作的一些亮點:

  • 類型提升健全性修復:修復了涉及巢狀函式的類型提升的 罕見不健全性 問題。
  • 通用前端重構:重構了內部通用前端元件,以實現與 Dart 分析器更大的程式碼共享。
  • DDC 模組系統統一:繼續從 Dart 開發編譯器 (DDC) 的工具中移除舊版模組系統,以建立單一、統一的模組系統。
  • 原生運行時記憶體安全:透過在 Dart 堆周圍引入記憶體籠,增強了原生運行時記憶體安全。
  • 動態模組連結:開始實驗 動態模組 以實現動態程式碼連結,為改進開發工作流程鋪平道路,例如團隊內部的快速原型共享。

工具更新

Dart 格式化程式

保持程式碼庫整潔易讀是 dart format 的首要任務。在 Dart 3.13 中,我們引入了一些樣式調整,以使格式化的程式碼更加簡潔。雖然大多數更改都是微小的,但一些關鍵更新將使您的日常程式碼明顯更容易閱讀:

  • 方法調用格式錯誤修復:我們修復了一個錯誤,其中一個優化有時會錯誤地啟動並導致程式碼格式錯誤。它主要出現在包含大型集合常量的方​​法調用周圍:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Before:
await MethodChannelContainer()
.onMethodChannelInvoke('reportCrash', <String, Object?>{
'time': nowTime,
'errorValue': errorName,
'reason': reason,
'stacktrace': stacktrace,
});

// After:
await MethodChannelContainer().onMethodChannelInvoke(
'reportCrash',
<String, Object?>{
'time': nowTime,
'errorValue': errorName,
'reason': reason,
'stacktrace': stacktrace,
},
);
  • 方法鏈分割啟發式:我們更改了格式化程式決定是在 . 處分割方法調用鏈還是分割其中一個參數列表的啟發式。如果方法鏈的目標是具有單個元素或參數的集合文字或函式調用,它現在更傾向於分割調用鏈而不是目標:
1
2
3
4
5
6
7
8
9
// Before, split the target:
function(
argument,
).method().another();

// After, split the chain:
function(argument)
.method()
.another();
  • 導入區段分離:格式化程式現在會在一系列導入中不同「區段」之間插入一個空行。格式化程式不會對導入進行排序,但它現在會根據 Effective Dart 中的規則 將它們分開:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Before:
import 'dart:io';
import 'dart:math';
import 'package:args/args.dart';
import 'package:test/test.dart';
import 'my_library.dart';

// After:
import 'dart:io';
import 'dart:math';

import 'package:args/args.dart';
import 'package:test/test.dart';

import 'my_library.dart';

dart_style 變更日誌 中描述了一些其他樣式調整,但這些是最明顯的。我們知道格式化更改可能會導致令人煩惱的變動,因此我們在更改樣式時會盡量保守。同時,樣式改進可以使程式碼更容易閱讀,這在我們由於生成式 AI 而審查比以往更多程式碼的時代,是一個寶貴的優勢。除了優化錯誤修復之外,這些樣式更改是 語言版本化 的。您只有在將程式碼升級到 Dart 3.13 後才能看到它們。

了解更多: Dart 格式化程式文件

Pub 更新

套件文件更新

清晰且結構良好的套件文件對於健康的生態系統至關重要。為了幫助套件作者建立更簡潔、更易於維護的文件,pub.dev 現在支援 &lt;callout-box&gt; 標籤和 {@example} 指令的端到端。您可以將程式碼片段直接從範例檔案中提取到您的 API 文件中,同時隱藏不必要的樣板程式碼。

例如,在 example/foo.dart 中定義一個片段區域:

1
2
3
4
5
6
7
8
// example/foo.dart
void main() {
// #region abc
// Included in documentation
foo();
assert(false); // #hide
// #endregion
}

然後在您的 Dart 文件註釋中引用該區域:

1
2
3
4
5
/// This is a great function.
///
/// Example usage:
/// {@example /example/foo.dart#abc}
void foo() {}

pub.dev 直接在生成的文檔中呈現指定的程式碼區域。

The cupertino_ui documentation on pub.dev displaying a 'callout-box' element with a blue border alongside an embedded '{@example}' code block.
pub.dev 上的 `cupertino_ui` 文件顯示了一個帶藍色邊框的 `<callout-box>` 元素,以及一個嵌入的 `{@example}` 程式碼塊。

在幕後,pub.dev 還為 dartdoc 檔案查詢部署了兩級哈希索引。此更新大幅加快了包含 10 萬多個生成檔案的大型套件的文件渲染速度。

Chart showing Docs Request Latency drop after deploying the new blob index.
部署新的 Blob 索引後,文件請求延遲降低。

了解更多: CupertinoActivityIndicator 類別文件

原生互操作更新

使用 @RecordUsepackage:record_use 進行原生函式庫樹狀結構刪除

我們對效率的承諾一直延伸到您編譯的應用程式二進位檔案。當使用 dart:ffi 和 Code Assets 構建與原生 C、C++ 或 Rust 程式碼互操作的 Dart 和 Flutter 應用程式時,Dart 編譯器始終會樹狀結構刪除未使用的 Dart 包裝函式。然而,底層的原生二進位檔案傳統上是完整捆綁的。

有了 @RecordUse (在 package:meta 中) 和 package:record_use,Dart 和 Flutter 現在可以像處理 Dart 程式碼一樣對原生函式庫進行樹狀結構刪除。這確保您的最終應用程式捆綁包只包含您的應用程式實際調用的原生程式碼。

運作方式

  1. 使用 @RecordUse() 標註原生 FFI 綁定:使用 @RecordUse() 註釋標記您的原生 FFI 綁定 (例如由 ffigen 生成的綁定):
1
2
3
4
5
6
7
8
9
10
11
12
13
import 'dart:ffi';
import 'package:meta/meta.dart';

@RecordUse()
@Native<Int32 Function(Int32, Int32)>()
external int sqlite3_open(
Pointer<Utf8> filename,
Pointer<Pointer<sqlite3>> ppDb,
);

@RecordUse()
@Native<Int32 Function(Pointer<sqlite3>)>()
external int sqlite3_close(Pointer<sqlite3> db);
  1. 在編譯期間追蹤可達的呼叫:在 Dart AOT 建置的整個程式編譯和樹狀結構刪除期間,編譯器會追蹤在可執行程式碼中哪些帶有 @RecordUse() 註釋的綁定是可達的。位於未使用的 Dart 程式碼中且被樹狀結構刪除的呼叫會自動排除。

  2. 在您的連結掛鉤中修剪未使用的原生符號:在您的套件的連結掛鉤 (hook/link.dart) 中,檢索 input.recordedUses。使用 package:record_use,查詢已記錄的呼叫,並指示您的原生工具鏈 (例如 package:native_toolchain_c 或 Rust 建置腳本) 只保留 Dart 實際呼叫的符號:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import 'package:hooks/hooks.dart';
import 'package:native_toolchain_c/native_toolchain_c.dart';
import 'package:record_use/record_use.dart';
import 'package:my_package/src/c_library.dart';
import 'package:my_package/src/record_use_mapping.dart';

void main(List<String> arguments) async {
await link(arguments, (input, output) async {
// Extract symbols for functions called in reachable Dart code:
final symbolsToKeep = input.recordedUses?.calls.keys
.cast<Method>()
.map((method) => recordUseMapping[method.name]!);

await cLibrary.link(
input: input,
output: output,
linkerOptions: LinkerOptions.treeshake(
symbolsToKeep: symbolsToKeep,
),
);
});
}

為何這很重要

  • 大幅縮小二進位檔案:SQLite、密碼學、影像解碼器或音訊引擎等重量級原生相依性公開了數百個函式。在發行版本建置期間,連結器會刪除未引用的原生程式碼、無用的物件檔案和未使用的匯出。
  • 完全省略未使用的原生函式庫:如果您的應用程式從不調用套件的原生綁定,連結掛鉤會將原生二進位檔案從最終應用程式捆綁包中完全刪除。
  • 無縫工具整合ffigen 等工具會自動標註生成的綁定,而 package:native_toolchain_c 則直接與連結掛鉤整合,以實現端到端原生樹狀結構刪除。

了解更多: 原生連結掛鉤文件紀錄使用文件

總結

Dart 3.13 實現了我們對更簡單、更簡潔的開發者體驗的願景。透過將主要建構函式等表達性語言功能與更智慧的工具、更豐富的 pub.dev 文件和緊湊的原生樹狀結構刪除相結合,此版本可幫助您專注於最重要的事情:建置出色的應用程式。

此版本中的所有內容都來自您的實際洞察力、錯誤報告和套件貢獻。Dart 生態系統因您的積極參與而蓬勃發展,我們非常感謝您在塑造語言未來方面的合作。

我們迫不及待想看看您用 Dart 3.13 創造了什麼!立即花點時間 更新 Dart 或運行 flutter upgrade,並在我們的 GitHub 議題追蹤器 上加入對話。感謝您成為如此熱情的社群並與我們一起建立 Dart 的未來!

了解更多: Dart SDK 變更日誌

更多來自 Dart 的消息

隆重推出 Dart 3.12

Announcing Dart 3.12

Google I/O 2026 大幅提升開發人員生產力
Connie Ooi ・ 2026 年 5 月 20 日 ・ 閱讀時間 7 分鐘

隆重推出 Dart 3.11

Announcing Dart 3.11

各位 Dart 開發人員您好!最新的穩定版本 Dart 3.11 正式發布!
Connie Ooi ・ 2026 年 2 月 11 日 ・ 閱讀時間 3 分鐘