バクラク事業部エンジニアの id:upamune です。最近、ローカル開発環境構築に対して人より熱意があるということに気がつきました。
ということで、この記事ではバクラク事業部での、ローカル開発環境構築の今について書きます。
はじめに
近頃、AIの発展により開発、特にコーディングのハードルは大きく下がりました。弊社でもプロダクトマネージャーやデザイナーがエンジニアに混じってPRを出しています。
詳しくはバクラクビジネスカードでプロダクトマネージャーをしている原山がnoteを書いているのでご覧ください。
しかし、ここで開発の障壁となるのが最初のローカル開発環境の構築です。セットアップドキュメントは存在しますが、主にソフトウェアエンジニア向けに書かれており、ローカルでアプリケーションを動かすだけなら不要なツールまでまとめてインストールするため、時間のかかるものになっていました。
特にリポジトリごとで利用するNode.jsのバージョンが異なっているため、Node.jsのバージョン管理ツールも導入したりと複雑になっています。
この記事では、 CLIツールのパッケージマネージャーであるaquaを導入することで、この課題をどのように解決したかについて共有します。
現在のローカル開発環境の構成
バクラクシリーズはモノレポで開発しており、必要なマイクロサービスを全てローカル上で動かすことが出来ます。一度セットアップを行えば、誰でもローカル上でプロダクトの機能開発や複数箇所に影響ある修正を行うことができます。
現状の課題
Homebrewを利用してローカル開発環境を構築していましたが、以下のような課題がありました:
- 各ツールの複数バージョンを使い分けることが難しく、特定のリポジトリだけで必要なツールをバージョン固定で利用することが困難
- インストール時に自動でアップデートが走り、予期せぬ時間を消費する(Homebrewの環境変数で制御は可能)
- ビルドの再現性が担保できない
- 人によってによって必要/不要なツールの区別なく一括インストールされるため、時間がかかる
そして、前述のようにNode.jsの複数バージョンを使い分ける必要があるため、Node.jsバージョン管理ツールも利用する必要があり複雑になっており、 セットアップドキュメントではソフトウェアエンジニア向けに書かれているためどのNode.jsのバージョン管理ツールを利用するかは利用者にお任せの状態でした。
aquaの導入
aquaとは
aquaは、CLIツールのための宣言的パッケージマネージャーです。主な特徴として以下があります。
- lazy installによる必要時のみのインストール
- 複数バージョンの切り替えが容易
- checksumによるセキュリティの担保
- renovateによる自動更新対応
特筆すべきはlazy installで、ツールが必要になった瞬間にインストールが始まる機能です。この機能によって、利用しないツールはインストールされないため無駄にインストール時間が増加することがありません。
なぜaquaを選択したのか
aquaを選択した理由は以下の通りです:
- すでにCI環境での実績があった
- CI上で必要なツールのセットアップに利用していた
 
- 他のツール(Nix, Devbox等)と比較して:
- 学習コストが低い
- トラブルシューティングが容易
- 必要なツールのみを効率的にインストール可能
 
導入プロセス
基本的な設定
aquaの設定はaqua.yamlで管理します。以下は基本的な設定例です。利用したいツールとバージョンを列挙すれば良いだけになっています。ツールの追加もインタラクティブに追加できる方法も用意されており、いたせり尽せりです。
packages: - name: cli/cli@v2.67.0 - name: golang/go@1.24.0 - name: 1password/cli@v2.30.3
利用できるツールはstandard registryに登録されており、誰でもPRを送ることで対応されてないツールを追加できるようになっています。
一部standard registryに存在しないツールを利用していましたが、 go_install packageを使うことでstandard registryにないものでも対応できました。
standard registryに存在しないツールでも以下のpackage typeに対応しているため幅広く対応されています。
- cargo
- github_archive
- github_content
- github_release
- go_build
- go_install
- http
最新の対応状況はドキュメントをご確認ください。
ref: https://aquaproj.github.io/docs/reference/registry-config/#package-types
direnvとの連携
以下のように direnv と連携することで、プロジェクトディレクトリに移動した際に自動的に必要なツールがセットアップ(lazy install)されるようにしました。lazyにinstallされるため、ここでインストールは走らないので時間がかかったりはしません。
# .envrc
use_aqua() {   
 PATH_add $(aqua root-dir)/bin
 watch_file aqua-checksums.json aqua-policy.yaml aqua-registry.yaml aqua.yaml
 aqua install -l
}
 
has aqua && use aqua
複数のNode.jsバージョンへの対応
基本バクラクではモノレポなのですが、一部リポジトリが別れています。その別れているリポジトリごとにNode.jsのバージョンが異なっている問題があります。 正攻法としては、それぞれのリポジトリに aqua.yaml を置いても良かったのですが、今回はaquaのツールをグローバルにインストールできる仕組みを使って対応しました。
具体的にはモノレポでスクリプトを実行すると、冪等にグローバルへのaquaで管理されたツールをセットアップするようにしました。
グローバルの aqua.yaml に定義されているパッケージは以下の通りです。
packages: - name: pnpm/pnpm@v10.1.0
pnpmは9.6.0からNode.jsの管理もしてくれるようになっているため、pnpmをグローバルに1つインストールしておくだけで、個別のNode.jsのバージョン管理を行う必要がなくなりました。pnpmは packageManger で指定されているバージョンを見てpnpm自体のバージョンも切り替えてくれるためグローバルにはpnpmの単一バージョンをインストールするだけで良くなりました。
pnpmに各リポジトリで利用しているNode.jsのバージョンを教えるために .npmrc に use-node-version の指定は必要です。
これによって、利用するNode.jsのバージョンについて深く考えなくても、pnpm installやpnpm devを実行した時に指定したバージョンのNode.jsが存在しなければ自動的にインストールされるようになりました。
導入後の成果
Homebrewでインストールすることがなくなり、自動アップデートが走らなくなったことで時間がかかりすぎることがなくなりました。 さらに必要なツールのみインストールするようになったので、これまで無駄にインストールしていた時間もなくなりました。
Homebrewでインストールしていたツールだけではなく、 go install でインストールしていたツール群もstandard registryにあるものは置き換えたり、前述の go_install packageを使うことで全てaquaに置き換わったことで時間が短縮されました。
しかし、ローカル環境は千差万別なので実際に導入してみると問題が発生しました。これは「aqua トラブルシューティング」というページを作っておくことで、問題と解決策を貯めるようにしたところ自然に解決していきました。


このaqua導入によって、CIの高速化もなされ一部のCIの時間が半分以下になったのですが、またそれは次回に... 🤫
今後の課題
最初に上げた課題については解消されましたが、まだ現在も以下の課題が残っているので解消してよりストレスフリーかつスムーズな開発体験を提供していきます 💪
- aqua自体のインストールをHomebrewに依存している点の解消
- aqua-installerを使ってHomebrew無しで利用できるように
 
- 初期セットアップの完全自動化
- まだドキュメントを見ながらコピペしてコマンドを打つ必要がある
 
まとめ
aquaの導入により、ローカル開発環境の構築における多くの課題を解決することができました。
- 環境構築の簡素化と高速化
- バージョン管理の容易さ
- チーム全体の開発体験の向上
これらの改善により、エンジニアだけでなく、プロダクトマネージャーやデザイナーを含むチーム全体がより効率的に開発に参加できるようになったため、今後も継続的な改善を重ねながら、より良い開発体験の実現を目指していきます。
