Calmery.me

みっかぼうずにならないようがんばる

良さげな開発環境を作る

最近やっていることをまとめる.忘れないようにメモ.適宜更新したい.

何をしているの

身内で使用するための Twitter のアカウントに紐づいた Web アプリケーションを開発している.

ここではサーバ側とクライアント側で完全にコードを分けている.サーバーサイドレンダリングとかはしてない.サーバ側は REST API っぽく Node.js,Express を使用して開発して,クライアント側は React を使用して開発している.認証周りは Firebase の Twitter 認証,認証後はサーバ側で API キーを発行してヘッダーに X-Api-Key を追加してやり取りを行う.データ自体は Postgres に,Node.js の Sequelize を使って良しなに管理している.

ちなみにサーバ側は Heroku を使用して,クライアント側は GitHub Pages を使用している.

色々

使っているツールとかをまとめる.アルバイト先で教えて頂いたものが多い.

見た目を整える

クライアント側の見た目は material-ui を使用している(どこかに使用できるアイコンまとめないかな?)

認証する

Firebase を使用している.クライアント側で Twitter にログインして発行されるトークンをサーバ側に送ってサーバ側は firebase-admin - npm を使用してそのトークンを認証する.認証できたら uid が取得できるのでそれをデータベースに保存するという感じ.サーバ側は認証後にクライアント側に API キーを返して,クライアント側はリクエストを行うときにこの API キーをヘッダーの X-Api-Key に追加するようにしている.

データベースは Heroku 上でも使える Postgres を使用している.Sequelize を TypeScript から使える sequelize-typescript - npm が良さげだった.

自動デプロイする

サーバ側もクライアント側も GitHubリポジトリに変更を加えられたときに自動でデプロイするようにしている.

クライアント側

CircleCI を使用してリポジトリに変更が加えられた際にテストとビルドを実行する.master に限ってはビルドの後にデプロイまで実行される.GitHub - facebook/create-react-app: Create React apps with no build configuration. を使用しているのでテストとビルドに関しては react-scripts をそのまま利用する.デプロイに関しては gh-pages というブランチにビルドで作成された build というフォルダの内容を GitHub 上の gh-pages というブランチに追加すれば良いので gh-pages - npm を使用して良しなにやっている.また gh-pages ブランチでは CircleCI を実行したくないのでコミットのコメントに [skip ci] を加えている.Skipping and Cancelling Builds - CircleCI を見ればわかる.

package.json の内容はこんな感じ.

{
  "scripts": {
    "test": "react-scripts test --env=jsdom",
    "build": "react-scripts build",
    "deploy": "gh-pages -d build -m \"Updates\nCircleCI [skip ci]\""
  }
}

長くなるので jobs 部分は省略するけど CircleCI で使用する config.yml はこんな感じ.

...
workflows:
  version: 2

  test-build-and-deploy:
    jobs:
      - test:
          filters:
            branches:
              ignore: gh-pages

      - build:
          requires:
            - test

      - deploy:
          requires:
            - build

          filters:
            branches:
              only: master

使用している外部サービスが CircleCI だけなので簡単で作りやすい.

サーバ側

Node.js を使用して TypeScript,Express で開発しており,テストには Jest を使用している.基本的にはクライアント側とほとんど同じだが,こちらは Heroku にデプロイする必要があるので CircleCI で行うのはテストとビルドまでで,デプロイは Heroku の Automatic deploys を使用して行なっている.Automatic deploys の Wait for CI to pass before deploy にチェックを入れておくと CircleCI の処理が終わるまで待ってくれるので良い.

f:id:calmery:20180704220837p:plain

package.json はこんな感じ.Heroku の Automatic deploys は GitHub 上のコードを使用してデプロイを行おうとするので package.json の scripts に heroku-postbuild を追加してそこでビルドを行うようにする.

{
  "scripts": {
    "test": "jest --forceExit --coverage --verbose",
    "build": "rimraf dist/ && tsc",
    "heroku-postbuild": "npm run build"
  }
}

サーバ側はステージングとプロダクション環境で分けており,どちらも Automatic deploys で同時にデプロイされる.これステージングがもはやステージングと言えるのかが怪しい.ただ使用する Postgres のデータベースは分けているので壊せる環境としてある感じ.

レビューしやすくする

クライアント側は GitHub 上でプルリクエストを出した際に Heroku の Review Apps で自動で動作する環境を作ってくれる.Heroku Review Apps now Generally Available | Heroku を見るとわかりそう.コードのレビューと動作のレビューを同時に行えるので良い.ちなみにここで作った環境からはサーバのステージングの環境を使用するようになっている.ステージング云々というよりは,このためにサーバの環境を分ける必要があった.

ちなみにプルリクエストを作成して時間経過,またはプルリクエストのクローズでレビューのための環境は自動で壊される.Personal の場合はクレジットカードの登録で Free プランでも 1000 時間稼働させることができるし,小規模であればこれで全然良さそう.

app ドメインを使う

app ドメインを使うには HTTPS の使用が必須となっている.今回は GitHub Pages が HTTPS に対応しているのでリポジトリの設定から Enforce HTTPS にチェックを入れるだけで良い.

Heroku に関しては Hobby 以上でないとカスタムドメインSSL が使用できないので今はそのまま Heroku のアドレスを使用している.

まとめ

めっちゃ便利になったし感動してる.