monorepo/docker環境で、Railsのvscodeでの開発を快適にする


これはなに

私はいつも vscode を使って開発してるんですが、いまのプロジェクトでフロントエンドは prettier でいつもサクサク快適に自動フォーマットされるのと比べ、Railsのコード編集が重くてつらいなあと思っていたのです。

主に rubocop が重い(formatに数秒かかる)からなので、rubocop-daemon を使って快適にしたいなあと思ったのでした。

vscode の remote container 拡張を使えばいい感じにできるかな?と思ったので試してみたのが今回の記事になります。

出来上がりのリポジトリ

APIサーバは Rails7, フロントエンドは Next.js 12 (Chakra-UI, React-Query) で、 docker composeで構成した monorepo になります。

https://github.com/coji/monorepo-rails-next-docker-boilerplate

clone したあと docker compose up で起動できます。

また、このディレクトリを vscode で開くと remote container で開き直すか?というダイアログが出るので、そうすると docker 環境で vscode が開き、ソースコードフォーマットや solargprah によるクロスリファレンスなどが快適に動作します。

やったこと

rubocop-daemon を docker 環境で動作させる

rubocop-daemon-wrapper を api/bin/rubocop という名前で保存し alpine で動くように一部改造して chmod +x しています。

https://github.com/coji/monorepo-rails-next-docker-boilerplate/blob/main/api/bin/rubocop#L22

改造したのは22行目のこちら。 alpine Linux だと OSTYPE が linux-musl になるのですが、rubocop-daemon のメンテナさんが非アクティブになっちゃったようで issue にも書かれておらずだったので一旦手元で書き換えて動かしました。

rubocop
elif [[ "$OSTYPE" == "linux-musl" ]]; then # docker で動くようにとりあえず
  NETCAT_CMD="nc"

vscode remote containerの設定

以下のようにしました。

.devcontainer/devcontainer.json
{
  "name": "Existing Docker Compose (Extend)",
  "dockerComposeFile": ["../docker-compose.yml", "docker-compose.yml"],

  "service": "api",
  "workspaceFolder": "/api",
  "settings": {
    "ruby.useLanguageServer": true,
    "ruby.useBundler": true,
    "ruby.format": "rubocop",
    "ruby.lint": {
      "rubocop": {
        "useBundler": true,
        "except": ["Metrics"] // because it is annoying that it puts wavy lines to all lines in those methods
      }
    },
    "ruby.rubocop.executePath": "./bin/", // rubocop-daemon-wrapper (rubocopに名前変更) のパス
    "editor.defaultFormatter": "misogi.ruby-rubocop",
    "[ruby]": {
      "editor.formatOnSave": true
    },
    "editor.formatOnSaveTimeout": 5000,
    "solargraph.useBundler": true,
    "solargraph.bundlerPath": "/usr/local/bin/bundle"
  },
  "extensions": [
    "rebornix.ruby",
    "wingrunr21.vscode-ruby",
    "visualstudioexptteam.vscodeintellicode",
    "redhat.vscode-yaml",
    "castwide.solargraph",
    "misogi.ruby-rubocop"
  ],
  "runServices": ["api", "db"],
  "postCreateCommand": "bundle exec yard gems && rubocop-daemon start" // gem の中身まで solargraph で補完
}
.devcontainer/docker-compose.yml
version: '3.8'
services:
  api:
    volumes:
      - ~/.config/git:/root/.config/git

    command: /bin/sh -c "while sleep 1000; do :; done"

なんとかしたいこと (残件)

docker 環境で vscode が快適に動作してだいぶ快適になったんですが、monorepo のサブディレクトリを指定して開く感じになるので、親ディレクトリにある.git ディレクトリが見えなくなり、vscode の git 機能が使えなくなっちゃって悲しいです。 blame とか history とか結構みてたので。。

というわけで、monorepo + vscode remote container の環境で git を快適に使える方法を引き続き探しています。ご存知のかたいらっしゃればコメントいただけると嬉しいです。