Guide de mise a jour
Nouveautes de la v7
Nylo Website v7 est une version majeure avec des ameliorations significatives de l'experience developpeur :
Configuration d'environnement chiffree
- Les variables d'environnement sont desormais chiffrees en XOR au moment de la compilation pour plus de securite
- Nouvelle commande
metro make:keypour generer votre APP_KEY - Nouvelle commande
metro make:envpour generer le fichierenv.g.dartchiffre - Prise en charge de l'injection de APP_KEY via
--dart-definepour les pipelines CI/CD
Processus de demarrage simplifie
- Le nouveau modele
BootConfigremplace les callbacks setup/finished separes - Syntaxe plus claire pour
Nylo.init()avec le parametreenvpour l'environnement chiffre - Hooks du cycle de vie de l'application directement dans main.dart
Nouvelle API nylo.configure()
- Une methode unique consolide toute la configuration de l'application
- Syntaxe plus claire remplacant les appels individuels
nylo.add*() - Methodes de cycle de vie
setup()etboot()separees dans les providers
NyPage pour les pages
NyPageremplaceNyStatepour les widgets de page (syntaxe plus claire)view()remplace la methodebuild()- Le getter
get init =>remplace les methodesinit()etboot() NyStatereste disponible pour les widgets stateful qui ne sont pas des pages
Systeme LoadingStyle
- Nouvelle enumeration
LoadingStylepour des etats de chargement coherents - Options :
LoadingStyle.normal(),LoadingStyle.skeletonizer(),LoadingStyle.none() - Widgets de chargement personnalises via
LoadingStyle.normal(child: ...)
Routage type-safe avec RouteView
static RouteView pathremplacestatic const path- Definitions de routes type-safe avec factory de widget
Support multi-themes
- Enregistrement de plusieurs themes sombres et clairs
- Identifiants de theme definis dans le code au lieu du fichier
.env - Nouveaux
NyThemeType.dark/NyThemeType.lightpour la classification des themes - API de theme prefere :
NyTheme.setPreferredDark(),NyTheme.setPreferredLight() - Enumeration des themes :
NyTheme.lightThemes(),NyTheme.darkThemes(),NyTheme.all()
Nouvelles commandes Metro
make:key- Generer APP_KEY pour le chiffrementmake:env- Generer le fichier d'environnement chiffremake:bottom_sheet_modal- Creer des modales en feuille de fondmake:button- Creer des boutons personnalises
Voir tous les changements sur GitHub
Apercu des changements majeurs
| Changement | v6 | v7 |
|---|---|---|
| Widget racine de l'application | LocalizedApp(child: Main(nylo)) |
Main(nylo) (utilise NyApp.materialApp()) |
| Classe d'etat de page | NyState |
NyPage pour les pages |
| Methode view | build() |
view() |
| Methode init | init() async {} / boot() async {} |
get init => () async {} |
| Chemin de route | static const path = '/home' |
static RouteView path = ('/home', (_) => HomePage()) |
| Boot du provider | boot(Nylo nylo) |
setup(Nylo nylo) + boot(Nylo nylo) |
| Configuration | Appels individuels nylo.add*() |
Appel unique nylo.configure() |
| IDs de theme | Fichier .env (LIGHT_THEME_ID, DARK_THEME_ID) |
Code (type: NyThemeType.dark) |
| Widget de chargement | useSkeletonizer + loading() |
Getter LoadingStyle |
| Emplacement config | lib/config/ |
lib/bootstrap/ (decoders, events, providers, theme) |
| Emplacement ressources | public/ |
assets/ |
Approche de migration recommandee
Pour les projets plus importants, nous vous recommandons de creer un nouveau projet v7 et de migrer les fichiers :
- Creer un nouveau projet v7 :
git clone https://github.com/nylo-core/nylo.git my_app_v7 -b 7.x - Copier vos pages, controllers, models et services
- Mettre a jour la syntaxe comme indique ci-dessus
- Tester minutieusement
Ceci vous assure d'avoir toute la derniere structure de boilerplate et les configurations.
Si vous souhaitez voir un diff des changements entre v6 et v7, vous pouvez consulter la comparaison sur GitHub : https://github.com/nylo-core/nylo/compare/6.x...7.x
Liste de verification rapide pour la migration
Utilisez cette liste de verification pour suivre votre progression de migration :
- Mettre a jour
pubspec.yaml(Dart >=3.10.7, Flutter >=3.24.0, nylo_framework: ^7.0.0) - Executer
flutter pub get - Executer
metro make:keypour generer APP_KEY - Executer
metro make:envpour generer l'environnement chiffre - Mettre a jour
main.dartavec le parametre env et BootConfig - Convertir la classe
Bootpour utiliser le modeleBootConfig - Deplacer les fichiers de configuration de
lib/config/verslib/bootstrap/ - Creer les nouveaux fichiers de configuration (
lib/config/app.dart,lib/config/storage_keys.dart,lib/config/toast_notification.dart) - Mettre a jour
AppProviderpour utilisernylo.configure() - Supprimer
LIGHT_THEME_IDetDARK_THEME_IDdu fichier.env - Ajouter
type: NyThemeType.darkaux configurations de themes sombres - Renommer
NyStateenNyPagepour tous les widgets de page - Changer
build()enview()dans toutes les pages - Changer
init()/boot()enget init =>dans toutes les pages - Mettre a jour
static const pathenstatic RouteView path - Changer
router.route()enrouter.add()dans les routes - Renommer les widgets (NyListView -> CollectionView, etc.)
- Deplacer les ressources de
public/versassets/ - Mettre a jour les chemins des ressources dans
pubspec.yaml - Supprimer les imports Firebase (si utilises - ajoutez les packages directement)
- Supprimer l'utilisation de NyDevPanel (utilisez Flutter DevTools)
- Executer
flutter pub getet tester
Guide de migration etape par etape
Etape 1 : Mise a jour des dependances
Mettez a jour votre pubspec.yaml :
environment:
sdk: '>=3.10.7 <4.0.0'
flutter: ">=3.24.0"
dependencies:
nylo_framework: ^7.0.0
# ... autres dependances
Executez flutter pub get pour mettre a jour les packages.
Etape 2 : Configuration de l'environnement
La v7 necessite des variables d'environnement chiffrees pour une securite amelioree.
1. Generer APP_KEY :
metro make:key
Ceci ajoute APP_KEY a votre fichier .env.
2. Generer env.g.dart chiffre :
metro make:env
Ceci cree lib/bootstrap/env.g.dart contenant vos variables d'environnement chiffrees.
3. Supprimer les variables de theme obsoletes du fichier .env :
# Supprimez ces lignes de votre fichier .env :
LIGHT_THEME_ID=...
DARK_THEME_ID=...
Etape 3 : Mise a jour de main.dart
v6 :
import 'package:nylo_framework/nylo_framework.dart';
import 'bootstrap/boot.dart';
void main() async {
await Nylo.init(
setup: Boot.nylo,
setupFinished: Boot.finished,
);
}
v7 :
import '/bootstrap/env.g.dart';
import 'package:nylo_framework/nylo_framework.dart';
import 'bootstrap/boot.dart';
void main() async {
await Nylo.init(
env: Env.get,
setup: Boot.nylo(),
appLifecycle: {
// Optionnel : Ajoutez des hooks du cycle de vie de l'application
// AppLifecycleState.resumed: () => print("App resumed"),
// AppLifecycleState.paused: () => print("App paused"),
},
);
}
Changements cles :
- Importer le fichier
env.g.dartgenere - Passer
Env.getau parametreenv Boot.nylodevientBoot.nylo()(retourneBootConfig)setupFinishedest supprime (gere dansBootConfig)- Hooks
appLifecycleoptionnels pour les changements d'etat de l'application
Etape 4 : Mise a jour de boot.dart
v6 :
class Boot {
static Future<Nylo> nylo() async {
WidgetsFlutterBinding.ensureInitialized();
if (getEnv('SHOW_SPLASH_SCREEN', defaultValue: false)) {
runApp(SplashScreen.app());
}
await _setup();
return await bootApplication(providers);
}
static Future<void> finished(Nylo nylo) async {
await bootFinished(nylo, providers);
runApp(Main(nylo));
}
}
v7 :
class Boot {
static BootConfig nylo() => BootConfig(
setup: () async {
WidgetsFlutterBinding.ensureInitialized();
if (AppConfig.showSplashScreen) {
runApp(SplashScreen.app());
}
await _init();
return await setupApplication(providers);
},
boot: (Nylo nylo) async {
await bootFinished(nylo, providers);
runApp(Main(nylo));
},
);
}
Changements cles :
- Retourne
BootConfigau lieu deFuture<Nylo> setupetfinishedcombines en un seul objetBootConfiggetEnv('SHOW_SPLASH_SCREEN')->AppConfig.showSplashScreenbootApplication->setupApplication
Etape 5 : Reorganisation des fichiers de configuration
La v7 reorganise les fichiers de configuration pour une meilleure structure :
| Emplacement v6 | Emplacement v7 | Action |
|---|---|---|
lib/config/decoders.dart |
lib/bootstrap/decoders.dart |
Deplacer |
lib/config/events.dart |
lib/bootstrap/events.dart |
Deplacer |
lib/config/providers.dart |
lib/bootstrap/providers.dart |
Deplacer |
lib/config/theme.dart |
lib/bootstrap/theme.dart |
Deplacer |
lib/config/keys.dart |
lib/config/storage_keys.dart |
Renommer et refactoriser |
| (nouveau) | lib/config/app.dart |
Creer |
| (nouveau) | lib/config/toast_notification.dart |
Creer |
Creer lib/config/app.dart :
Reference : App Config
class AppConfig {
// Le nom de l'application.
static final String appName = getEnv('APP_NAME', defaultValue: 'Nylo');
// La version de l'application.
static final String version = getEnv('APP_VERSION', defaultValue: '1.0.0');
// Ajoutez d'autres configurations d'application ici
}
Creer lib/config/storage_keys.dart :
Reference : Storage Keys
final class StorageKeysConfig {
// Definir les cles a synchroniser au demarrage
static syncedOnBoot() => () async {
return [
auth,
bearerToken,
// coins.defaultValue(10), // donner 10 coins par defaut a l'utilisateur
];
};
static StorageKey auth = 'SK_USER';
static StorageKey bearerToken = 'SK_BEARER_TOKEN';
// static StorageKey coins = 'SK_COINS';
/// Ajoutez vos cles de stockage ici...
}
Creer lib/config/toast_notification.dart :
Reference : Toast Notification Config
import 'package:nylo_framework/nylo_framework.dart';
class ToastNotificationConfig {
static Map<ToastNotificationStyleMetaHelper, ToastMeta> styles = {
// Personnalisez les styles de toast ici
};
}
Etape 6 : Mise a jour de AppProvider
v6 :
class AppProvider implements NyProvider {
@override
boot(Nylo nylo) async {
await NyLocalization.instance.init(
localeType: localeType,
languageCode: languageCode,
assetsDirectory: assetsDirectory,
);
nylo.addLoader(loader);
nylo.addLogo(logo);
nylo.addThemes(appThemes);
nylo.addToastNotification(getToastNotificationWidget);
nylo.addValidationRules(validationRules);
nylo.addModelDecoders(modelDecoders);
nylo.addControllers(controllers);
nylo.addApiDecoders(apiDecoders);
nylo.useErrorStack();
nylo.addAuthKey(Keys.auth);
await nylo.syncKeys(Keys.syncedOnBoot);
return nylo;
}
@override
afterBoot(Nylo nylo) async {}
}
v7 :
class AppProvider implements NyProvider {
@override
setup(Nylo nylo) async {
await nylo.configure(
localization: NyLocalizationConfig(
languageCode: LocalizationConfig.languageCode,
localeType: LocalizationConfig.localeType,
assetsDirectory: LocalizationConfig.assetsDirectory,
),
loader: DesignConfig.loader,
logo: DesignConfig.logo,
themes: appThemes,
initialThemeId: 'light_theme',
toastNotifications: ToastNotificationConfig.styles,
modelDecoders: modelDecoders,
controllers: controllers,
apiDecoders: apiDecoders,
authKey: StorageKeysConfig.auth,
syncKeys: StorageKeysConfig.syncedOnBoot,
useErrorStack: true,
);
return nylo;
}
@override
boot(Nylo nylo) async {}
}
Changements cles :
boot()devientsetup()pour la configuration initialeboot()est maintenant utilise pour la logique post-configuration (anciennementafterBoot)- Tous les appels
nylo.add*()consolides en un seulnylo.configure() - La localisation utilise l'objet
NyLocalizationConfig
Etape 7 : Mise a jour de la configuration des themes
v6 (fichier .env) :
LIGHT_THEME_ID=default_light_theme
DARK_THEME_ID=default_dark_theme
v6 (theme.dart) :
final List<BaseThemeConfig> appThemes = [
BaseThemeConfig(
id: getEnv('LIGHT_THEME_ID'),
description: "Light Theme",
theme: lightTheme(),
colors: LightThemeColors(),
),
BaseThemeConfig(
id: getEnv('DARK_THEME_ID'),
description: "Dark Theme",
theme: darkTheme(),
colors: DarkThemeColors(),
),
];
v7 (theme.dart) :
final List<BaseThemeConfig<ColorStyles>> appThemes = [
BaseThemeConfig<ColorStyles>(
id: 'light_theme',
theme: lightTheme,
colors: LightThemeColors(),
type: NyThemeType.light,
),
BaseThemeConfig<ColorStyles>(
id: 'dark_theme',
theme: darkTheme,
colors: DarkThemeColors(),
type: NyThemeType.dark,
),
];
Changements cles :
- Supprimer
LIGHT_THEME_IDetDARK_THEME_IDdu fichier.env - Definir les IDs de theme directement dans le code
- Ajouter
type: NyThemeType.darka toutes les configurations de themes sombres - Les themes clairs utilisent par defaut
NyThemeType.light
Nouvelles methodes de l'API Theme (v7) :
// Definir et memoriser le theme prefere
NyTheme.set(context, id: 'dark_theme', remember: true);
// Definir les themes preferes pour suivre le systeme
NyTheme.setPreferredDark('dark_theme');
NyTheme.setPreferredLight('light_theme');
// Obtenir les IDs des themes preferes
String? darkId = NyTheme.preferredDarkId();
String? lightId = NyTheme.preferredLightId();
// Enumeration des themes
List<BaseThemeConfig> lights = NyTheme.lightThemes();
List<BaseThemeConfig> darks = NyTheme.darkThemes();
List<BaseThemeConfig> all = NyTheme.all();
BaseThemeConfig? theme = NyTheme.getById('dark_theme');
List<BaseThemeConfig> byType = NyTheme.getByType(NyThemeType.dark);
// Effacer les preferences sauvegardees
NyTheme.clearSavedTheme();
Etape 10 : Migration des widgets
NyListView -> CollectionView
v6 :
NyListView(
child: (context, data) {
return ListTile(title: Text(data.name));
},
data: () async => await api.getUsers(),
loading: CircularProgressIndicator(),
)
v7 :
CollectionView<User>(
data: () async => await api.getUsers(),
builder: (context, item) => ListTile(
title: Text(item.data.name),
),
loadingStyle: LoadingStyle.normal(),
)
// Avec pagination (tirer pour actualiser) :
CollectionView<User>.pullable(
data: (page) async => await api.getUsers(page: page),
builder: (context, item) => ListTile(
title: Text(item.data.name),
),
)
NyFutureBuilder -> FutureWidget
v6 :
NyFutureBuilder(
future: fetchData(),
child: (context, data) => Text(data),
loading: CircularProgressIndicator(),
)
v7 :
FutureWidget<String>(
future: fetchData(),
child: (context, data) => Text(data ?? ''),
loadingStyle: LoadingStyle.normal(),
)
NyTextField -> InputField
v6 :
NyTextField(
controller: _controller,
validationRules: "not_empty|email",
)
v7 :
InputField(
controller: _controller,
formValidator: FormValidator
.notEmpty()
.email(),
),
NyRichText -> StyledText
v6 :
NyRichText(children: [
Text("Hello", style: TextStyle(color: Colors.yellow)),
Text(" WORLD ", style: TextStyle(color: Colors.blue)),
Text("!", style: TextStyle(color: Colors.red)),
]),
v7 :
StyledText.template(
"{{Hello}} {{WORLD}}{{!}}",
styles: {
"Hello": TextStyle(color: Colors.yellow),
"WORLD": TextStyle(color: Colors.blue),
"!": TextStyle(color: Colors.red),
},
)
NyLanguageSwitcher -> LanguageSwitcher
v6 :
NyLanguageSwitcher(
onLanguageChange: (locale) => print(locale),
)
v7 :
LanguageSwitcher(
onLanguageChange: (locale) => print(locale),
)
Etape 11 : Mise a jour des chemins des ressources
La v7 change le repertoire des ressources de public/ a assets/ :
1. Deplacez vos dossiers de ressources :
# Deplacer les repertoires
mv public/fonts assets/fonts
mv public/images assets/images
mv public/app_icon assets/app_icon
2. Mettez a jour pubspec.yaml :
v6 :
flutter:
assets:
- public/fonts/
- public/images/
- public/app_icon/
v7 :
flutter:
assets:
- assets/fonts/
- assets/images/
- assets/app_icon/
3. Mettez a jour toutes les references aux ressources dans le code :
v6 :
Image.asset('public/images/logo.png')
v7 :
Image.asset('assets/images/logo.png')
Widget LocalizedApp - Supprime
Reference : Main Widget
Migration : Utilisez Main(nylo) directement. Le NyApp.materialApp() gere la localisation en interne.
v6 :
runApp(LocalizedApp(child: Main(nylo)));
v7 :
runApp(Main(nylo));
Reference des classes supprimees
| Classe supprimee | Alternative |
|---|---|
NyTextStyle |
Utilisez le TextStyle de Flutter directement |
NyBaseApiService |
Utilisez DioApiService |
BaseColorStyles |
Utilisez ThemeColor |
LocalizedApp |
Utilisez Main(nylo) directement |
NyException |
Utilisez les exceptions Dart standard |
PushNotification |
Utilisez flutter_local_notifications directement |
PushNotificationAttachments |
Utilisez flutter_local_notifications directement |
Reference de migration des widgets
Widgets renommes
| Widget v6 | Widget v7 | Notes |
|---|---|---|
NyListView |
CollectionView |
Nouvelle API avec builder au lieu de child |
NyFutureBuilder |
FutureWidget |
Widget asynchrone simplifie |
NyTextField |
InputField |
Utilise FormValidator |
NyLanguageSwitcher |
LanguageSwitcher |
Meme API |
NyRichText |
StyledText |
Meme API |
NyFader |
FadeOverlay |
Meme API |
Widgets supprimes (pas de remplacement direct)
| Widget supprime | Alternative |
|---|---|
NyPullToRefresh |
Utilisez CollectionView.pullable() |
Exemples de migration de widgets
NyPullToRefresh -> CollectionView.pullable() :
v6 :
NyPullToRefresh(
child: (context, data) => ListTile(title: Text(data.name)),
data: (page) async => await fetchData(page),
)
v7 :
CollectionView<MyModel>.pullable(
data: (page) async => await fetchData(page),
builder: (context, item) => ListTile(title: Text(item.data.name)),
)
NyFader -> FadeOverlay :
v6 :
NyFader(
child: MyWidget(),
)
v7 :
FadeOverlay.bottom(
child: MyWidget(),
);
Depannage
"Env.get not found" ou "Env is not defined"
Solution : Executez les commandes de generation d'environnement :
metro make:key
metro make:env
Ensuite, importez le fichier genere dans main.dart :
import '/bootstrap/env.g.dart';
"Theme not applying" ou "Dark theme not working"
Solution : Assurez-vous que les themes sombres ont type: NyThemeType.dark :
BaseThemeConfig(
id: 'dark_theme',
description: "Dark Theme",
theme: darkTheme(),
colors: DarkThemeColors(),
type: NyThemeType.dark, // Ajoutez cette ligne
),
"LocalizedApp not found"
Reference : Main Widget
Solution : LocalizedApp a ete supprime. Changez :
// De :
runApp(LocalizedApp(child: Main(nylo)));
// A :
runApp(Main(nylo));
"router.route is not defined"
Solution : Utilisez router.add() a la place :
// De :
router.route(HomePage.path, (context) => HomePage());
// A :
router.add(HomePage.path);
"NyListView not found"
Solution : NyListView est maintenant CollectionView :
// De :
NyListView(...)
// A :
CollectionView<MyModel>(...)
Les ressources ne se chargent pas (images, polices)
Solution : Mettez a jour les chemins des ressources de public/ a assets/ :
- Deplacez les fichiers :
mv public/* assets/ - Mettez a jour les chemins dans
pubspec.yaml - Mettez a jour les references dans le code
"init() must return a value of type Future"
Solution : Changez vers la syntaxe getter :
// De :
@override
init() async { ... }
// A :
@override
get init => () async { ... };
Besoin d'aide ? Consultez la Documentation Nylo ou ouvrez une issue sur GitHub.