Build customization
Flutter Montreal Meetup - January 2024
Slide 2
Slide 2 text
Nicolas Cuillery
Software developer
Has worked with:
- Flutter
- React Native
- React
- Angular.js
- Flex
- jQuery
- JSP
Slide 3
Slide 3 text
BASE1
eCommerce Services
Web and Mobile storefront
Slide 4
Slide 4 text
Cloud9
Slide 5
Slide 5 text
Cloud9 application
- Project started in February 2021
- Android and iOS
- Single codebase, multiple apps
- Currently in production in 10 countries
- 1M daily users
Slide 6
Slide 6 text
Multiple markets
- Phase 1: Japan and Australia
- Phase 2: Mexico, UK and New Zealand
- Phase 3: Korea and Taiwan
- Quarterly releases: France, Spain, Sweden, Iceland
Multiple flavors/configurations
Different builds from the same project.
Examples:
- Pricing model
- White-label app
- Beta version
- etc.
Slide 11
Slide 11 text
Non-prod applications
Country selector screen on startup
- Ease dev and QA workflow
- Faster CI build = faster feedback loop
- Cheaper CI
Slide 12
Slide 12 text
New market launch
Slide 13
Slide 13 text
New requirements
- Different dependencies for China
- Alternatives for the Firebase products:
- Remote Config
- Cloud Messaging
- Analytics
- …
Slide 14
Slide 14 text
Nice-to-have goals
- The unused deps are not compiled nor packaged in the app.
- no Firebase deps in the app for China
- no WeChat Pay in the UK build
- Dev and tester experience preserved
- “China” available in the country selector
- Minimal impact in the dev workflow
Slide 15
Slide 15 text
Arsenal: Layered Architecture 🚀
Separation between:
- Data
- Business Logic
- UI
More about that on:
https://www.reddit.com/r/FlutterDev/comments/192h8l0/comment/kh3sm2w/
Slide 16
Slide 16 text
Arsenal: Dependency injection
Heavy usage of GetIt https://pub.dev/packages/get_it
Slide 17
Slide 17 text
Arsenal: Dependency injection
Usage of “interface” (barely used)
Slide 18
Slide 18 text
Arsenal: Import tree-shaking
Successive imports are read from the entry-point: main.dart
Slide 19
Slide 19 text
- Centralize all the Firebase usage in one place (per Firebase Product)
- Abstraction layer between the Firebase SDK and its usages
- Specific main file for China, loading the non-Firebase implementation
Draft of a solution
Slide 20
Slide 20 text
Pre-china implementation
main.dart
Slide 21
Slide 21 text
initialization_helper.dart
Slide 22
Slide 22 text
address_search_bloc.dart
Slide 23
Slide 23 text
Step 1: Preparation
initialization_helper.dart
Slide 24
Slide 24 text
address_search_bloc.dart
Slide 25
Slide 25 text
No content
Slide 26
Slide 26 text
Step 2: Specific main file
main_china.dart
Slide 27
Slide 27 text
china_initialization_helper.dart
Slide 28
Slide 28 text
Less compiled code
https://stackoverflow.com/questions/52822353/how-to-test-debug-tree-shaking-in-flutter
Customers want guidance and docs for tree-shaking: https://github.com/dart-lang/sdk/issues/33920
Slide 29
Slide 29 text
Dev and tester experience preserved
Previously
(non-prod)
Entry point
initGlobalSingletons() {}
InitializationHelper
main() {} in main.dart
Country Selector
initCountrySingletons() {}
Home Page
InitializationHelper
Splash screen
setCountry() {} SettingsService
Slide 30
Slide 30 text
Now
(non-prod)
Entry point
initGlobalSingletons() {}
InitializationHelperImpl
main() {} in main.dart
Country Selector
initCountrySingletons() {}
Home Page
InitializationHelper
Splash screen
setCountry() {} SettingsService
initCountrySingletons() {} initCountrySingletons() {}
InitializationHelperChinaImpl InitializationHelperProdImpl
Slide 31
Slide 31 text
Strip Flutter plugins
- Native changes abstracted by Flutter
- Manual changes in the native files kept as minimal as possible
- pubspec.yaml is the main source of truth
Non-prod
Include all plugins (Firebase +
the alternatives)
China
Strip the Firebase plugins
Other countries
Strip the chinese dependencies
Slide 32
Slide 32 text
Flutter plugins
- iOS: Integration with cocoapods
- Android: Hook in the app/build.gradle
Slide 33
Slide 33 text
CI script
https://github.com/mikefarah/yq
Slide 34
Slide 34 text
Possible improvement #1
Slide 35
Slide 35 text
Possible improvement #2
From Flutter itself:
https://github.com/flutter/flutter/issues/46979
Slide 36
Slide 36 text
Native changes
Less hack-y because we are in the native world
Access to the flavor/configuration 🎉
Slide 37
Slide 37 text
Size comparison
Slide 38
Slide 38 text
Takeaways
- Architecture is key
- Unknown path to scalability
- OOP still works