続・Nixで作る個人開発環境 (WSL2 + Nix + Zed)
WSL2 + Nixで開発環境が作れる算段を付けた後、NixOSマシンとの相互促進的な遊びの中で、Windowsマシンでの新開発環境を一旦結論したのでログ。
元々の開発環境
- Windows 11
- ホスト
- 下記を有する
- VSCode
- Docker Desktop for Windows
- WSL2
- Docker Desktop側で作成のディストリビューション
docker-desktop
がある
- Docker Desktop側で作成のディストリビューション
- Dockerコンテナ
- ホストにあるDockerデーモンがWSL2の上にコンテナを作る
程度に差はあれども、Windowsマシン上でDockerを織り交ぜた場合は大体こんな感じな気はする。ただし、上記記事でも記載の様にいくつか懸念があった。
- Docker Desktopが不安定
- 登場人物が多い
- 前回は「障害ポイントが多い」と書いたポイント
- 記載以外にもVSCodeもコンテナ上にVSCodeサーバーを作ったりと結構あれこれしている
- ネイティブアプリ開発に激弱
- devcontainer拡張が肝すぎてVSCodeにロックイン
- 単純に他の面白そうでVSCodiumベースで無いエディタ使いたい
これからの開発環境
- Windows 11
- ディスプレイサーバー用途
- 後述するエディタの表示、動作確認用のブラウザ起動だけ
- WSL2
- 結論、ここに開発環境の肝になる部分が詰まる
- システムパッケージ管理
- Nix
- ランタイム管理までNixの責務
- ランタイムパッケージ管理
- 各ランタイムエコシステムに紐付く管理ツールに任せる
-
npm
pip
等
-
- 各ランタイムエコシステムに紐付く管理ツールに任せる
- エディタ
- Zed
詳細
この章が記事の肝になるので、元々側よりは丁寧めに。
Nix
前回記事から抜粋。
Nixは純粋関数型のパッケージマネージャーで、FlakesはNixの拡張機能として依存パッケージや開発環境等のプロジェクトのベース環境定義を提供する。
Nixはインストールしたパッケージを /nix/store/ の下に保持し、これらのパッケージはソースコードやビルド定義、依存関係等を含むプロジェクト定義情報をインプットに生成したハッシュによりプロジェクトと依存パッケージが関連付けられる。これはグローバル環境にインストールの上Pathも更新、と言ったローカル汚染を回避しており、かつ共有ライブラリで起きがちなバージョンコンフリクト(アプリAはv1、アプリBはv2と依存しているためにどちらかの挙動に支障が生じる、みたいな)の事象も回避出来ると、個人的に求めていた恩恵とも合致する。
ドキュメントを読んだ限りでは、これまでDockerfileを書いてDevContainerを立ち上げていた部分がFlakes作成に置き換わり、コンテナの代わりにNixによる開発シェルを起動する様な形に出来そうなイメージ。
最後に記載した思惑がちゃんと想定通りな点を簡単なReactアプリ開発で把握した。開発環境を作るだけなので flake.nix
に書く出力は devShells
だけでOK。Nixはパッケージ管理を自身管轄配下に集めながらハッシュベースで紐付けながら行うことで依存関係衝突やトランザクション的パッケージ管理等が出来る点が売りなので、Dockerの様に新しい仮想環境レイヤーが足される訳でも無い。WSL2とホスト間の関係性だけなので(Dockerもめちゃくちゃあった訳では無いが)考慮事項はある程度減る。
上記でランタイムパッケージ管理をあえて切り出して記載した理由は、例えばPython環境をNixで作る場合、パッケージインストールもNixの責務として取り扱いが出来るからだ。
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = [
(pkgs.python312.withPackages (ps: with ps; [ flask ]))
];
}
Nixとしてはランタイムパッケージも含めて彼らが標榜する堅牢な管理を行うべきだ、と言う意図と理解しているが、下記の理由でランタイム側はランタイムのパッケージ管理ツールに任せることにした。
- 全パッケージが
nixpkgs
にある訳では無い - Nixの中ではきちんと解釈されるが、エディタのLSPでちゃんと把握してくれるのか怪しい
- 実際、Pythonでは一部パッケージが解釈されなかった。物による気がする
-
pip
は無かったがnpm
はあったりとランタイムで状況まちまち- Nix寄せにしきれないのならば、管理方針の一貫性を取る意味でもランタイム側にお任せ
Zed
NixOS上で遊ぶ中で、VSCodeやVSCodiumベースの物以外のエディタ選択肢を模索しており、その時Zedにめちゃくちゃ惚れた。キーバインドはVSCodeの物を流用出来る上、デフォルトでLSPもフォーマッタも効くので使用感も悪くない。パッケージなり自作クラス等の追加後の解釈も元々環境時よりもぐっと高速になった感がある。
Zedはダウンロードページを見るとWindowsのサポートが無く、調査する限りWSL2対応も同様との感じであった。が、必要なシステムパッケージをWSL2に用意したり、Linuxアプリをきちんとホスト側で表示出来る様にXサーバー回りを整備出来ればいけるのでは、と調べていたところ、下記の記事を発見した。
特に .bashrc
回りは設定項目を網羅出来ていなかったので非常に助かった。
プロジェクト管理場所について
利用ツールの話では無いがプロジェクトをどこに置くことにしたかも変化があったので記載。結論、/mnt/
配下にプロジェクト用のワークディレクトリを切り、この下であれこれ開発する方針とした。
これはDocker時に良く遭遇した問題が背景にあり、WSL2の制約上、ホスト側で管轄しているファイルたちの変更検知をWSL2側から行うことが出来ない。例えば下記はまさにその件に当たった場合の対処を書いた記事だった。
元々の環境上はホスト側にインストールしていたVSCodeを利用していた点からこの制約を回避出来なかったが、Zedをメインエディタとした結果、彼はホストには存在しないためWSL2だけが管轄出来る場所にプロジェクトを配置することで制約を突破出来ることが判明した。具体的には /mnt/c
配下にプロジェクトが無ければOKである。
結論
- ホストとWSL2、Dockerにあれこれ散らばっていた構成が、核になる物が基本WSL2に集まる構成になった
- WindowsでもZedを味わえるぞ
- WSL2側に日本語入力の設定を入れていない点が残タスクだが、グローバルエリートになるためにも英語だけで生きるのも有かも
- 満足したぜ
Discussion