Ce document présente toutes les fonctionnalités et améliorations majeures apparues dans Dart entre les versions 3.5 (août 2024) et 3.8 (mai 2025).
La fonctionnalité principale de Dart 3.6 est l'introduction des séparateurs de chiffres pour améliorer la lisibilité des nombres.
// Configuration requise dans pubspec.yaml
// sdk: '>=3.6.0'
// Exemples d'utilisation des séparateurs de chiffres
void main() {
// Nombres décimaux
const population = 8_000_000_000; // 8 milliards
const budget = 1_234_567_890.50;
// Notation hexadécimale
const memoryAddress = 0x00FF_00FF_00FF;
const macAddress = 0x00_14_22_01_23_45;
// Notation scientifique
const avogadro = 6.022_140_76e23;
const planck = 6.626_070_15e-34;
// Nombres binaires
const flags = 0b1010_0011_1100_0101;
print('Population mondiale: $population');
print('Adresse mémoire: ${memoryAddress.toRadixString(16)}');
}
// Note: Les séparateurs ne peuvent pas être utilisés:
// - Au début ou à la fin d'un nombre
// - Adjacent à d'autres caractères (., x, e)
// Invalide: _100, 100_, 1_.5, 0x_FFSupport amélioré pour les références dans les commentaires de documentation.
/// Cette classe utilise [Future] et [Stream] pour les opérations async.
///
/// Voir aussi:
/// - [Future.value] pour créer une Future résolue
/// - [Stream.periodic] pour créer un Stream périodique
class AsyncProcessor {
/// Traite les données de manière asynchrone
Future<String> processData(Stream<int> input) async {
// Implementation
return 'Processed';
}
}Nouvelle fonctionnalité pour gérer plusieurs packages dans un même repository.
# Fichier pubspec.yaml à la racine du workspace
name: my_workspace
workspace:
- packages/core
- packages/ui
- packages/data
# Chaque sous-package a son propre pubspec.yaml
# mais partage la résolution des dépendances# Force l'utilisation exacte du lockfile
dart pub get --enforce-lockfile
# Utile pour les builds reproductibles et CI/CDIntroduction des variables wildcard (non-liantes) avec le caractère _.
// Les variables wildcard peuvent être déclarées plusieurs fois
void processData(List<String> items) {
// Ignorer certaines valeurs dans un pattern matching
for (var (_, second, _) in getTriples()) {
print('Second element: $second');
}
// Multiple déclarations sans collision
var _ = computeExpensiveValue1(); // Ignoré
var _ = computeExpensiveValue2(); // Ignoré aussi
var _ = computeExpensiveValue3(); // Pas de conflit
// Utile dans les callbacks où on ignore certains paramètres
items.forEach((_, index) {
print('Index: $index');
});
}
// Pattern matching avec wildcards
String describePoint(Object point) {
return switch (point) {
(int x, int _) when x > 0 => 'Point sur l'axe X positif',
(int _, int y) when y > 0 => 'Point sur l'axe Y positif',
(int _, int _) => 'Point à l'origine ou ailleurs',
_ => 'Pas un point valide',
};
}
// Records avec wildcards
(String, int, bool) getUserInfo() => ('Alice', 25, true);
void main() {
var (name, _, _) = getUserInfo(); // On ne garde que le nom
print('User: $name');
}Le formateur a été largement réécrit pour supporter un nouveau style "tall".
// Avant Dart 3.7 (nécessitait des virgules manuelles)
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16),
child: Column(children: [
Text('Title'),
Text('Subtitle'),
ElevatedButton(onPressed: () {}, child: Text('Click'))
]));
}
// Avec Dart 3.7 - Le formateur ajoute/enlève automatiquement les virgules
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16),
child: Column(
children: [
Text('Title'),
Text('Subtitle'),
ElevatedButton(
onPressed: () {},
child: Text('Click'),
),
],
),
);
}
// Le formateur est maintenant lié à la version du langage
// Pour forcer le nouveau style:
// dart format --language-version=3.7 .// Nouveau lint: unnecessary_underscores
void example() {
// ⚠️ Avertissement: underscore inutile pour une variable utilisée
var _localVar = 42;
print(_localVar); // La variable est utilisée, pas besoin de _
// ✅ Correct: wildcard pour ignorer
var _ = expensiveComputation();
// ✅ Correct: variable privée de classe
class MyClass {
final int _privateField = 10;
}
}
// Quick fix pour ajouter await manquant
Future<void> process() async {
getData(); // ⚠️ Quick fix: Add 'await'
// Devient: await getData();
}
// Conversion de else en else if
if (condition1) {
// ...
} else { // Quick fix disponible
if (condition2) {
// ...
}
}
// Devient: else if (condition2) { ... }// Les packages affichent maintenant:
// - Téléchargements mensuels
// - Graphique des téléchargements hebdomadaires
// - Téléchargements par version du package
// Utile pour évaluer la popularité et l'adoption
// des différentes versions d'un packageLa fonctionnalité workspaces devient stable pour gérer les monorepos.
# Structure d'un workspace
# /racine/pubspec.yaml
name: my_monorepo
environment:
sdk: ^3.8.0
workspace:
- packages/core
- packages/ui
- packages/data
- apps/mobile
- apps/web
# Avantages:
# - Résolution unique des dépendances
# - Meilleure performance de l'analyzer
# - Gestion simplifiée des versions// Les packages du workspace peuvent se référencer entre eux
// packages/ui/lib/widgets.dart
import 'package:core/models.dart';
import 'package:data/repositories.dart';
class UserWidget extends StatelessWidget {
final UserRepository repo; // Depuis package:data
final User user; // Depuis package:core
// ...
}Nouvelle syntaxe pour référencer des éléments externes dans la documentation sans les importer.
/// @docImport 'dart:async';
/// @docImport 'package:http/http.dart' as http;
library my_library;
/// Cette fonction retourne un [Future] qui se résout avec
/// le résultat d'une requête HTTP.
///
/// Utilise [http.Client] pour effectuer la requête.
/// En cas d'erreur, retourne [Future.error].
///
/// Exemple:
/// ```dart
/// final result = await fetchData();
/// ```
Future<String> fetchData() async {
// Note: Future et http.Client sont référencés dans la doc
// sans avoir besoin d'importer dart:async ou package:http
return 'data';
}Nouvelle syntaxe ? pour insérer conditionnellement des éléments dans les collections.
void main() {
String? userName = getUserName(); // Peut être null
int? age = getAge(); // Peut être null
String? city;
// Liste avec éléments null-aware
var userInfo = [
'User Info',
?userName, // Ajouté seulement si non-null
?age?.toString(), // Converti et ajouté si non-null
?city, // Ignoré si null
];
// Résultat si userName="Alice", age=30, city=null:
// ['User Info', 'Alice', '30']
// Map avec entrées null-aware
var config = {
'debug': true,
?'username': userName, // Clé-valeur ajoutée si userName non-null
?'age': age,
?'city': city, // Entrée ignorée si city est null
};
// Set avec éléments null-aware
var tags = {
'required',
?optionalTag1,
?optionalTag2,
...?additionalTags, // Spread null-aware
};
}
// Utilisation avec des conditions complexes
List<Widget> buildWidgets({String? title, String? subtitle}) {
return [
?if (title != null) Text(title),
?if (subtitle != null) Text(subtitle, style: subtitleStyle),
?for (var item in items)
if (item.isVisible) Card(child: Text(item.name)),
];
}Support de la compilation croisée vers Linux x64 et ARM64.
# Compiler depuis macOS vers Linux x64
dart compile exe -t linux-x64 bin/server.dart
# Compiler depuis Windows vers Linux ARM64
dart compile exe -t linux-arm64 bin/app.dart
# Compilation native (comportement par défaut)
dart compile exe bin/app.dart
# Plateformes supportées:
# - Hôte: macOS, Windows, Linux (64-bit)
# - Cible: Linux x64, Linux ARM64# Nouvelle commande: dart pub bump
# Incrémente automatiquement la version du package
# Version actuelle: 1.2.3
dart pub bump patch # -> 1.2.4
dart pub bump minor # -> 1.3.0
dart pub bump major # -> 2.0.0
dart pub bump build # -> 1.2.3+1
# Exemple avec options
dart pub bump minor --dry-run # Aperçu sans modification
dart pub bump major --no-git-tag # Sans créer de tag git# Nouvel avertissement pour git status
dart pub publish
# ⚠️ Warning: Your git working tree is not clean.
# Consider committing or stashing your changes before publishing.
# Nouveau flag pour upgrade
dart pub upgrade --unlock-transitive
# Met à jour toutes les dépendances transitives
# au lieu de seulement les dépendances directes// Configuration pour activer le hot reload web
// Dans pubspec.yaml:
dev_dependencies:
webdev: ^3.0.0
// Lancer avec hot reload
// dart run webdev serve --hot-reload
// Le code Dart est injecté dans l'application
// sans recharger la page complète
void main() {
runApp(MyApp());
// Les changements dans MyApp sont appliqués
// instantanément pendant le développement
}// Nouvel assist: Ajouter/Retirer les séparateurs de chiffres
const value = 1000000; // Quick action: Add digit separators
// Devient: 1_000_000
const formatted = 1_000_000; // Quick action: Remove digit separators
// Devient: 1000000
// Nouvel assist: Inverser l'expression conditionnelle
if (isEnabled) {
doSomething();
} else {
doSomethingElse();
}
// Quick action: Invert conditional
// Devient:
if (!isEnabled) {
doSomethingElse();
} else {
doSomething();
}# pubspec.yaml
environment:
sdk: ^3.8.0 # Pour utiliser toutes les nouvelles fonctionnalités# Vérifier les dépréciations
dart analyze
# Appliquer les fixes automatiques
dart fix --apply
# Formater avec le nouveau style (3.7+)
dart format .
# Migrer vers package:web (depuis dart:html)
dart pub add web
dart fix --apply- Dart 3.5: Migrer de
dart:htmlverspackage:web - Dart 3.6: Adopter les séparateurs de chiffres pour les grandes constantes numériques
- Dart 3.7: Utiliser les variables wildcard et adopter le nouveau formatage
- Dart 3.8: Implémenter les workspaces pour les monorepos et utiliser les éléments null-aware
| Version | Fonctionnalité principale | Impact |
|---|---|---|
| 3.5 | Interopérabilité Web/Native | Migration de dart:html vers package:web |
| 3.6 | Séparateurs de chiffres | Meilleure lisibilité du code |
| 3.7 | Variables wildcard | Code plus expressif et concis |
| 3.8 | Workspaces & null-aware collections | Meilleure gestion des monorepos et collections |
Ces versions représentent une évolution significative de Dart, avec un focus sur l'interopérabilité, la productivité des développeurs, et la modernisation du langage. La migration est généralement simple grâce aux outils automatiques fournis.