AI時代になって、個人開発はずいぶん楽になった。それなのに、開発環境は相変わらずだるい。最近、そんなことをよく考えている。というのも、AIを使うようになってから、複数のプロジェクトを同時に触ることがめっきり増えたからだ。

WebアプリAを作りながらWebアプリBにも手を入れ、CLIを書き、APIサーバーも少しいじる。以前ならどれか一つに絞っていたことを、今は平然と並行して進めている。一つのアプリでWorktreeを使い、複数の機能を並行開発する人もいるだろう。だが僕の場合は、複数のアプリケーションを同時に抱えることの方が多い。

昔なら「まあ面倒だしいいや」で終わっていたものでも、AIに相談しながら進めれば、とりあえず動くところまでは持っていける。設計をざっくり考え、最初の実装をして、ローカルで動かしてみる。そこまでのハードルは劇的に下がった。

ところが、困るのはコードを書くことではない。複数のものを動かす環境の方なのだ。プロジェクトが一つか二つのうちは、まだなんとかなった。Dockerを起動し、開発サーバーを立ち上げ、作業が終われば落とせばいい。

並行して触るプロジェクトが増えると、話が変わる。こっちのWebアプリではDBが動き、別のAPIサーバーも立ち上がり、あっちのアプリもある。モノレポではReactアプリが四つ同時に動いている。こうなると、ローカルでなにが動いているのか、さっぱり分からなくなってくる。

殊に、僕がよく触るNext.jsやReactは、どれもこれもやたらとポート3000を欲しがる。おかげで、どのアプリがどのポートで動いているのか把握できなくなる。Dockerコンテナは増え、ターミナルのタブは増え、環境変数はプロジェクトごとに違う。コードを書くのは楽になったのに、複数のプロジェクトを同時に動かす面倒くささは、ほとんど変わっていないのである。

むしろ、AIで作れるものが増えたぶん、複数の開発環境を同時に立ち上げる場面が増えた。そこが前より気になるようになったわけだ。フロントエンドだけならまだいいが、APIサーバーやDB、Dockerが絡むと、ローカル環境はそれなりに重くなる。最初は気にならなかったものが、プロジェクトが増えるにつれて、じわじわと辛くなってきた。

書くのは楽でも動かす場所は要る

AIのおかげで、コードを書くコストはかなり下がった。複数のプロジェクトを同時に触ることも可能になった。それでも結局、次のようなコマンドを叩く場所は必要になる。

pnpm install
pnpm dev
pnpm test
docker compose up

DBを使うならDBを起動しなければならない。外部APIを使うならMockサーバーも建てる必要があるし、Webアプリなら開発サーバーも要る。AIがコードを書いてくれたところで、実行環境までいい感じに面倒を見てくれるわけではない。

翻って、触るプロジェクトが増えたことで、開発環境の管理は前より目立つようになった。昔は一つのプロジェクトに集中していればよく、ローカル環境をそこまで気にする必要もなかった。ところが今は、少なくとも僕にとって、WebサービスAを触りつつBの検証もして、ついでにAPIサーバーも書くのが普通になりつつある。そうなると、全部をメインのMacに入れていくのがだんだんしんどくなってくるのだ。

書く場所と動かす場所を分ける

断っておくと、僕はMacそのものは好きだ。かれこれ10年以上、Apple信者をやらせてもらっている。コードを書く場所としては、むしろ今のままMacを使い続けたい。

ただ、アプリを動かす環境まで全部Macに詰め込む必要があるのか。そこはいささか疑問が残る。たとえるなら、原稿を書く書斎に、旋盤や溶接機まで持ち込んでいるような状態だ。書く場所と動かす場所は、書斎と工房のように分けてもよいのではないだろうか。

実は自宅には、使っていないPCが転がっている。以前 https://vscode.dev/ が登場したときも、これでiPadから開発できるのではと考え、試そうとしたことがある。結局、面倒くさくなってやめた。当時は同時に触るプロジェクトがせいぜい二つか三つで、そこまで辛くはなかったのだ。

ところが今は、なにしろ無限にアプリケーションが作れる状況になってしまった。いや、無限は盛った。とはいえ、思いついたらとりあえず作ってみる、というのが日常になっているのは事実である。

そこで考えているのが、Macでは今まで通りコードを書きつつ、サーバーは別の環境に立てる構成だ。平たく言えば、自分専用の、ホットリロードが効くStaging環境が作れればいい。Macではエディタを開き、AIコーディングツールを使い、Gitを操作する。設計や調査をして、ブラウザで動作を確認するのもMacだ。

一方、アプリの実行、Docker、DB、テスト、開発サーバーといった実際に動かす部分は、Windows/WSLや別のLinuxマシンに任せる。両者の間は、SSHとファイル同期でつなぐ。書斎で書いた図面を、廊下の向こうの工房へ回すイメージである。

完全にクラウドIDEへ移行したいわけではない。お金もかかる。VS Code Remote SSHやGitHub Codespacesのような方向もあるが、今考えているのはもう少しゆるい構成だ。Macでいつも通り編集し、動かす場所だけを別にする。半分だけリモート開発、とでも言えばよいか。このくらいの距離感が、今の僕にはちょうどよさそうに見えている。

なぜWindows/WSLなのか

もっとも、別にWindows/WSLである必要はない。Linuxサーバーでもいいし、Mac miniでもいいし、余っているPCならなんでもいい。単に、僕の手元にはWindowsマシンと2014年製の古いMac miniがある。これを実行環境として使えないかと考えているだけだ。

Windowsといっても、実際にはWSLを使うつもりでいる。WSL上でNodeやDockerを動かし、Mac側からSSHで入る。Macで編集したファイルをWSL側に同期し、向こうで開発サーバーを立ち上げる。ブラウザで確認するものは、Mac側からアクセスできるようにしておく。こうすれば、Macをメインの作業場所にしたまま、実行環境だけをWindows/WSLに逃がせる。

手元のマシンを使えるので、クラウド環境を常時立ち上げておくよりずっと気軽だ。Codespacesのようなものはもちろん便利だが、毎回そこに寄せるほどでもないプロジェクトも多い。ちょっと試したいだけのものに、クラウド環境を作り、課金を気にし、設定を整える。それはいささか重い。

それなら、家にあるWindowsマシンやLinuxマシンを、実行環境として雑に扱う方がよほど性に合う。壊れても困らないし、必要なら作り直せばいい。AIコーディングエージェントに好き勝手触らせる環境としても、メインのMacから少し切り離されている方が安心できる。工房なら、多少散らかっても書斎の本は汚れないわけだ。

この構成でなにより期待しているのは、メインのMacをなるべくきれいに保てることだ。もちろん、Gitやエディタ、AIコーディングツール、ブラウザ、ターミナルといった最低限の開発ツールはMacにも入れる。ただし、入れるのはそこまでだ。DB、Docker、開発サーバー、テスト実行といったプロジェクトごとの実行環境は、できるだけWindows/WSL側に寄せたい。そうすればMacは書く場所として使いやすいまま保てるし、プロジェクトごとに環境を分ける割り切りもしやすくなるはずだ。

ファイル同期という難所

ところが、実際にやろうとすると、最大の問題はファイル同期である。Macでコードを書くと、その変更がWindows/WSL側に反映される。向こうで動いている開発サーバーが変更を検知し、ホットリロードする。この流れが気持ちよく動かないと、たぶんすぐに使わなくなる。

開発環境で一番大事なのは、結局ストレスがないことなのだ。反映が少し遅い、たまに同期されない、ホットリロードが効かない。そういうことが一度でもあると、使う気は一気に失せる。

候補としては、rsync、Syncthing、Mutagen、SSHFS、VS Code Remote SSHあたりが挙がる。まずrsyncは、シンプルで分かりやすい。ただ常時同期させるなら、ファイル変更をwatchしてrsyncを走らせる仕組みが別途要る。単発の同期なら簡単でも、開発中ずっと使うなら少し工夫がいる。

次にSyncthingは、常時同期という意味ではかなりよさそうだ。ただ開発用途となると、node_modulesやビルド成果物、キャッシュファイルの扱いをちゃんと考えなければならない。同期してほしくないものまで同期されると辛いし、逆に必要なものが同期されないのも困る。

Mutagenも、この用途に近そうに見える。ローカルとリモートのファイル同期をいい感じにやってくれるので、開発環境の分離とは相性がよさそうだ。もっとも、僕の用途にどこまで合うかは、実際に試してみないと分からない。

SSHFSは一見シンプルだが、開発環境として使うと、ファイル監視やパフォーマンスでハマりそうな予感がする。とりわけフロントエンドの開発サーバーは、ファイル監視に依存している。そこが不安定だと厳しい。

VS Code Remote SSHを使えば、かなりの問題は解決するだろう。ただそれは、エディタごとリモートに寄せる方向になる。書斎ごと工房へ引っ越すようなものだ。今回やりたいのは、Mac側でいつも通り編集し、実行だけを別マシンに逃がすこと。Remote SSHで十分ではあるのだが、僕が欲しいものとは少し違う。

結局のところ、この構成の肝は、ホットリロードが自然に効くかどうかに尽きる。Macで保存すると、Windows/WSL側にファイルが同期され、向こうの開発サーバーが変更を検知し、ブラウザが更新される。この流れが違和感なく回らなければ、日常的には使えない。逆に、ここさえ気持ちよく動けばかなり実用的になる。

同期の仕組みが多少雑でも、保存してすぐ反映されるなら十分だ。最初から完璧な分散開発環境を作りたいわけではない。Macで書いたファイルがWindows/WSL側にいい感じに同期され、開発サーバーがちゃんと反応してくれる。それだけで、僕はかなり助かる。

自分用の同期ツール

このあたりを考えていると、いっそ自分用に小さな同期ツールを拵えてもいいのではないか、という気がしてくる。たとえば、プロジェクトごとに次のような設定ファイルを書いておく。

project: my-app

local:
  path: ~/src/my-app

remote:
  host: windows
  path: /home/me/src/my-app

ignore:
  - node_modules
  - .next
  - dist
  - .git
  - coverage

そのうえで、次のように起動する。

devsync start

すると、Mac側の変更を監視して、必要なファイルだけをリモート側に送ってくれる。最初に全体を同期し、以降は差分だけを同期する。node_modulesやdist、.next、coverageのようなものは除外する。保存したら、すぐに反映される。

まず欲しいのは、その程度のものだ。最初から立派なツールにする必要はない。自分の環境で動いて、自分が困らなければそれで十分である。

ゆくゆくは、次のようなことまでできると便利そうだ。

devsync shell
devsync run pnpm dev
devsync run pnpm test
devsync status

もっとも、最初からそこまで作ろうとすると大変なので、まずは同期だけでいい。ファイルを送る部分はrsyncに任せてもいいし、watchだけ自前で書いてもいい。要するに、Macで保存したらWindows/WSL側に反映される。それだけでも使い道はいくらでもある。

ボトルネックの移動

AIを使うようになって、開発のボトルネックは少し移った気がする。そもそも以前は、コードを書くこと自体が大変だった。設計して、実装して、テストコードを書いて、動作検証して。実装方針を考え、ライブラリを調べ、細かいコードを書き、エラーを直すところに時間を吸われていた。今ももちろん楽ではないが、AIにかなり手伝ってもらえるようになった。

一方で、実行環境の面倒くささはほとんど変わっていない。むしろ書く速度が上がったぶん、そちらが目立つようになった。AIがコードを書いても、アプリはどこかで動かさなければならないし、テストもどこかで回さなければならない。DBも要る、Dockerも要る、外部APIの設定も要る。

そう考えると、これからは「どうコードを書くか」だけでなく、「どこで安全に動かすか」も大事になっていくのだろう。殊に、AIコーディングエージェントにいろいろ触らせるなら、メインPCと実行環境を分ける意味は大きい。コマンドを実行させ、テストを回させ、ファイルを編集させる。そういうことをやらせるなら、メインのMacを直接いじらせるより、別マシンやコンテナ、WSL上の環境を用意しておいた方が、精神衛生上もずっと楽に違いない。

以上、AI時代の開発環境について、今考えていることを書いた。作れるものが増えたぶん、ローカル環境が散らかる問題は前より気になるようになった。そこで、Macではコードを書き、実行環境はWindows/WSLや別のLinuxマシンに逃がし、その間をファイル同期でつなぐ構成を試してみたい。課題はファイル同期とホットリロードだが、最初は自分用の小さな同期ツールで十分だ。Macで保存したら向こうに反映され、向こうで開発サーバーが動く。まずはそれだけでいい。書斎に工房まで詰め込むより、廊下一本ぶん離しておくくらいが、AI時代の開発環境にはちょうどいいのだ。