【Next.js】チーム開発までの環境整備手順
はじめに
初めまして、現在エンジニアをしながら起業をしてサービスを開発中の橋田至です。
私は今Swappyという同人誌のフリマサイトを開発中です。
初めは一人で開発をしていたのですが、開発すべき機能が多すぎることに気づき、共同開発者を募集しました。
その結果、現在約10名ほどのメンバーがアクティブに開発しています。
チーム開発の難しさ
一人で開発するなら自分だけがコードを読めて理解できたら良いです。
しかし、チーム開発となると統一されたコーディング規約やルールが必要になります。
今回は、個人開発レベルをチームで行う際の環境整備手順を記事にしました。
参考になれば幸いです。
技術スタック
- Next14(App Router)
- TypeScript
- Prisma
- tailwindcss
- daisy UI
他:MongoDB・Vercel・git,github・NextAuthなど
pull_request_templateの作成
PR作成時のテンプレートです。
以下例
<!-- この記号(<!-- と -->)で囲まれた部分はコメントです。この記号より外に書いてください。 -->
# What's changed
<!--
このプルリクで何をしたのかを記入してください。
画像とテキストを使って説明するのがおすすめです。
CodeRabbitがある程度作ってくれるので、人間がわかりづらい部分の補足を書きます -->
<!-- Fix #IssueNumber -->
<!-- 上記のコメントアウトを外してIssueNumberを入れると、PRがマージされたら自動的にそれに紐づくissueがクローズされるようになります -->
## Todo List
<!-- 今回のプルリクでまだやっていないことや、将来やる予定の事項を記入してください -->
<!-- 以下のうち今回のPRにあてはまるものをコメントの外に出してください
- [ ] デザイナーに確認してもらいます
- [ ] iOS 16のデバイスにテストします
- [ ] テストケースを書きます
-->
## Check List
- [ ] developブランチから派生しています
- [ ] テストが全て通りました
- [ ] ESLintはエラーや警告は出ませんでした
- [ ] `pnpm run build`を使ってエラーは出ませんでした
- [ ] CodeRabbitのレビューを対応し、対応済みのものはResolveしました
- [ ] UI系の変更を伴う場合はPCとスマホの画面のスクショを貼りました
## Remark
<!-- 補足事項 -->
ブランチ保護ルール
githubのリポジトリのsettingからブランチ保護ルールを設定できます。
公式のドキュメントを見ても位置が変わっていたりしたので注意が必要です。
.github/workflows/branch_restrictions.yml
name: Branch Restrictions
on:
pull_request:
branches:
- main
jobs:
check_base_branch:
runs-on: ubuntu-latest
steps:
- name: Fail if not from develop branch
run: |
if [[ "${{ github.event.pull_request.head.ref }}" != "develop" ]]; then
echo "Error: PRs to main must come from the develop branch."
exit 1
fi
READMEやwikiの作成
READMEには環境構築手順を記載し、wikiにその他情報をまとめました。
ESLintの設定
例
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: ["tsconfig.json"],
tsconfigRootDir: __dirname,
sourceType: "module",
},
plugins: ["@typescript-eslint/eslint-plugin", "tailwindcss", "jsdoc"],
extends: [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"plugin:tailwindcss/recommended",
"prettier",
"plugin:jsdoc/recommended-typescript-error",
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ["./next*", "**/*.js", "**/*.cjs", "pnpm-lock.yaml"],
rules: {
"no-restricted-syntax": [
"error",
"TSEnumDeclaration",
"TSInterfaceDeclaration",
"ForInStatement",
"ForOfStatement",
"LabeledStatement",
"WithStatement",
"VariableDeclaration[kind='let']",
],
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "warn",
"jsdoc/tag-lines": "off",
"jsdoc/no-types": "off",
"jsdoc/require-param": [
"error",
{
checkDestructuredRoots: false,
},
],
"jsdoc/check-param-names": [
"error",
{
checkDestructured: false,
},
],
"jsdoc/require-jsdoc": [
"error",
{
publicOnly: true,
require: {
FunctionDeclaration: true,
MethodDefinition: true,
ClassDeclaration: true,
ArrowFunctionExpression: true,
FunctionExpression: true,
},
},
],
"jsdoc/require-returns": "off",
"jsdoc/require-returns-description": "off",
"jsdoc/require-description": [
"error",
{
descriptionStyle: "body",
},
],
},
};
Prettierの設定
tailwindcssを使用する場合は以下の記述を推奨
// prettier.config.js
module.exports = {
plugins: ['prettier-plugin-tailwindcss'],
}
CodeRabbitのレビュー
AIがコードレビューしてくれるサービスです。
使用している感じ神ですが、たまに変な指摘をしてくるので、プロンプトは適宜修正することを推奨します。
.github/workflows/ai-review.yaml
name: ai-pr-reviewer
permissions:
contents: read
pull-requests: write
on:
pull_request:
types: [opened, synchronize, reopened]
branches-ignore:
- master
- main
pull_request_review_comment:
types: [created]
issue_comment:
types: [created]
concurrency:
group: ${{ github.repository }}-${{ github.event.number || github.head_ref || github.sha }}-${{ github.workflow }}-${{ github.event_name == 'pull_request_review_comment' && 'pr_comment' || 'pr' }}
cancel-in-progress: ${{ github.event_name != 'pull_request_review_comment' }}
jobs:
review:
runs-on: ubuntu-latest
if: (github.event_name == 'issue_comment' && contains(github.event.comment.body, '[run review]') && github.event.issue.pull_request) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '[run review]')) || (github.event_name == 'pull_request' && !contains(github.event.pull_request.title, 'release') && !contains(github.event.pull_request.title, 'Release'))
timeout-minutes: 15
steps:
- uses: coderabbitai/openai-pr-reviewer@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
with:
debug: false
review_simple_changes: false
review_comment_lgtm: false
openai_light_model: gpt-4-1106-preview # 好みで変更
openai_heavy_model: gpt-4-1106-preview # 好みで変更
openai_timeout_ms: 900000 # 15分.
language: ja-JP
path_filters: |
!db/**
!**/*.lock
system_message: |
回答は日本語で書いてください。
あなたは @coderabbitai(別名 github-actions[bot])で、OpenAIによって訓練された言語モデルです。
あなたの目的は、非常に経験豊富なソフトウェアエンジニアとして機能し、コードの一部を徹底的にレビューし、
以下のようなキーエリアを改善するためのコードスニペットを提案することです:
- ロジック
- セキュリティ
- パフォーマンス
- データ競合
- 一貫性
- エラー処理
- 保守性
- モジュール性
- 複雑性
- 最適化
- ベストプラクティス: DRY, SOLID, KISS
些細なコードスタイルの問題や、コメント・ドキュメントの欠落についてはコメントしないでください。
重要な問題を特定し、解決して全体的なコード品質を向上させることを目指し、細かい問題は意図的に無視してください。
以下は指摘しない:
- use client,use server directive
- function recieved by form action attribute
- async component
- Link > a
- hooks export static component
- async function throws error
- React.cache
- next/navigation
- FaSquareXTwitter
回答は日本語で書いてください。
summarize: |
次の内容でmarkdownフォーマットを使用して、最終的な回答を提供してください。
- *ウォークスルー*: 全体の変更についての80語以内の高レベル要約。
- *変更点*: ファイルと要約のテーブル。同様の変更を持つファイルを1行にまとめてスペースを節約。
GitHubのプルリクエストにコメントとして追加されるこの要約には、追加のコメントを避けてください。
summarize_release_notes: |
このプルリクエストの目的とユーザーストーリーに焦点を当て、markdownフォーマットで簡潔なリリースノートを提供。変更は次のように分類し箇条書きにすること:
"New Feature", "Bug fix", "Documentation", "Refactor", "Style",
"Test", "Chore", "Revert"
例えば:
```
- New Feature: UIに統合ページが追加されました
```
回答は50-100語以内にしてください。この回答はそのままリリースノートに使用されるので、追加のコメントは避けてください。
Slack(Discord)ルールの作成
私の場合は以下のようなチャンネルを作成しています。
VSCodeの設定
拡張機能のインストールを推奨します。
.vscode/extensions.json
{
// 拡張機能がインストールされていない場合、インストールの推奨を表示
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"github.vscode-pull-request-github",
"vscode-icons-team.vscode-icons",
"bradlc.vscode-tailwindcss"
]
}
.vscode/settings.json
{
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": true
},
// デフォルトのフォーマッターに prettier を指定
"editor.defaultFormatter": "esbenp.prettier-vscode",
// 保存時に prettier によって整形
"editor.formatOnSave": true,
// インポートを絶対パス優先に
"typescript.preferences.importModuleSpecifier": "non-relative",
"[prisma]": {
"editor.defaultFormatter": "Prisma.prisma"
}
}
最後に
その他にも「こうすれば良いよ!」などの設定などありましたらお声かけいただけると嬉しいです!
また、Swappyの開発者は随時募集しておりますので、気軽にDMください!!
参考
Discussion