プロジェクト開発のベスト・プラクティス(Part1)

Tuyoshi Akiyama
Jul 28, 2017 · 9 min read

以下の記事を参考に、開発におけるガイドラインをまとめていきます。

以下、それぞれの項目ごとのベスト・プラクティスになります。


Git

  • work in a feature branch
    →masterに影響を与えずに、pull-requestを行える為、conflictを起こす心配も減ること
  • branchはdevelopからきること
    →masterは常に既にbuildされた完成された機能を持ったレポジトリの為、いくつかの開発中の機能を使えなくなってしまう。
  • masterとdevelopに直接pushしないこと
    →機能ごとのブランチをきって、pull requestをdevelop,masterに行う
  • feature branchをpush + pull requestする前に、localのdevelopブランチを更新して、rebaseすること
    →rebaseはmearge commitを作成せずにlocalのブランチをremoteのものに更新して、localのコミットを最新のものにすること
  • リベース中およびプルリクエストを行う前に潜在的な競合を解決する
    マージ後、ローカルとリモートの機能ブランチを削除します。
    →feature branchは一度だけdevelopにマージするものですので、開発が終えれば、そのブランチは消して整理をする必要がある。
  • プルリクエストを作成する前に、機能ブランチが正常に構築され、すべてのテスト(コードスタイルチェックを含む)に合格していることを確認。
    →フィーチャブランチテストが失敗した場合、ターゲットブランチビルドも失敗する可能性が高くなります。
  • .gitignore ファイルを使用する、リンクはこちら
    →すでにコードでリモートリポジトリに送信すべきではないシステムファイルのリストがあります。
  • develop/master branchを大事に扱います。
    →プロダクションの準備ができたブランチが予期せぬ不可逆的な変更を受けないよう、保護します。

Git workflow

project directory内でgit repositoryのinitializeをします。

cd <project directory>
git init

git checkout -b <branchname>
git add
git commit -a

↓ remoteのrepositoryと同期します

git checkout develop
git pull

↓ feature branch(pushしたい機能をもつ)をinteractive rebaseで更新

git checkout <branchname>
git rebase -i --autosquash develop

ここのリベース時にに、conflictがある場合
まず、コンフリクトを直してから

git push -f

もし、誰か他の作業者が同じブランチを開発している場合は、 の代わりに使います。

最後にそれぞれlocal/remoteのfeature branchを消します。

git branch -d <branchname>git fetch -p && for branch in `git branch -vv | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done

good commit message

  • subjectとbodyは一行開けて書く
    自身のtext editorをcommit時のメッセージを書くもの設定
git config --global core.editor atom
  • subjectは50文字以内に、bodyは72文字以内にまとめる
    →コミットは可能な限り細かく集中している必要がありますが、冗長な場所ではありません。
  • subjectの文章はCapitalizedする
    →コミッターが何をしたかを示すメッセージを書くのではなく、 これらのメッセージは、コミットがリポジトリに適用された後に何が行われるかの指示と考えるのが良いでしょう。
  • bodyにはなぜそうしたのか、何を変えたのかを書きます。

Documentation

上のテンプレートを使用し、README.mdを書きます。

  • projectsが一つ以上のレポジトリからなるなど、更新がある場合は、READMEファイルにリンクを書き加えていきます。
  • コードに対しては、必ずコメントをつけていきます。
    それはどんな、コードを書いていたとしてもです。
  • コードの変化に合わせて、コメントも変えていきます。

Environments

  • 必要に応じて、development/test/productionの3つの環境を用意します。
    →さまざまなデータ、トークン、API、ポートなどが異なる環境で必要になることがあります。自動化されたテストと手動によるテストの両方をより簡単に行うために、予測可能なデータを返す偽のAPIを呼び出す独立した開発モードが必要な場合があります。また、Googleアナリティクスを本番環境などでのみ有効にすることもできます。
  • 環境変数からデプロイメント固有の設定をロードし、定数としてコードベースに追加しない。
    →そこにはトークン、パスワードなどの貴重な情報があります。いつでもコードベースを公開できるかのように、設定はアプリケーション内部とは、正しく分離されている必要があります。

また、envファイルを使用して変数を保存し、.gitignoreに追加して除外します。代わりに、開発者のためのガイドとなる.env.exampleをコミットします。本番環境では、環境変数を標準的な方法で設定する必要があります。

  • アプリが起動する前に環境変数を検証すること。
    →このサンプルを見て、提供された値を検証するためにjoiを使用してください。

  • package.json内のエンジンにノードのバージョンを設定する
    →他の人がプロジェクトが動作するノードのバージョンを知ることができます。
  • nvmを使用してプロジェクトルートに.nvmrcを作成します。 ドキュメントでそれを言及することを忘れないでください
    →nvmを使用する人は、単にnvm useを使用して適切なノードのバージョンに切り替えることができます。
  • ノードとnpmのバージョンをチェックするプリインストールスクリプトをセットアップすることをお勧めします
    →新しいバージョンのnpmでインストールされた場合、いくつかの依存関係が失敗することがあります。
    可能であればDockerイメージを使用してください。
  • グローバルにインストールされたモジュールを使用する代わりにローカルモジュールを使用する
    →自分のツールを自分のシステム上でグローバルに共有するのではなく、同僚と共有することができます。
  • あなたのチームメンバーがあなたと同じ依存関係になっていることを確認してください
    →コードが期待どおりに動作し、任意の開発マシンで同一であることが必要になります。

Dependencies

  • 現在利用可能なパッケージを追跡します
  • パッケージのインストール前に、そのダウンロード数などを調べて、communityに使われているものかを確認します。
    ,
  • 常にアプリが最新のバージョンかつ、依存関係を壊さずに動作することを確認します
    or
  • パッケージに既知のセキュリティ脆弱性が存在するかどうか、確認します。
    Snyk

Testing

  • 必要に応じてテストモード環境を用意します。
    →生産モードでのE2Eテストだけで機能することもありますが、いくつかの例外があります。たとえば、生産モードで分析情報を有効にし、テストデータで誰かのダッシュボードを汚染したくない場合があります。もう1つの例は、あなたのAPIが実稼働環境でレート制限を持ち、一定量の要求の後でテストの呼び出しをブロックする等があります。
  • * .test.jsまたは* .spec.js命名規則(moduleName.spec.jsなど)を使用して、テストされるモジュールの隣にテストファイルを配置します。
    →単体テストを見つけるためにフォルダ構造を掘り下げないようにします。
  • 追加のテストファイルを別のテストフォルダに入れて、混乱を避けてください。
    →いくつかのテストファイルは、特定のインプリメンテーションファイルには特に関係しません。他の開発者が見つける可能性が最も高いフォルダ、__test__フォルダに配置する必要があります。この名前:__test__も現在標準であり、ほとんどのJavaScriptテストフレームワークで採用されています。
  • テスト可能なコードを書く、副作用を避け副作用を抽出する、純粋な関数を書く
    →別々の単位としてビジネスロジックをテストする必要があります。 「ランダム性と非決定的なプロセスがコードの信頼性に及ぼす影響を最小限に抑える」必要があります。
  • 純粋な関数は、同じ入力に対して常に同じ出力を返す関数です。逆に、不純な関数とは、副作用を伴うか、外部からの条件に依存して価値を生み出します。それはあまり予測できないようになります。
  • 静的型チェッカーを使用する
    →場合によっては、静的型チェッカーが必要な場合もあります。これは、コードに一定のレベルの信頼性をもたらします。
  • プルリクエストを作成する前に、ローカルでテストを実行します。
    →プロダクションの準備ができていないブランチビルドを失敗させない為に、リベースした後、feature branchをリモートリポジトリにプッシュする前に、テストを実行します。
  • README.mdファイルの該当するセクションに、テストのinstructionを文書化する。
    →これは、他の開発者や開発者に向けた、テスト方法を記したメモになります。

参考リンク

    Tuyoshi Akiyama

    Written by

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade