01/10 04:32 2021
01/17 10:35 2021
ある程度サービス開発を続けているとリポジトリを跨いだ処理の共通化、ライブラリを作成する必要がある。Node.js/TypeScriptでは、npmを利用することでバージョン毎にビルド済資材を管理でき、非常に便利。
一方で13人のチームでライブラリが34つあった場合にそれぞれリポジトリを分けて管理すると、リリースタスクが非常に煩雑。例えば..
本記事では1つリポジトリで、なるべく人の手を使わずに複数のnpmモジュールのリリース管理をする方法について書く。以下注意点。
リポジトリ。複数のパッケージでJavaScriptプロジェクトを管理するためのツール。Babel、React、Angular、 Ember、Meteor、Jestといったツールで利用されている。
下記の記事を参考にした。ここは時間のあるとき再考したい。
lernaのみで管理することも可能だが下記の点でYarn Workspacesと併用することとした
yarn addによるパッケージ追加が出来なくなる。lernaコマンド経由でのパッケージインストールは少し癖があると感じたパッケージ共有でインストール場合はコマンドは下記
lerna add eslint
任意のパッケージのみで利用したい場合は、scopeを設定する必要がある
lerna add lodash --scope lib-a
併用すれば、各パッケージルートでyarn add出来るため、慣れているやり方でパッケージ追加/削除が可能となる。
人間と機械が読みやすく、意味のあるコミットメッセージにするための仕様
本仕様に従うことで、lernaでセマンティックバージョニングベースでのリリースバージョン推論が可能となる。
フォーマットは下記。optionalは任意項目。
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
各項目で名付け規則が存在する。コミットする際には、こちらのルールを参考にしたい。
Conventional Commitsを通して、下記ようにバージョン推論が行われる
MAJORバージョンがインクリメントされるのは、bodyまたはfooterにBREAKING CHANGE:がある場合MINOR PATCHバージョンがインクリメントされるのは、下記の表参考| type名 | 説明 | 補足 |
|---|---|---|
| build | ビルド設定 | |
| ci | CI設定 | |
| chore | 雑事(カテゴライズする必要ないようなもの) | |
| docs | ドキュメント | |
| feat | 新機能 | MINORバージョンに該当 |
| fix | バグフィックス | PATCHバージョンに該当 |
| perf | パフォーマンス | |
| refactor | リファクタリング | |
| revert | コミット取り消し(git revert) | |
| style | コードスタイル修正 | |
| test | テスト |
# ドキュメントを更新した場合
docs(readme): 起動方法を変更
# 新機能を追加した場合(scopeは無理してつける必要なし!)
feat: 起動方法を変更
# renovateが自動アップデートした場合
chore(deps): update dependency @types/jest to v26.0.20
詳細設定はリポジトリを参考にして欲しい
lerna.json
{
"npmClient": "yarn", // npmクライアントにyarnを指定
"useWorkspaces": true, // Yarn Workspacesを有効化
"packages": [
"packages/*"
],
"version": "independent" // ①
"command": {
"version": {
"message": "chore(release): publish", // ②
"conventionalCommits": true // conventionalCommitsを使ったリリーズバージョン推論の有効化
}
},
}
lernaには、下記のモードが存在する
前者はモノレポ配下のパッケージを1つのバージョンで固定する方法。後者はパッケージ毎に任意のバージョンが指定可能。今回は、Independent modeを指定。
messageオプション。lerna versionをするときにlernaはコミットのバージョンをインクリメントして、CHANGELOG.mdを更新してコミットを作る。そのコミットに指定するメッセージを定義出来る。
Fixed/Locked modeであれば、メッセージに%sが含まれている場合は、「v」で始まる新しいグローバルバージョンのバージョン番号。%vが含まれている場合、先頭に「v」が付いていない新しいグローバルバージョンのバージョン番号に置き換えることが可能。
{
"command": {
"version": {
"message": "chore(release): publish %s"
}
}
}
後述のcommitlintを設定している場合、デフォルトだとルール違反と判定されてlerna versionが失敗します。commitlintと併用する場合は設定が必要。
Conventional Commitsに従っているか人の目で確認するのは難しいため、commitlintを利用。 .commitlintrc.json
{
"extends": ["@commitlint/config-conventional"]
}
commitlintのルールは、@commitlint/config-conventionalの他にも@commitlint/config-angularがある。今のところ違いがよくわからないため、追加で調査したい。
コミットをする際に、commitlintとeslintが走るように設定する。 .huskyrc.json
{
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "yarn lint:fix"
}
}
共通利用するパッケージをインストールする。WオプションはYarn Workspaces内にパッケージの追加をすることを表しています。
yarn add -D -W @typescript-eslint/eslint-plugin
各パッケージでyarn buildが実行されます。
lerna run build # yarn buildに設定するとよい
Independent modeの場合、更新のあるパッケージのバージョンインクリメントをします。最初にバーションを対話式で選んだら、tag打ち、CHANGELOG.mdの更新をしコミットを打ってpushするとこまで自動で行います。
lerna version
publishコマンドを利用する
lerna publish # 前回のリリース以降に変更されたパッケージを公開する
lerna publish from-git # 現在のコミットでタグ付けされたパッケージを明示的に公開する
lerna publish from-package # 最新バージョンがレジストリ(npm)に存在しないパッケージを明示的に公開する
from-gitのユースケースは正直よくわからない。タグベースでリリースの公開制御するのはデメリットが大きいと考えている。例えばleran versionは成功し、npmにログインしておらず、leran publishに失敗した場合にタグを削除しないとpublishすることが出来ないなど..。
from-packageを使えば漏れなくパッケージ公開可能なので、今回採用した。
npm-scriptsを利用し、新規リリースをする場合はビルドとバージョンアップとパッケージ公開はyarn releaseにまとめている。
"scripts": {
"build": "lerna run build",
"test": "lerna run build",
"lerna:pub": "lerna publish from-package",
"lerna:version": "lerna version",
"release": "yarn build && yarn lerna:version && yarn lerna:pub",
"lint:ts": "eslint --ext=.ts .",
"lint:fix": "yarn lint:ts --fix"
},
特定のCHANGELOGを抜き出す
yarn monorepo-utils-collect-changelog --directory . "@sugoi-site/lib-a@0.4.0"
出来ていないこととして、GitHub ReleaseへCHANGELOGの書き出しがあり、ここは色々試してみる予定です。実際に個人ブログのCSSやマークダウンのパースライブラリを本記事の方法で管理します。その過程で使い辛い点は見直して、本記事に反映します!!
This site uses Google Analytics.