mcpField
F
flutter-project-init

flutter-project-init

github.com/vp-k开发1443 次安装11 周前更新
代码仓库

关于 flutter-project-init

用于初始化 Flutter 应用的工作流 Skill,采用 Clean Architecture 结构。它收集项目和领域需求,协助选择状态管理方式与功能预设,再生成代码并使用 Flutter 工具验证。

主要功能

  1. 01项目名称与组织信息配置
  2. 02六种 CRUD 领域模式
  3. 03选择 Riverpod 或 BLoC
  4. 04Minimal、Essential 和 Full 预设
  5. 05代码生成与 Flutter 分析

适用场景

  1. 01根据项目需求启动 Flutter 应用
  2. 02选择数据模型模式和状态管理方式
  3. 03生成并检查应用初始结构

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/vp-k/flutter-craft --skill flutter-project-init

安装后在 Claude Code 中输入/flutter-project-init确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
categorized-pattern.md
relational-pattern.md
simple-pattern.md
stateful-pattern.md
tracked-pattern.md

详细介绍

Flutter 项目初始化

适用于:“新项目”“创建项目”“启动项目”“初始化 Flutter”

工作流概览

Step 1: Project Info     → name, org, description
Step 2: Domain Pattern   → Simple/Stateful/Categorized/Tracked/Relational/Custom
Step 3: Tech Stack       → State Management, Features
Step 4: Generate & Verify → create, build, analyze

第 1 步:收集项目信息

询问用户:

字段示例必填
项目名称my_app (snake_case)是
组织com.example是
描述“任务管理应用”是
实体名称Task、Note、Expense是

第 2 步:选择领域模式(基于 CRUD)

请用户选择:

模式示例生成的结构
SimpleNote、Memo、Bookmark单实体 CRUD
StatefulTodo、Task、Order包含状态字段(已完成/进行中等)
CategorizedExpense、Product、Recipe包含分类关系
TrackedHabit、Workout、Study基于时间/日期的追踪
RelationalBlog(User-Post-Comment)多实体关系
Custom-用户定义的字段
各模式生成的代码
Simple 模式
// Entity
@freezed
sealed class Note with _$Note {
  const factory Note({
    required String id,
    required String title,
    required String content,
    required DateTime createdAt,
    DateTime? updatedAt,
  }) = _Note;
}
Stateful 模式
// Entity with status
@freezed
sealed class Task with _$Task {
  const factory Task({
    required String id,
    required String title,
    required String description,
    @Default(TaskStatus.pending) TaskStatus status,
    required DateTime createdAt,
    DateTime? completedAt,
  }) = _Task;
}

enum TaskStatus { pending, inProgress, completed, cancelled }
Categorized 模式
// Entity with category relation
@freezed
sealed class Expense with _$Expense {
  const factory Expense({
    required String id,
    required String title,
    required double amount,
    required String categoryId,
    required DateTime date,
    String? note,
  }) = _Expense;
}

@freezed
sealed class Category with _$Category {
  const factory Category({
    required String id,
    required String name,
    required String icon,
    required String color,
  }) = _Category;
}
Tracked 模式
// Entity with time tracking
@freezed
sealed class Habit with _$Habit {
  const factory Habit({
    required String id,
    required String name,
    required String description,
    required HabitFrequency frequency,
    required List<DateTime> completedDates,
    required int currentStreak,
    required int bestStreak,
    required DateTime createdAt,
  }) = _Habit;
}

enum HabitFrequency { daily, weekly, monthly }
Relational 模式
// Multiple related entities
@freezed
sealed class User with _$User {
  const factory User({
    required String id,
    required String name,
    required String email,
    required DateTime createdAt,
  }) = _User;
}

@freezed
sealed class Post with _$Post {
  const factory Post({
    required String id,
    required String authorId,
    required String title,
    required String content,
    required DateTime createdAt,
    @Default(0) int likeCount,
  }) = _Post;
}

@freezed
sealed class Comment with _$Comment {
  const factory Comment({
    required String id,
    required String postId,
    required String authorId,
    required String content,
    required DateTime createdAt,
  }) = _Comment;
}

第 3 步:选择技术栈

状态管理(必须选择)
选项描述
Riverpod(推荐)现代、安全、可测试的编译时方案
BLoC事件驱动,适用于企业级项目
功能预设
预设包含内容
Minimal仅核心功能(Freezed、Drift、DI)
Essential+ GoRouter、Dio、错误处理
Full+ 身份验证、本地化、响应式布局
功能详情

前置条件: 使用近期的稳定版 Flutter SDK(Dart >= 3.9)。在较旧的 SDK 上,pub 会静默解析到一个有问题的 -dev 版 freezed 预发布版本,导致无法生成任何内容。 先运行 flutter --version 检查版本;如果版本过旧,请先运行 flutter upgrade。

使用一条 flutter pub add 命令安装所选预设所需的全部依赖—— 仅进行一次解析。分步安装会让依赖解析器陷入困境:每次解析都会锁定最新的 caret 版本, 而代码生成依赖组(freezed / drift_dev / injectable_generator / riverpod_generator)使用的 analyzer 主版本各不相同, 因此,后续的依赖组可能无法与先前锁定的版本兼容。 一次解析可让 pub 选择一组彼此兼容且均为稳定版的依赖。

# Full preset + Riverpod (remove what your preset doesn't need — but never
# split runtime and dev: codegen packages into separate commands).
# path_provider/path are required by app_database.dart.
# fpdart = Either for error handling (dartz is unmaintained).
flutter pub add freezed_annotation drift path_provider path get_it injectable flutter_riverpod riverpod_annotation go_router dio fpdart easy_localization responsive_framework dev:freezed dev:build_runner dev:injectable_generator dev:drift_dev dev:riverpod_generator

# Using BLoC instead of Riverpod: drop flutter_riverpod, riverpod_annotation
# and dev:riverpod_generator from the command above and run:
flutter pub add flutter_bloc

# Optional (Full preset):
flutter pub add firebase_auth

安装后,检查 pubspec.yaml 中是否存在 -dev/-beta 预发布版本。生态系统迁移 analyzer 主版本期间可能会出现此类版本;这本身并非致命问题,但这意味着第 4.6 步(代码生成后运行 flutter analyze)必须作为验证依据——如果代码生成悄无声息地什么都没生成,分析就会在此处失败。


第 4 步:生成项目

4.1 创建 Flutter 项目
flutter create --org <org> --project-name <name> <name>
cd <name>
4.2 设置文件夹结构
lib/
├── core/
│   ├── constants/
│   │   └── app_constants.dart
│   ├── database/
│   │   └── app_database.dart
│   ├── di/
│   │   └── injection.dart
│   ├── errors/
│   │   ├── exceptions.dart
│   │   └── failures.dart
│   ├── router/
│   │   └── app_router.dart
│   ├── theme/
│   │   ├── app_colors.dart
│   │   └── app_theme.dart
│   └── utils/
│       └── extensions.dart
├── features/
│   └── <entity>/
│       ├── domain/
│       │   ├── entities/
│       │   │   └── <entity>.dart
│       │   ├── repositories/
│       │   │   └── <entity>_repository.dart
│       │   └── usecases/
│       │       ├── create_<entity>.dart
│       │       ├── delete_<entity>.dart
│       │       ├── get_<entity>s.dart
│       │       └── update_<entity>.dart
│       ├── data/
│       │   ├── datasources/
│       │   │   └── <entity>_local_datasource.dart
│       │   ├── models/
│       │   │   └── <entity>_model.dart
│       │   └── repositories/
│       │       └── <entity>_repository_impl.dart
│       └── presentation/
│           ├── bloc/          # or providers/
│           │   ├── <entity>_bloc.dart
│           │   ├── <entity>_event.dart
│           │   └── <entity>_state.dart
│           ├── pages/
│           │   ├── <entity>_list_page.dart
│           │   └── <entity>_detail_page.dart
│           └── widgets/
│               └── <entity>_card.dart
├── shared/
│   └── widgets/
│       └── loading_widget.dart
└── main.dart
4.3 生成基础文件
core/errors/failures.dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'failures.freezed.dart';

@freezed
sealed class Failure with _$Failure {
  const factory Failure.server({required String message, int? code}) = ServerFailure;
  const factory Failure.cache({required String message}) = CacheFailure;
  const factory Failure.network({@Default('No internet connection') String message}) = NetworkFailure;
  const factory Failure.validation({required String message}) = ValidationFailure;
}
core/database/app_database.dart
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;

part 'app_database.g.dart';

// Tables will be added per domain pattern
@DriftDatabase(tables: [])
class AppDatabase extends _$AppDatabase {
  AppDatabase() : super(_openConnection());

  @override
  int get schemaVersion => 1;
}

LazyDatabase _openConnection() {
  return LazyDatabase(() async {
    final dbFolder = await getApplicationDocumentsDirectory();
    final file = File(p.join(dbFolder.path, 'app.db'));
    return NativeDatabase.createInBackground(file);
  });
}
core/di/injection.dart
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
import 'injection.config.dart';

final getIt = GetIt.instance;

@InjectableInit(preferRelativeImports: true)
Future<void> configureDependencies() async => getIt.init();
4.4 更新 pubspec.yaml

根据所选预设添加所有必需的依赖。

4.5 运行代码生成
flutter pub get
dart run build_runner build --delete-conflicting-outputs
4.6 验证(必需)
flutter analyze

必须通过,且错误数为 0。 信息/警告级别的问题可以接受。

如果存在错误:

  1. 修复每个错误
  2. 重新运行 dart run build_runner build
  3. 重新运行 flutter analyze
  4. 重复以上步骤,直到错误数为 0

第 5 步:初始化 Git

git init
git add .
git commit -m "Initial commit: <project_name> with Clean Architecture

- Domain pattern: <selected_pattern>
- State management: <Riverpod/BLoC>
- Features: <selected_preset>

🤖 Generated with flutter-craft"

完成检查清单

  • 项目已使用正确的名称/组织创建
  • 文件夹结构符合 Clean Architecture
  • 已使用 Freezed 生成领域实体
  • 已在 Drift 中创建数据库表
  • 已使用 injectable 配置 DI
  • flutter pub get 执行成功
  • dart run build_runner build 执行成功
  • flutter analyze 返回 0 个错误
  • 已初始化 Git 并创建初始提交

向用户提供的输出

完成后,告知用户:

✅ Project '<name>' created successfully!

📁 Structure: Clean Architecture
📦 Pattern: <selected_pattern>
🔄 State: <Riverpod/BLoC>
✨ Features: <preset>

Next steps:
1. cd <name>
2. flutter run
3. Use /brainstorm to plan your first feature

参考资料

如需查看各模式的详细代码模板,请参阅:

  • references/simple-pattern.md
  • references/stateful-pattern.md
  • references/categorized-pattern.md
  • references/tracked-pattern.md
  • references/relational-pattern.md

注意: Custom 模式没有专用模板,因为用户自定义字段需要自行设计。

评论

支持 Markdown