Flutter 高级样板

一个全新的、几乎全功能的 Flutter 样板项目,使用 BLoC

? 动机

这个样板项目的存在有几个原因,简而言之是为了创建清晰易读可重用可扩展可测试高性能易于维护的项目,但长远来看

  1. 使人们能够部署生产级 MVP 产品
  2. 确保我保持一切简单明了(*有争议,但我已尽力而为*),
  3. 确保随着应用程序的增长,项目可以轻松水平扩展
  4. 通过编写更少、生成更多节省开发人员时间减少样板代码
  5. 通过严格的 linting 规则来维护团队项目中的代码质量和平台标准
  6. 拥有bloc 和 golden 测试来验证所有内容是否按预期工作,
  7. 通过使用CI & CD自动化开发过程,从而快速高效地发布应用程序。

? 主要特点

  • API 系统与认证 使用 Dio、GraphQL 和 Fresh 支持 REST 和 GraphQL API,支持令牌续订和套接字。
  • 性能 通过 keframe 的帧拆分渲染,针对由构建引起的延迟(如页面切换或复杂列表的快速滚动)进行了性能优化。
  • 状态管理与架构 BLoC & Hydrated Bloc 通过创建持久化和强大的状态管理来帮助将业务逻辑与 UI 分离。
  • 高级 Linting 带有详细设置的 Linting 规则,以保持代码的健康状态并符合 dart 标准。
  • 类型安全 该样板项目采用类型安全优先的方法(语言、资产等),通过在开发过程中捕获 null 错误而不是在运行时捕获,来帮助您避免问题。
  • 表单 创建和管理表单从未如此轻松有趣。响应式表单是一种用于处理表单输入和验证的模型驱动方法。
  • 测试 应用程序的功能越多,手动测试就越困难。自动化测试有助于在您发布应用程序之前确保应用程序正常运行,通过 Bloc Test、Golden Tookit 和 Mocktail。
  • 依赖注入与服务定位器 使用 Injectable 和 GetIt 减少类之间的紧密耦合,从而实现更高的代码可重用性。
  • 代码生成 通过使用 Freezed、Artemis 和 Build Runner 生成数据类,最大限度地提高生产力并提高代码质量。
  • CI & CD 集成 CI/CD 用于持续将代码交付到生产环境,并通过 Codemagic 实现最高效的交付方式,确保新功能和错误修复的持续流程。
  • 简单干净的路由 AutoRouter 允许强类型参数传递、轻松深度链接和代码生成,以简化路由并减少样板代码。
  • 设计模式 Repository 设计模式降低了数据层的复杂性,将非结构化数据与应用程序的其余部分隔离,并组织了项目结构。
  • 异常处理 在每个函数中使用 try 和 catch 来处理异常并不是一个非常理想的解决方案。Data Channel 提供了处理异常和数据路由的实用程序。
  • 加密存储 加密存储允许您使用 Secure Storage 将令牌和用户信息安全地保存在平台的密钥链中。
  • 动态主题 借助 Android 12 和 Material You,可以提取壁纸颜色来创建 ColorScheme,用于为应用着色。
  • 本地化 使用类型安全的结构化“slang”语言生成器轻松将应用本地化为其他语言。
  • 权限 该样板还提供了一个跨平台(iOS、Android)API,使用 permission_handler 来请求权限和检查其状态。
  • 环境变量 环境变量允许定义应用程序中共享的全局常量,例如 API 密钥、基础 URL 等。
  • 日志记录与跟踪 详细的日志记录和错误跟踪机制,通过 Logging 和 Sentry 实时监控应用程序中发生的每一个操作。
  • 原生启动屏 Flutter Native Splash 自动生成 iOS、Android 和 Web 原生代码,用于自定义此原生启动屏的背景颜色和启动图像。
  • 刷新率 使用 flutter_displaymode 包支持高刷新率显示。

? 截图

移动端的动态主题

iOS 浅色 TR Android 系统深色 EN

Web 端的动态主题

Web 系统浅色 TR Web 深色 EN

? 如何使用

? 构建

要克隆并运行此样板,您需要在计算机上安装 GitFlutter。从您的命令行

# Clone this repository
$ git clone https://github.com/fikretsengul/flutter_advanced_boilerplate

# Go into the repository
$ cd flutter_advanced_boilerplate

# Install dependencies
$ flutter pub get

# Generate structured language files
$ flutter pub run slang

# Checks missing and unused translations
$ flutter pub run slang analyze

# Generate data classes & structured asset files
$ flutter packages pub run build_runner build -d

# Update goldens & Execute tests
$ flutter test --update-goldens

# Run the app
$ flutter run

# Run the app on web
$ flutter run -d chrome --web-renderer html (low performance, low download size)
$ flutter run -d chrome --web-renderer canvaskit (high performance, high download size)

# If you update your splash screen configuration you can regenerate it via
$ flutter pub run flutter_native_splash:create

隐藏生成的文件

为了隐藏生成的文件,请导航到 “VSCode” -> “首选项” -> “设置”,搜索 “Files: Exclude”,然后按 “添加模式” 按钮添加以下模式。

**/*.config.dart
**/*.freezed.dart
**/*.inject.summary
**/*.inject.dart
**/*.g.dart
**/*.gr.dart

在 Android Studio 中,导航到 “Android Studio” -> “首选项” -> “编辑器” -> “文件类型”,然后在忽略文件和文件夹部分粘贴以下行。

*.config.dart;*.freezed.dart;*.inject.summary;*.inject.dart;*.g.dart;*.gr.dart;

? 文件夹结构

Assets 文件夹

assets 文件夹位于 lib 文件夹的上方。应用程序中使用的资产、环境设置、字体、图像、翻译等都在这里。

.
└── assets
    ├── animations                          -> put your animated files here eg. lottie
    ├── configs                             -> put your env files here
    │   ├── dev.json                           -> env that is used for dev
    │   ├── prod.json                          -> env that is used for prod
    │   └── test.json                          -> env that is used for tes
    ├── fonts                               -> put your custom font files here
    ├── images                              -> put your image files here
    └── translations                        -> put your translation files here
        ├── en.json
        └── tr.json

Features 文件夹

features 文件夹是应用程序的骨干,它采用的是功能优先结构而不是层优先结构,因为后者在应用程序增长时扩展性不佳,并采用仓库设计模式。功能优先方法要求我们为添加到应用程序的每个新功能创建一个新文件夹。在该文件夹内,我们可以将仓库模式层本身添加为子文件夹。

.
└── lib
    └── features                            -> stands for FEATURE FIRST STRUCTURE
        └── feature_x                          -> seperate and put your features here
            ├── blocs                          -> stands for APPLICATION LAYER
            │   ├── x_cubit.dart                  -> seperate and put your logics here
            │   └── x_state.dart
            ├── models                         -> stands for DOMAIN LAYER
            │   └── x_model.dart                  -> seperate and put your models here
            ├── networking                     -> stands for DATA LAYER
            │   └── x_repository.dart             -> seperate and put your repos here
            └── presentation                   -> stands for PRESENTATION LAYER
                ├── widgets                       -> seperate and put your widgets here
                │   └── x_header_widget.dart
                └── x_screen.dart

Modules 文件夹

modules 文件夹中,有第三方模块的依赖注入注册和初始化过程,以确保它们可以轻松地从应用程序内部访问和使用。

.
└── lib
    └── modules
        ├── dependency_injection               -> add your modules injection here
        │   ├── di.dart                           -> must initialize di first
        │   └── x_module_di.dart                  -> example module injection
        └── x_module                           -> create folder for your modules
            └── init_x.dart                       -> create initialization files here

Theme 文件夹

theme 文件夹包含必要的主题配置和设置。

.
└── lib
    └── theme
        ├── color
        │   └── app_color_scheme.dart
        ├── text
        │   └── app_typography.dart
        └── app_theme_creator.dart             -> theme creation configuration here

Utils 文件夹

除上述之外,常量、助手类和方法、快捷方式以及应用程序中使用的更多内容都位于 utils 文件夹中。

.
└── lib
    └── utils
        ├── helpers                            -> put your helpers here
        │   ├── bar_helper.dart                   -> bar helper to show alert
        │   ├── logging_helper.dart               -> logging helper to show fancy log in console
        │   └── permission_helper.dart            -> permission helper to handle permission requests
        ├── methods                            -> put your methods here
        │   └── aliases.dart                      -> create alias variables here
        │   └── shorcuts.dart                     -> add shortcut methods here
        ├── constants.dart                     -> configure app constants here
        ├── navigation.dart                    -> add navigation destinations here
        ├── r.dart                             -> generated type-safe asset classes here (don't modify)
        └── router.dart                        -> add new screens here

? 值得了解的

我强烈推荐您阅读和观看的资源

  1. Code with Andrea Tutorials • 博客YouTube
  2. Reso Coder Tutorials • 博客YouTube
  3. Flutter • YouTube
  4. Marcus Ng • YouTube
  5. Flutter Mapp • YouTube
  6. Max on Flutter • YouTube

VSCode 扩展

扩展 用法
Awesome Flutter Snippets Awesome Flutter Snippets 是常用 Flutter 类和方法的集合。它通过消除创建小部件所需的大部分样板代码来提高您的开发速度。
Better Comments Better Comments 扩展将帮助您在代码中创建更人性化的注释。
bloc VSCode 对 Bloc 库的支持,并提供工具来有效地为 Flutter 和 AngularDart 应用程序创建 Blocs 和 Cubits。
Build Runner 方便地使用 VSCode 运行 build_runner 命令。
Dart Dart Code 通过对 Dart 编程语言的支持扩展了 VSCode,并提供了用于有效编辑、重构、运行和重新加载 Flutter 移动应用程序的工具。
Error Lens ErrorLens 通过更突出地显示诊断结果来加速语言诊断功能,突出显示由语言生成的诊断所在的整行,并在行内显示消息。
Fluent Icons 产品图标主题允许主题作者自定义 VS Code 内置视图中使用的图标:除文件图标(由文件图标主题涵盖)和扩展贡献的图标之外的所有图标。
Flutter 此 VS Code 扩展通过对 Flutter 移动应用程序的有效编辑、重构、运行和重新加载的支持来增强功能。它依赖于(并将自动安装)Dart 扩展来支持 Dart 编程语言。
flutter-stylizer Flutter Stylizer 是一个 VSCode 扩展,它以一种有见地且一致的方式组织您的 Flutter 类。
GitLens — Git 超级增强 GitLens 在 VS Code 中超级增强 Git,并解锁每个存储库中未开发的知识。它通过 Git blame 注释和 CodeLens 帮助您一目了然地可视化代码作者身份,无缝导航和探索 Git 存储库,通过丰富的可视化和强大的比较命令获得宝贵的见解,等等。
Min Theme 一个用于 VS Code 的极简主题,有深色和浅色可选。
Output Colorizer VSCode/Bluemix Code 的语言扩展,为输出/调试/扩展面板和 *.log 文件添加了语法着色。
Pubspec Assist Pubspec Assist 是一个 Visual Studio Code 扩展,可让您轻松地将依赖项添加到 Dart 和 Flutter 项目的 pubspec.yaml 中,而无需离开编辑器。
Rainbow Brackets 为圆括号、方括号和花括号提供彩虹色。这对于 Lisp 或 Clojure 程序员,当然还有 JavaScript 和其他程序员特别有用。
Settings Sync 使用 GitHub Gist 在多台机器上同步设置、代码片段、主题、文件图标、启动配置、键绑定、工作区和扩展。
Sort lines 在 Visual Studio Code 中对文本行进行排序。
终端 在文本编辑器中直接运行终端命令
Thunder Client Thunder Client 是一个轻量级的 REST API 客户端扩展,适用于 Visual Studio Code,由 Ranga Vadhineni 精心制作,设计简洁。
Version Lens 此扩展在打开包或项目时显示版本信息。

? 包

此存储库使用了以下 pub 包

版本 用法
dio ^4.0.6 API*
graphql_flutter ^5.1.0 API*
web_socket_channel ^2.2.0 API
internet_connection_checker_plus ^1.0.1 网络
fresh_dio ^0.3.2 Auth*
fresh_graphql ^0.5.2 Auth*
keframe ^3.0.0 Performance*
flutter_bloc ^8.1.1 State & Architecture*
hydrated_bloc ^8.1.0 State Persistance*
very_good_analysis ^3.1.0 Linting*
dart_code_metrics ^4.19.1 Linting*
reactive_forms ^14.1.0 Forms*
injectable ^1.5.4 Dependency Injection*
get_it ^7.2.0 Service Locator*
freezed ^2.2.0 Code Generation for Classes*
artemis ^7.9.0-beta Code Generation for GraphQL*
build_runner ^2.3.0 Code Generation for Others*
json_serializable ^6.5.4 Code Generation for JSON*
slang_flutter ^3.3.0 Code Generation for Languages*
slang_build_runner ^3.3.0 Code Generation for Languages*
r_resources ^1.0.1 Code Generation for Assets*
auto_route ^5.0.2 Routing*
data_channel ^2.0.0+1 Exceptions*
hive_flutter ^1.1.0 Storage*
flutter_secure_storage ^6.0.0 Storage*
slang ^3.3.1 Localization*
permission_handler ^10.2.0 Permission
logger ^1.1.0 Logging*
pretty_dio_logger ^1.2.0-beta-1 Logging*
sentry_flutter ^6.13.1 Tracking*
sentry_dart_plugin ^1.0.0-beta.4 Tracking*
sentry_dio ^6.13.1 Tracking*
statsfl ^2.3.0 Tracking
flutter_displaymode ^0.4.0 Refresh Rate
animations ^2.0.7 动画
golden_toolkit ^0.13.0 测试
bloc_test ^9.1.0 测试
mocktail ^0.3.0 测试
mocktail_image_network ^0.3.1 测试
universal_platform ^1.0.0+1 Tool*
json_theme ^4.0.2+2 Tool*
ionicons ^0.2.1 图标
flutter_staggered_grid_view ^0.6.2 其他
custom_sliding_segmented_control ^1.7.3 其他
url_launcher ^6.1.6 其他
path_provider ^2.0.11 Others*
intl ^0.17.0 其他
http ^0.13.5 其他
infinite_scroll_pagination ^3.2.0 其他
spring_button ^2.0.0 其他
rounded_loading_button ^2.1.0 其他
auto_size_text ^3.0.0 Others*
styled_text ^6.0.0 Others*
shimmer ^2.0.0 其他
url_strategy ^0.2.0 其他
image_picker ^0.8.6 其他

*建议无论您的项目如何都保留。

❓ 常见问题

Riverpod 目前非常流行,用于状态管理。我对 bloc 的看法以及您为什么更喜欢它而不是其他产品感到好奇?

对我来说,BLoC 的可扩展性更好,更适合大型团队。Riverpod 更像是一个依赖注入系统,它也包含一些状态管理功能。您可以完全使用 blocs 或 cubits 来代替 StateNotifier。其他可能的选择是:

  • 如果您的单个屏幕非常复杂且状态众多,那么 bloc 可以使代码非常简洁,并轻松处理每个状态(特别是与 freezed 结合使用时)。
  • Bloc 迫使您将 UI 和逻辑分开。
  • Bloc 提供了一种将函数与其事件封装的方法。这允许您使用事件转换器,它们非常酷。您可以使函数并发、并行、节流等。所有这些都可以通过 bloc observers 来精确监控每个事件的作用以及状态的变化。
  • Hydrated bloc 也是另一个很酷的功能。只需扩展 hydrated bloc 而不是 bloc,您就可以在重新启动应用程序时持久化应用程序状态。
我使用 go_router。您有不使用的特定原因吗?

实际上,我只是在多个项目中使用 auto_route,它对我有用,所以我一直坚持使用它,因为我已经熟悉它了。不必追逐潮流去做大多数人或每个人都在做的事情,因为每天都有包的替代方案。

? 社区

? 贡献

如果您想说谢谢,您可以:

代码贡献也一直受到欢迎和赞赏。

  1. 报告错误 如果您认为您遇到了错误,并且我应该知道,请随时报告,我会处理它。
  2. 请求功能 您也可以请求功能,如果可行,它将被纳入开发。
  3. 创建拉取请求 没有比这更好的了,您的拉取请求将受到社区的赞赏。您可以通过选择任何未解决的问题并提交拉取请求来开始。

如果您是开源新手,请确保在此处阅读更多并在此处了解更多关于创建拉取请求的信息

? 分支

  1. stage 是开发分支。

  2. master 是生产分支。

  3. 主存储库中不应创建其他永久分支,您可以创建功能分支,但它们应与 master 合并。

处理功能分支的步骤

  1. 要开始处理新功能,请创建一个以 feat 为前缀并后跟功能名称的新分支。(例如:feat-FEATURE-NAME
  2. 完成后,您可以提交 PR。

创建拉取请求的步骤

  1. stage 分支提交 PR。
  2. 遵守最佳实践和指南,例如,当 PR 涉及视觉元素时,应附带显示效果的图片。
  3. 它必须通过所有持续集成检查并获得积极的评审。

之后,更改将被合并。

我们一起,每天都可以让这个项目变得更好! ?

? 许可证

MIT © Fikret Şengül

GitHub

查看 Github