Slide 1

Slide 1 text

Pub workspaces 로 monorepo 구성하기 @jaichangpark 1

Slide 2

Slide 2 text

박제창 Flutter Seoul GDG Golang Korea 2

Slide 3

Slide 3 text

3

Slide 4

Slide 4 text

4

Slide 5

Slide 5 text

5

Slide 6

Slide 6 text

6

Slide 7

Slide 7 text

“ Pub now supports shared resolution between packages in a monorepo, or workspace. A workspace is a tightly related group of packages developed, resolved, and released together. — Announcing Dart 3.6 7

Slide 8

Slide 8 text

dart pub 8

Slide 9

Slide 9 text

9

Slide 10

Slide 10 text

In version-control systems, a monorepo ("mono" meaning 'single' and "repo" being short for 'repository') is a software-development strategy in which the code for a number of projects is stored in the same repository. This practice dates back to at least the early 2000s, when it was commonly called a shared codebase. Google, Meta, Microsoft, Uber, Airbnb, and X all employ very large monorepos with varying strategies to scale build systems and version control software with a large volume of code and daily changes. a software-development strategy Monorepo 10 @source: https://en.wikipedia.org/wiki/Monorepo

Slide 11

Slide 11 text

Monorepo : Advantages dependency management In a multiple repository environment where multiple projects depend on a third-party dependency, that dependency might be downloaded or built multiple times. In a monorepo the build can be easily optimized, as referenced dependencies all exist in the same codebase. code reuse Similar functionality or communication protocols can be abstracted into shared libraries and directly included by projects, without the need of a dependency package manager. Collaboration across teams In a monorepo that uses source dependencies (dependencies that are compiled from source), teams can improve projects being worked on by other teams. This leads to flexible code ownership. 11 @source: https://en.wikipedia.org/wiki/Monorepo

Slide 12

Slide 12 text

Monorepo : disadvantages More storage needed by default With split repositories, you fetch only the project you are interested in by default. With a monorepo, you check out all projects by default. This can take up a significant amount of storage space. While some versioning systems have a mechanism to do a partial checkout, doing so defeats some of the advantages of a monorepo. Loss of version information Although not required, some monorepo builds use one version number across all projects in the repository. This leads to a loss of per-project semantic versioning. 12 @source: https://en.wikipedia.org/wiki/Monorepo

Slide 13

Slide 13 text

전환 또는 도입은 언제나 (옵션)선택사항 ● 앱이 점점 슈퍼 앱이 되어가고 있다면 ● 협업하는 팀원이 늘어나고 있다면 ● 커스텀이 필요한 네이티브 패키지 개발이 필요하다면 ● 커스텀 패키지의 소스 오픈이 제한되어 있다면 ● n개의 앱(하나이상의 앱)이 동일한 로직(ex:도메인 또는 데이터 모델)을 사용하고 있다면 언제 도입하는게 적절할까요? Monorepo 13

Slide 14

Slide 14 text

그렇다면 기존에는? Monorepo 14

Slide 15

Slide 15 text

Monorepo 15 ● firebase/flutterfire ● Flame-Engine/Flame ● cfug/dio ● simolus3/drift ● FlutterGen/flutter_gen Melos

Slide 16

Slide 16 text

Monorepo 16 Melos ● Automatic versioning & changelog generation. ● Automated publishing of packages to pub.dev. ● Local package linking and installation. ● Executing simultaneous commands across packages. ● Listing of local packages & their dependencies.

Slide 17

Slide 17 text

Full-Stack 17 Backend Dart Server Shared Models APIs Front Flutter App (Client)

Slide 18

Slide 18 text

Pub workspaces 18

Slide 19

Slide 19 text

The pub workspaces feature ensures that packages in a monorepo share a consistent set of dependencies. This forces you to resolve dependency conflicts between your grouped packages as they arise, rather than facing confusion when you start using the packages. The Flutter analyzer processes all of the packages in a pub workspace in a single analysis context, as opposed to the previous behavior of a separate context for each package. For large repositories, this can significantly reduce the amount of memory the Dart language server consumes, improving IDE performance. monorepo support Pub workspaces 19 @source: https://medium.com/dartlang/announcing-dart-3-6-778dd7a80983

Slide 20

Slide 20 text

20

Slide 21

Slide 21 text

Today.. 21

Slide 22

Slide 22 text

flutter create my_app 22

Slide 23

Slide 23 text

23 📦my_app ┣ 📂lib ┃ ┗ 📜main.dart ┣ 📜.gitignore ┣ 📜.metadata ┣ 📜README.md ┣ 📜analysis_options.yaml ┣ 📜my_app.iml ┣ 📜pubspec.lock ┗ 📜pubspec.yaml

Slide 24

Slide 24 text

24 @source: https://docs.flutter.dev/app-architecture/concepts https://docs.flutter.dev/app-architecture/case-study Common architecture concepts

Slide 25

Slide 25 text

25 @source: https://docs.flutter.dev/app-architecture/concepts https://docs.flutter.dev/app-architecture/case-study the Model-View-ViewModel design pattern (MVVM) app architecture

Slide 26

Slide 26 text

26 https://github.com/android/nowinandroid

Slide 27

Slide 27 text

27 @source: https://docs.flutter.dev/app-architecture/concepts https://docs.flutter.dev/app-architecture/case-study lib |____ui | |____core | | |____ui | | | |____ | | |____themes | |____ | | |____view_model | | | |_____.dart | | |____widgets | | | |_____screen.dart | | | |____ |____domain | |____models | | |____.dart |____data | |____repositories | | |____.dart | |____services | | |____.dart | |____model | | |____.dart |____config |____utils |____routing |____main_staging.dart |____main_development.dart |____main.dart

Slide 28

Slide 28 text

28 View View Model Repository Service API jsonplaceholder API https://news.ycombinator.com/ Model

Slide 29

Slide 29 text

29 ● freezed & generator ● riverpod & generator ● retrofit & generator ● dio

Slide 30

Slide 30 text

30 📦lib ┣ 📂domain ┃ ┗ 📂models ┃ ┃ ┣ 📂hacker_news ┃ ┃ ┃ ┣ 📜hn.dart ┃ ┃ ┃ ┣ 📜hn.freezed.dart ┃ ┃ ┃ ┗ 📜hn.g.dart ┃ ┃ ┗ 📂user ┃ ┃ ┃ ┣ 📜user.dart ┃ ┃ ┃ ┣ 📜user.freezed.dart ┃ ┃ ┃ ┗ 📜user.g.dart

Slide 31

Slide 31 text

31 📦lib ┣ 📂data ┃ ┣ 📂providers ┃ ┃ ┣ 📜dio_provider.dart ┃ ┃ ┗ 📜dio_provider.g.dart ┃ ┣ 📂repositories ┃ ┃ ┣ 📜hn_repository.dart ┃ ┃ ┣ 📜hn_repository.g.dart ┃ ┃ ┣ 📜user_repository.dart ┃ ┃ ┗ 📜user_repository.g.dart ┃ ┗ 📂services ┃ ┃ ┣ 📜hacker_news_api.dart ┃ ┃ ┣ 📜hacker_news_api.g.dart ┃ ┃ ┣ 📜user_api.dart ┃ ┃ ┗ 📜user_api.g.dart

Slide 32

Slide 32 text

32 📦lib ┣ 📂data ┃ ┣ 📂providers ┃ ┃ ┣ 📜dio_provider.dart ┃ ┃ ┗ 📜dio_provider.g.dart ┃ ┣ 📂repositories ┃ ┃ ┣ 📜hn_repository.dart ┃ ┃ ┣ 📜hn_repository.g.dart ┃ ┃ ┣ 📜user_repository.dart ┃ ┃ ┗ 📜user_repository.g.dart ┃ ┗ 📂services ┃ ┃ ┣ 📜hacker_news_api.dart ┃ ┃ ┣ 📜hacker_news_api.g.dart ┃ ┃ ┣ 📜user_api.dart ┃ ┃ ┗ 📜user_api.g.dart

Slide 33

Slide 33 text

33 📦lib ┣ 📂ui ┃ ┣ 📂core ┃ ┃ ┣ 📂shared ┃ ┃ ┗ 📜theme.dart ┃ ┣ 📂hacker_news ← Feature 1 ┃ ┃ ┣ 📂view_model ┃ ┃ ┃ ┣ 📜hacker_news_view_model.dart ┃ ┃ ┃ ┗ 📜hacker_news_view_model.g.dart ┃ ┃ ┗ 📂widgets ┃ ┃ ┃ ┣ 📜hacker_news_screen.dart ┃ ┃ ┃ ┗ 📜news_list_widget.dart ┃ ┣ 📂user ← Feature 2 ┃ ┃ ┣ 📂view_model ┃ ┃ ┃ ┣ 📜user_view_model.dart ┃ ┃ ┃ ┗ 📜user_view_model.g.dart ┃ ┃ ┗ 📂widgets ┃ ┃ ┃ ┣ 📜user_list_widget.dart ┃ ┃ ┃ ┗ 📜user_screen.dart

Slide 34

Slide 34 text

34 📦lib ┣ 📂ui ┃ ┣ 📂core ┃ ┃ ┣ 📂shared ┃ ┃ ┗ 📜theme.dart ┃ ┣ 📂hacker_news ← Feature 1 ┃ ┃ ┣ 📂view_model ┃ ┃ ┃ ┣ 📜hacker_news_view_model.dart ┃ ┃ ┃ ┗ 📜hacker_news_view_model.g.dart ┃ ┃ ┗ 📂widgets ┃ ┃ ┃ ┣ 📜hacker_news_screen.dart ┃ ┃ ┃ ┗ 📜news_list_widget.dart ┃ ┣ 📂user ← Feature 2 ┃ ┃ ┣ 📂view_model ┃ ┃ ┃ ┣ 📜user_view_model.dart ┃ ┃ ┃ ┗ 📜user_view_model.g.dart ┃ ┃ ┗ 📂widgets ┃ ┃ ┃ ┣ 📜user_list_widget.dart ┃ ┃ ┃ ┗ 📜user_screen.dart

Slide 35

Slide 35 text

35 Modularization https://github.com/android/nowinandroid

Slide 36

Slide 36 text

36 apps client_app data domain app package apps client_app repository service domain

Slide 37

Slide 37 text

37 apps client_app packages data domain apps client_app packages repository domain service app package

Slide 38

Slide 38 text

environment: sdk: ^3.6.0 38

Slide 39

Slide 39 text

39 root

Slide 40

Slide 40 text

40 root

Slide 41

Slide 41 text

41 domain

Slide 42

Slide 42 text

42 data

Slide 43

Slide 43 text

43 data

Slide 44

Slide 44 text

44 app

Slide 45

Slide 45 text

45 app

Slide 46

Slide 46 text

46

Slide 47

Slide 47 text

47 https://github.com/JAICHANGPARK/2025_flutter_in_production

Slide 48

Slide 48 text

Thank You 💙 @jaichangpark Flutter Seoul / GDG Golang Korea 박제창 48