Riverpod 的 Flutter 项目目录结构最佳实践
1. 基础项目结构
lib/
├── main.dart
├── app/
│ ├── app.dart
│ ├── router/
│ └── theme/
├── core/
│ ├── constants/
│ ├── exceptions/
│ ├── extensions/
│ ├── utils/
│ └── network/
├── features/
│ ├── auth/
│ ├── home/
│ ├── profile/
│ └── settings/
├── shared/
│ ├── providers/
│ ├── widgets/
│ ├── models/
│ └── services/
└── generated/
2. 详细目录结构
核心应用层
app/
├── app.dart # 主应用配置
├── router/
│ ├── app_router.dart # 路由配置
│ ├── router_provider.dart # 路由相关 Provider
│ └── routes.dart # 路由常量
└── theme/
├── app_theme.dart # 主题配置
└── theme_provider.dart # 主题 Provider
核心功能层
core/
├── constants/
│ ├── api_constants.dart
│ ├── app_constants.dart
│ └── storage_keys.dart
├── exceptions/
│ ├── app_exception.dart
│ ├── network_exception.dart
│ └── cache_exception.dart
├── extensions/
│ ├── string_extension.dart
│ ├── context_extension.dart
│ └── date_extension.dart
├── utils/
│ ├── logger.dart
│ ├── validators.dart
│ └── formatters.dart
└── network/
├── dio_client.dart
├── api_client.dart
└── network_provider.dart
3. 功能模块结构(Feature-First)
每个功能模块采用完整的分层结构:
features/
├── auth/
│ ├── data/
│ │ ├── datasources/
│ │ │ ├── auth_local_datasource.dart
│ │ │ └── auth_remote_datasource.dart
│ │ ├── models/
│ │ │ ├── login_request.dart
│ │ │ ├── login_response.dart
│ │ │ └── user_model.dart
│ │ ├── repositories/
│ │ │ └── auth_repository_impl.dart
│ │ └── providers/
│ │ └── auth_data_providers.dart
│ ├── domain/
│ │ ├── entities/
│ │ │ └── user_entity.dart
│ │ ├── repositories/
│ │ │ └── auth_repository.dart
│ │ ├── usecases/
│ │ │ ├── login_usecase.dart
│ │ │ ├── logout_usecase.dart
│ │ │ └── get_current_user_usecase.dart
│ │ └── providers/
│ │ └── auth_domain_providers.dart
│ └── presentation/
│ ├── providers/
│ │ ├── auth_state_provider.dart
│ │ ├── login_form_provider.dart
│ │ └── auth_notifier.dart
│ ├── pages/
│ │ ├── login_page.dart
│ │ ├── register_page.dart
│ │ └── forgot_password_page.dart
│ ├── widgets/
│ │ ├── login_form.dart
│ │ ├── auth_button.dart
│ │ └── password_field.dart
│ └── state/
│ ├── auth_state.dart
│ └── login_form_state.dart
├── home/
│ └── ... (类似结构)
└── profile/
└── ... (类似结构)
4. 共享资源结构
shared/
├── providers/
│ ├── app_providers.dart # 全局应用 Provider
│ ├── storage_providers.dart # 存储相关 Provider
│ ├── connectivity_providers.dart # 网络连接 Provider
│ └── device_info_providers.dart # 设备信息 Provider
├── widgets/
│ ├── common/
│ │ ├── custom_button.dart
│ │ ├── loading_widget.dart
│ │ ├── error_widget.dart
│ │ └── empty_state_widget.dart
│ ├── forms/
│ │ ├── custom_text_field.dart
│ │ ├── custom_dropdown.dart
│ │ └── form_validators.dart
│ └── layouts/
│ ├── scaffold_with_nav.dart
│ └── responsive_layout.dart
├── models/
│ ├── api_response.dart
│ ├── pagination.dart
│ └── result.dart
└── services/
├── storage_service.dart
├── notification_service.dart
├── analytics_service.dart
└── cache_service.dart
5. Provider 组织最佳实践
全局 Provider 集中管理
// shared/providers/app_providers.dart
import 'package:riverpod/riverpod.dart';
// 基础服务 Provider
final storageServiceProvider = Provider<StorageService>((ref) {
return StorageService();
});
final apiClientProvider = Provider<ApiClient>((ref) {
return ApiClient();
});
final loggerProvider = Provider<Logger>((ref) {
return Logger();
});
// 应用级状态 Provider
final connectivityProvider = StreamProvider<ConnectivityResult>((ref) {
return Connectivity().onConnectivityChanged;
});
final deviceInfoProvider = FutureProvider<DeviceInfo>((ref) async {
return await DeviceInfoService.getDeviceInfo();
});
功能模块 Provider 分层
// features/auth/data/providers/auth_data_providers.dart
final authLocalDataSourceProvider = Provider<AuthLocalDataSource>((ref) {
final storage = ref.read(storageServiceProvider);
return AuthLocalDataSource(storage);
});
final authRemoteDataSourceProvider = Provider<AuthRemoteDataSource>((ref) {
final client = ref.read(apiClientProvider);
return AuthRemoteDataSource(client);
});
final authRepositoryProvider = Provider<AuthRepository>((ref) {
final localDS = ref.read(authLocalDataSourceProvider);
final remoteDS = ref.read(authRemoteDataSourceProvider);
return AuthRepositoryImpl(localDS, remoteDS);
});
// features/auth/domain/providers/auth_domain_providers.dart
final loginUseCaseProvider = Provider<LoginUseCase>((ref) {
final repository = ref.read(authRepositoryProvider);
return LoginUseCase(repository);
});
final getCurrentUserUseCaseProvider = Provider<GetCurrentUserUseCase>((ref) {
final repository = ref.read(authRepositoryProvider);
return GetCurrentUserUseCase(repository);
});
// features/auth/presentation/providers/auth_state_provider.dart
final authStateProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
final loginUseCase = ref.read(loginUseCaseProvider);
final getCurrentUserUseCase = ref.read(getCurrentUserUseCaseProvider);
return AuthNotifier(loginUseCase, getCurrentUserUseCase);
});
6. 文件命名约定
命名规则:
- Provider 文件:{feature}_providers.dart
- State 类:{Feature}State
- Notifier 类:{Feature}Notifier
- UseCase 类:{Action}UseCase
- Repository 实现:{Feature}RepositoryImpl
- Model 类:{Feature}Model
- Entity 类:{Feature}Entity
- Page 组件:{Feature}Page
- Widget 组件:{Feature}Widget
7. 导入组织
// features/auth/presentation/pages/login_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// 核心导入
import '../../../../core/extensions/context_extension.dart';
import '../../../../shared/widgets/common/custom_button.dart';
// 功能模块导入
import '../providers/auth_state_provider.dart';
import '../widgets/login_form.dart';
import '../state/auth_state.dart';
8. 测试目录结构
test/
├── features/
│ ├── auth/
│ │ ├── data/
│ │ │ ├── datasources/
│ │ │ ├── models/
│ │ │ └── repositories/
│ │ ├── domain/
│ │ │ ├── usecases/
│ │ │ └── repositories/
│ │ └── presentation/
│ │ ├── providers/
│ │ └── pages/
│ └── ...
├── shared/
│ ├── services/
│ └── widgets/
├── helpers/
│ ├── test_helpers.dart
│ └── mock_providers.dart
└── fixtures/
└── auth_fixtures.dart
9. 配置文件结构
lib/
├── config/
│ ├── app_config.dart
│ ├── env_config.dart
│ └── flavor_config.dart
└── environment/
├── dev_config.dart
├── staging_config.dart
└── prod_config.dart
10. 完整的 main.dart 示例
// lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'app/app.dart';
import 'core/utils/logger.dart';
import 'shared/providers/app_providers.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化日志
Logger.init();
runApp(
ProviderScope(
observers: [AppProviderObserver()],
child: const MyApp(),
),
);
}
class AppProviderObserver extends ProviderObserver {
@override
void didUpdateProvider(
ProviderBase provider,
Object? previousValue,
Object? newValue,
ProviderContainer container,
) {
Logger.d('Provider updated: ${provider.name ?? provider.runtimeType}');
}
}
这种目录结构的优势:
清晰的分离: 功能模块独立,依赖关系明确
可扩展性: 易于添加新功能模块
可测试性: 每层都可以独立测试
可维护性: 代码组织清晰,便于维护
团队协作: 不同开发者可以专注不同模块