コントリビュート
Crowi 2.0 の開発に参加するための開発フロー・規約ガイド
このページは、Crowi 2.0 のコードベースに変更を加えるための開発フローと 規約をまとめたものです。開発環境のセットアップ自体は 開発環境をつくる を先に済ませてください。
開発コマンド
スクリプトはリポジトリルートと各パッケージの package.json に定義されて
います。pnpm <script> は Turborepo によって自動でパッケージを絞り込み
ます。
| コマンド | 用途 |
|---|---|
pnpm dev | api + web + プラグインを並行起動 |
pnpm dev:api / pnpm dev:web | 片側だけ起動 |
pnpm test | 全パッケージのテスト (api は Jest + supertest。CI では services.mongo コンテナを利用、ローカル開発時は mongodb-memory-server にフォールバック) |
pnpm type-check | 型チェック (api + web + site) |
pnpm lint | Lint。errors=0 が必須 (warning は許容) |
pnpm format | Biome によるフォーマット |
pnpm build | 全パッケージのビルド |
特定のパッケージだけ動かしたいときは
pnpm --filter @crowi/api <script> のように絞り込めます。
Tip: API 契約 (
packages/api-contract) を編集したら、pnpm --filter @crowi/api-contract buildで dts を再生成してください。 turbo パイプラインはdev/build/testで^buildを自動実行 しますが、単発のスクリプトでは手動が必要になることがあります。
Lint と Format
Crowi は Biome をフォーマッタに、ESLint を Linter に使い分けて います。
- Lint は
pnpm lintで実行され、エラー 0 が必須です。warning は 許容されますが、エラーは pre-push フックで弾かれます。 - Format は Biome が担当します。ステージされたファイルに対して
pre-commit フックが自動実行するため、通常は手動実行は不要です。
フックをバイパスした場合のみ
pnpm formatを使ってください。 - 既存の
anyを見かけても、無関係なコードまで巻き込んで直さないで ください。差分は触っている範囲に絞ります。新たなanyの追加は 避けてください。
lefthook フック
Git フックは lefthook で管理され、pnpm install 時に自動でセットアップ
されます。
| フック | 内容 |
|---|---|
| pre-commit | ステージされたファイルに Biome フォーマットを適用 |
| pre-push | pnpm lint (errors=0 必須) と pnpm build を実行。packages/api-contract/** に変更があるときは pnpm check:openapi も実行 |
コミットメッセージ
コミットメッセージは Conventional Commits 形式に従います。
feat(api): add page export endpoint
fix(web): correct notification bell badge count
refactor(merge): deduplicate ws token signer
chore(config): bump dev ports
docs(site): document attachment thumbnails- 型は
feat/fix/refactor/chore/docsなどを使い、 スコープにapi/web/api-contractなどを書きます。 - 変更の意図が自明でないときは、なぜその変更をしたのかを説明する 本文を複数段落で添えてください。
Changesets
リリースノートの蓄積には @changesets/cli を使います。v2 開発中も
pnpm changeset add で各変更を .changeset/*.md として蓄積していき、
将来のリリース時にリリースノートが自動生成されます。
- changeset は「ユーザー価値の単位」で 1 つ作ります。機能追加・バグ修正・ 破壊的変更が対象です。
- 内部リファクタ・コード整理・lint 修正・フォーマット・テスト追加だけ、 あるいはドキュメント更新だけの変更には changeset は不要です。判断基準は 「次の changelog に書いて意味があるか」です。
- bump レベルは、バグ修正なら
patch、新機能ならminor、破壊的変更 ならmajorを選びます。
pnpm changeset add # package + bump レベル + 概要を対話的に選ぶ
pnpm changeset status # 蓄積された未公開 changeset 一覧TypeScript の指針
- 新たな
anyは追加しません。anyのあるコードを触るときは、機を見て 適切な型へ少しずつ置き換えます。 - 1 つの変更で無関係なコードを巻き込まず、差分は焦点を絞ります。
- フィールドの再定義より
Pick<>/Omit<>を優先します。 - Mongoose ドキュメントの型は
models/xxx.tsのXxxDocumentを import します。
ローカルでの動作確認
ふだんの pnpm test では動かさない、手で立ち上げて確かめる類の検証をまとめます。
共同編集を 2 レプリカで確かめる
同梱の compose 構成から実際に 2 レプリカを立てます。準備は 2 点です — api の固定ホストポート公開を外すこと (レプリカ間で衝突します) と、全レプリカが同じ WS_TOKEN_SECRET を読むように .env に書いておくことです。
# 1. スケール用の override (ホストポート公開を外し、複数レプリカを宣言する)
cat > compose.scale.yml <<'YAML'
services:
api:
ports: !override []
environment:
CROWI_MULTI_INSTANCE: "2"
YAML
# 2. api を 2 レプリカで起動
docker compose -f docker-compose.yml -f compose.scale.yml --profile app up -d --scale api=2
# 3. 2 つ立っていることを確認
docker compose ps api2 つのブラウザウィンドウで同じページを開き、それぞれの編集が相手に伝わること、片方のレプリカを止めても再接続して編集が続けられることを確認します。想定される挙動と既知の制約は リアルタイム共同編集の運用 を参照してください。
GCS ストレージドライバをエミュレータで確かめる
GCS ドライバのテストは、通常の CI では起動しない opt-in のエミュレータサービスを使います。
docker compose --profile gcs-test up -d crowi-test-gcs
STORAGE_EMULATOR_HOST=http://127.0.0.1:4443 pnpm --filter @crowi/api test -- --runInBand src/plugin/storage-gcs.emulator.test.ts
docker compose --profile gcs-test stop crowi-test-gcsエミュレータが検証するのは、アップロード・ダウンロードの往復、オブジェクト名のマッピング、冪等な削除、存在しないオブジェクトの扱い、ローカルから GCS へのコピーです。匿名リクエストを受け付けるだけなので、認証情報の解決や IAM 権限、署名付き URL の可否は再現しません。 そこまで確かめるには実際の GCS バケットが必要です。
Slack 連携をトンネル越しに確かめる
Slack は localhost に到達できないため、ngrok や cloudflared などのトンネルで Crowi を公開します。生成される manifest の request URL をトンネルの公開 URL にするには、環境変数 SLACK_MANIFEST_REQUEST_URL にその公開オリジン (例: https://abc123.ngrok.app) を設定してください。未設定なら CLIENT_URL が使われます。
新しいエンドポイントを追加するには
レガシーの Express + ts-rest スタックは RFC-0006 で完全に廃止されました (2026-05-22 完了)。新しいエンドポイントを追加するときは以下の手順に 従ってください。
packages/api-contract/src/配下に Zod スキーマとcreateRoute定義 (@hono/zod-openapi) を追加します。packages/api/src/hono/handlers/配下にハンドラを実装します (管理系 はhono/handlers/admin/配下)。hono/app.tsでハンドラを Hono アプリに組み込み、必要なミドルウェアをhono/middleware/に追加します。- Web 側からは、契約から生成された
apiClientV2(型付き Hono RPC クライアント、createClientが返すCrowiApiClient型) 経由でエンドポイントを呼び出します。
Crowi 2.0 全体のフェーズ状況はリリースノートに反映されて います。
関連ページ
- 開発環境のセットアップ → 開発環境をつくる
- アーキテクチャ全体像 → アーキテクチャ
- 設計提案の一覧 → RFC インデックス