В чем разница между dependencies и dev_dependencies в pubspec.yaml?

«В чем разница между dependencies и dev_dependencies в pubspec.yaml?» — вопрос из категории Other, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В файле pubspec.yaml зависимости разделяются на два типа, которые влияют на сборку приложения и процесс разработки.

dependencies (Основные зависимости):

Пакеты, необходимые для работы приложения в runtime. Они включаются в финальную сборку (APK, IPA, исполняемый файл).

dependencies:
  flutter:
    sdk: flutter

  # UI-библиотеки
  provider: ^6.1.2
  flutter_bloc: ^8.1.3

  # Работа с сетью
  dio: ^5.4.0

  # State management
  riverpod: ^2.4.9

  # Локальная база данных
  sqflite: ^2.3.0

  # Нативные возможности
  url_launcher: ^6.2.1
  camera: ^0.10.7

dev_dependencies (Зависимости для разработки):

Пакеты, нужные только в процессе разработки: тестирование, линтинг, кодогенерация, инструменты сборки. Не попадают в production-сборку.

dev_dependencies:
  flutter_test:
    sdk: flutter

  # Моки для тестов
  mockito: ^5.4.2
  mocktail: ^0.3.7

  # Генерация кода
  build_runner: ^2.4.7
  json_serializable: ^6.7.1
  freezed: ^2.4.7

  # Статический анализ
  flutter_lints: ^3.0.1

  # Инструменты
  flutter_gen_runner: ^5.4.0

  # Тестирование производительности
  integration_test:
    sdk: flutter

Практические примеры различий:

  1. Генерация кода:
    
    // Аннотация из json_serializable
    import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable() class User { final String name; final int age;

User(this.name, this.age);

factory User.fromJson(Map<String, dynamic> json) => $UserFromJson(json); Map<String, dynamic> toJson() => $UserToJson(this); }


Запуск генерации (только в разработке):
```bash
flutter pub run build_runner build
  1. Тестирование:
    
    // test/widget_test.dart
    import 'package:flutter_test/flutter_test.dart';
    import 'package:mocktail/mocktail.dart';

class MockAuthService extends Mock implements AuthService {}

void main() { testWidgets('Login screen test', (tester) async { final mockAuth = MockAuthService(); when(() => mockAuth.login(any(), any())) .thenAnswer((_) async => User('test', 'token'));

await tester.pumpWidget(
  Provider<AuthService>.value(
    value: mockAuth,
    child: const LoginScreen(),
  ),
);

expect(find.text('Welcome'), findsOneWidget);

}); }



**Ключевые отличия:**

*   **Размер билда:** `dev_dependencies` не увеличивают размер production-приложения
*   **Время сборки:** Меньше зависимостей = быстрее компиляция release-версии
*   **Безопасность:** Код из `dev_dependencies` не выполняется у пользователей

**Мой workflow:** Я всегда разделяю зависимости и добавляю в `dev_dependencies` всё, что не нужно в рантайме. Это особенно важно для пакетов с нативным кодом, которые могут значительно увеличить размер приложения.