Version 1.0.0
This repository contains my starter code for a Flutter project, which is highly inspired by dbestech and Very Good Ventures.
For quick installation, you can run the following command:
Linux & MacOS:
curl -s https://raw.githubusercontent.com/fzl-22/faisal-starter-code-flutter/master/install.sh > install.sh && bash install.sh
Note:
gnu-sed
is required for installation on MacOS (brew install gnu-sed
)
- 1 Technology Stack
- 2 Dependencies
- 3. Directory Structures and Architectural Overviews
- 4 Guides
- 5 Documentation
Software | Version |
---|---|
Flutter | 3.19.2 |
Dart | 3.3.0 |
OpenJDK | 11.0.22 |
Package | Description |
---|---|
bloc | State management library that helps implement the BLoC design pattern. |
cached_network_image | Loads and caches network images. |
dartz | Functional programming in Dart (used for clean error-handling) |
dio | HTTP networking package with supports on Interceptor, request cancellation, timeout, and etc. |
envied | Explicitly reads environment variables into a dart file from a .env file for more security and faster start up times. |
equatable | Value-based objects comparison. |
flutter_bloc | Flutter Widgets that make it easy to implement the bloc |
flutter_dotenv | Load configuration at runtime from a .env file |
flutter_svg | SVG rendering widget from an asset. |
freezed_annotation | Annotations for freezed. |
get_it | Simple direct Service Locator for dependency injection. |
go_router | Routing package with URL-based API. |
injectable | Code generator for get_it |
logger | Beautiful log printer. |
provider | A wrapper around InheritedWidget . Used for local state-abstraction. |
safe_change_notifier | Safer replacement for ChangeNotifier and ValueNotifer . |
talker_dio_logger | Lightweight and customizable dio http client logger on talker base. |
bloc_test | Testing library for blocs and cubits (dev_dependencies) |
build_runner | A build system for Dart code generation and modular compilation (dev_dependencies) |
envied_generator | Generator for https://pub.dev/packages/envied (dev_dependencies). |
freezed | Code generation for immutable classes (dev_dependencies). |
injectable_generator | A generator for injectable library (dev_dependencies) |
mocktail | Mock library which simplifies mocking with null safety support (dev_dependencies) |
very_good_analysis | Lint rules for Dart and Flutter by Very Good Ventures (dev_dependencies). |
This directory contains asset resources such as fonts, images, icon, and etc. Any new asset must be registered to pubspec.yaml and lib/core/resources.
Here resides the application source code. Contains only [lib/core/] and [lib/src/].
Contains core features and utilities of the app written mostly in Dart code (almost framework-independent).
Contains application-wide shared themes, widgets, screens, or state.
Contains application-wide constant values.
Contains predefined exceptions and failures.
Contains developer-defined extensions for built-in Dart object. This directory provides more-compact of some Dart object/method calls.
Contains injection of dependencies of the application architecture. This directory provides dependency injection container.
Contains registered constants that hold the value of each assets path in assets/ and defined typographies. This dependency provides UI assets consistency.
Contains application routes and transitions. This directory defines routes configuration.
Contains classes that encapsulate the business logic of the application (usecases).
Contains additional utilities to the application.
This directory holds the features of the application. Any feature added in the application must reside in this directory as lib/src/[feature]/
.
Each feature has 3 layers according to the Clean Architecture design by Robert C. Martin.
Source image: dbestech.com
So, each feature must have:
lib/src/[feature]/domain/
lib/src/[feature]/data/
lib/src/[feature]/presentation/
Domain layer contains the business logic of the application (core business logic, not BLoC logic).
Domain does not depend on anyone. Presentation layer finds domain layer to work with.
This layer have 3 sublayers:
lib/src/[feature]/domain/entities/
lib/src/[feature]/domain/repos/
lib/src/[feature]/domain/usecases/
Entities hold the blue print of data model which we will pass around for a certain features or screens or pages.
Domain repositories contains abstract classes that defines a contract between domain layer and data layer.
The method of repository must be implemented in the data layer's repository.
Usecases contains communication tunnel between presentation and domain layer
Usecases depend on repositories and should be independent of anything outside of domain layer.
Data layer is an interface to communicate with data outside the app (remote or local).
Data layer depends on domain layer.
This layer have 3 sublayers:
lib/src/[feature]/data/models/
lib/src/[feature]/data/repos/
lib/src/[feature]/data/datasources/
Model is an extension of the extensions. This sublayer provides JSON serialization or constructorss to interact with outside data.
The repos in data layer is the implementation of the repos in the domain layer. It provides the communication with domain layers.
Data layer's repositories depends on datasources.
Data sources provides communication with data from outside (API, local storage, and etc).
Data sources depends on external source, for example: http package.
Presentation layer provides UI presented to the user. Flutter's code only resides here in lib/src/[feature]/
directory.
DO NOT add framework-dependent code to any other layer than the presentation layer.
Presentation layer is framework-dependent and depends on domain layer.
This layer may have 3 sublayers:
lib/src/[feature]/domain/bloc/
lib/src/[feature]/domain/views/
lib/src/[feature]/domain/widgets/
This sublayer can have providers
to manages local state-abstraction if necessary.
BLoC contains the state management to controls UI state.
BLoC is dependent to the domain layer's usecases.
It provides multilayer state-management between presentation layer and domain layer.
Note: It is recommended to inject BLoC to the widget tree via the router instead of the root widget or inside a views.
Views sublayer provides the screens of the feature. The state of the screens and widgets inside is controlled with state manager.
Provides the feature-wide shared widgets that resides in the views sublayer.
Clone this repository to your local machine.
git clone [email protected]:fzl-22/faisal-starter-code-flutter.git
To get all dependencies, run the following command.
flutter pub get
In a newly cloned project, you will notice that some files with *.g.dart
, *.config.dart
, and *.freezed.dart
are missing. You need to generate those files with build_runner.
dart run build_runner build # one time and exits
or
dart run build_runner watch # watch and rebuild as necessary
Turn on your Android emulator or physical device. Then, run the project.
flutter run
flutter run
key commands.
r
to hot reload.R
to hot restart.h
to list all available interactive commands.d
to detach (terminate "flutter run" but leave application running).c
to clear the screenq
to quit (terminate the application on the device).
Install a package.
flutter pub add {package}
Install a package as dev_dependencies
.
flutter pub add dev:{package}
Uninstall a package.
flutter pub remove {package}
The documentation of this project can be generated using dartdoc.
Install compatible version of dartdoc
.
fvm dart pub global activate dartdoc
In the project root directory, generate HTML documentation.
dart doc .
Make sure you have no error in the source code
Your generated documentation will be on doc/api/
directory.
Serve the docs with dhttpd package (install with fvm dart pub global activate dhttpd
).
dhttpd --path doc/api
You can read the documentation at http://localhost:8080
.