Flutter/Dartでもモノレポで運用したいなと思って、
いろいろ調べたときの備忘録(*´ω`*)
FlutterFireやFlameなどでも使われている。
FlutterFire CLIなどでおなじみのInvertase社製。
Melosの機能
トップページに書いてある機能はこのあたり
- ローカルパッケージのリンクとインストール
- パッケージ間でのコマンドの実行
- ローカルパッケージやそのdependenciesの表示
- pub.devへのパッケージ公開
- versioningとchangelogの生成
Node.jsまわりだと、pnpm/lerna-lite/turborepoといった感じ
ディレクトリ構成
おすすめのディレクトリ構成はこんな感じ。
my_project ├── apps │ ├── apps_1 │ └── apps_2 ├── packages │ ├── package_1 │ └── package_2 ├── melos.yaml ... melosの設定ファイル ├── pubspec.yaml ... ワークスペースrootのpubspec.yaml └── README.md
pubspec.yaml
pubspec.yaml
はこんな感じ。dartのsdk設定のみ。
name: my_project environment: sdk: '>=3.0.0 <4.0.0'
melos.yaml
melos.yaml
はこんな感じ。
対象のpackageのパスやコマンドを設定できる。
FVMを使っているので、SDKのパスも設定
name: my_project # 対象とするpackageの設定 packages: - apps/** - packages/** # melos runで実行するコマンドの設定 scripts: analyze: exec: dart analyze . # SDKのパス sdkPath: .fvm/flutter_sdk
設定できる内容はこのあたりに
FVM v3だと.fvm/flutter_sdk
がなくなっているらしいけど、
sdkPath
がなくても大丈夫っぽい。
初期設定/bootstrap
とりあえず、初期設定コマンドを実行
# global install版(おすすめ) $ dart pub global activate melos $ melos bootstrap # local install版 $ fvm flutter pub add dev:melos $ fvm flutter pub get $ fvm dart run melos bootstrap
実行すると、
- dependenciesのpackageをinstall(
pub get
) - パッケージ内の依存関係を解析して
pubspec_overrides.yaml
を作成
pubspec_overrides.yaml
は開発時はローカルのパスを見るように、
dependenciesを上書きしてくれるやつ
たとえば、こんな感じで書いているのがあると、
# apps/apps_1/pubspec.yaml dependencies: package_1: path: ../../packages/package_1
こんな感じのファイルが作成される。
# apps/apps_1/pubspec_overrides.yaml dependency_overrides: package_1: path: ../../packages/package_1
このpubspec_overrides.yaml
がある状態で、
fvm flutter pub get
を実行すると
$ fvm flutter pub get ! package_1 0.0.1 from path ../../packages/package_1 (overridden in ./pubspec_overrides.yaml)
という感じになり、pubspec_overrides.yaml
の設定が参照されるようになる。
そのため、apps/apps_1/pubspec.yaml
側では、
path
の指定が不要になる。
# apps/apps_1/pubspec.yaml
dependencies:
package_1:
- path: ../../packages/package_1
shared dependencies
利用するパッケージのバージョンを揃えたいときにも使える。
こんな感じで、Dart/Flutterのバージョンや、
各dependenciesで揃えたいパッケージを記載してから、
fvm dart run melos bootstrap
を実行すると、
各パッケージのpubspec.yaml
を上書きしてくれる。
# melos.yaml command: bootstrap: environment: sdk: ">=3.0.0 <4.0.0" flutter: ">=3.0.0 <4.0.0" dependencies: collection: ^1.18.0 dev_dependencies: build_runner: ^2.3.3
各種コマンド
# 長いのでalias $ alias fvm-melos="fvm dart run melos bootstrap"
list: パッケージの一覧を表示
$ fvm-melos list $ fvm-melos list -l # 詳細版(ver/privateなど) $ fvm-melos list --graph # 依存関係グラフのjson表記 $ fvm-melos list --cycles # 循環参照のチェック
exec: 各パッケージで同じコマンドを実行
$ fvm-melos exec flutter pub get $ fvm-melos exec -- "flutter pub get && flutter pub run build_runner build"
run: scriptsのコマンドを実行
melos.yaml
のscriptsに定義したコマンドを実行する。
exec
で定義したコマンドはexecとして実行される。
# melos.yaml scripts: # rootで実行 hello: echo 'Hello $(dirname $PWD)' # 各パッケージで実行 print: exec: echo 'Hello $(dirname $PWD)'
実行はこんな感じ
$ fvm-melos run hello
$ melos run print
ただ、fvm dart run melos run print
だと実行できないので、
グローバルインストールしたmelos
じゃないとだめっぽい。。
version: version変更/commitlog生成
versionの一括変更などしてくれるコマンド
# 自動バージョン変更 $ fvm-melos version # 手動での変更 $ fvm-melos version --manual-version=foo:patch $ fvm-melos version --manual-version=foo:1.0.0
詳しいガイドはこのあたりに。 - Automated Releases
自動でのバージョンアップは、Conventional Commitsが採用されていて、
feat
やfix
などから次のバージョンを選択してくれる。
gitのタグ付け(--git-tag-version
)や--preid
、--prerelease
などにも対応
melos.yaml
にcommand/version
の設定もある
publish: pub.devへの公開
$ fvm-melos publish --dry-run $ fvm-melos publish --no-dry-run
詳しいガイドはこのあたりに - Automated Releases
こちらにも--git-tag-version
のオプションがある
filtering
特定のpackageにのみ対して実行したい場合は、
filteringのオプションを利用すればOK
# マッチしたpackage名のみで実行 $ melos exec --scope="*example*" -- flutter build ios # マッチしたpackage名以外で実行 $ melos exec --ignore="*internal*" -- flutter build ios # flutter packageのみ実行 $ melos exec --flutter -- flutter test # 特定のpackageを利用しているもののみ実行 $ melos exec --depends-on="flutter" --depends-on="firebase_core" -- flutter test
以上!! なんとなくわかった気がする。。(*´ω`*)