はじめに
複数のプロジェクトを掛け持ちしていると、こういう経験ありませんか。
あるプロジェクトは npm、別のプロジェクトは yarn、最近始まったプロジェクトは pnpm...
で、よく間違えるんですよね。
pnpmのプロジェクトで npm install を打ってしまって、package-lock.jsonが生成されて「あっ」となる。逆もまた然り。地味にストレスが溜まります。
そんな問題を解決してくれるのがniです。
Anthony Fu(antfu)氏が作ったツールで、ロックファイルを見て自動的に適切なパッケージマネージャーを判別してくれます。GitHubスターは7,800を超えていて、OSS界隈では知る人ぞ知る便利ツール。
一度使い始めると、もう元には戻れません。
niとは
niは「use the right package manager」をモットーにしたCLIツールです。
プロジェクトのルートにある lock ファイル(yarn.lock、pnpm-lock.yaml、package-lock.json、bun.lockb)を検出して、対応するパッケージマネージャーのコマンドを実行します。
つまり、niと打つだけで、
- yarn.lockがあれば →
yarn install - pnpm-lock.yamlがあれば →
pnpm install - package-lock.jsonがあれば →
npm install - bun.lockbがあれば →
bun install
が自動で実行される。
これだけ聞くと「たいしたことないじゃん」と思うかもしれませんが、実際に使ってみると、思考のオーバーヘッドがなくなる快適さを実感できます。
特徴・メリット
パッケージマネージャーを気にしなくていい
これが最大のメリット。
どのプロジェクトでも ni を打てば正しくインストールされる。yarn addなのかpnpm addなのかnpm installなのか、考えなくて済む。
特にOSSのコントリビュートをしている人には刺さると思います。リポジトリごとにパッケージマネージャーが違うので、README読んでコマンド確認して...という手間がなくなる。
複数のコマンドをカバー
niには兄弟コマンドがいくつかあります。
| コマンド | 役割 |
|---|---|
ni |
パッケージのインストール |
nr |
スクリプトの実行 |
nlx |
一時的なパッケージ実行(npx相当) |
nup |
依存関係の更新 |
nun |
パッケージのアンインストール |
nci |
クリーンインストール |
nd |
依存関係の重複排除 |
na |
エージェント(パッケージマネージャー)の直接実行 |
個人的にnrはかなり使います。npm run devもyarn devもpnpm devも、全部nr devで済む。
対話的なスクリプト選択
nrを引数なしで実行すると、package.jsonのscriptsから対話的に選択できます。
$ nr
? script to run ›
build
dev
lint
test
これ、意外と便利。「あれ、このプロジェクトのdevコマンドって何だっけ」というとき、いちいちpackage.jsonを開かなくて済む。
前回のコマンドを再実行
nr -で前回実行したスクリプトを再実行できます。
開発中にビルドとテストを交互に実行するような場面で、地味に効きます。
npm、yarn、pnpm、bun、denoに対応
主要なパッケージマネージャーはほぼ網羅。Denoにも対応しているので、将来的にも安心。
インストール方法
グローバルインストールが基本です。
npmの場合
npm i -g @antfu/ni
Homebrew(macOS / Linux)
brew install ni
これだけ。シンプル。
インストール後、確認:
ni --version
バージョンが表示されればOK。
基本的な使い方
パッケージのインストール
# 全依存をインストール
ni
# 特定パッケージを追加
ni vite
# 開発依存として追加
ni @types/node -D
# 本番依存のみインストール
ni -P
# ロックファイル固定でインストール(CI向け)
ni --frozen
# グローバルインストール
ni -g eslint
スクリプトの実行
# スクリプト実行
nr dev
# 引数を渡す
nr dev --port=3000
# 対話的にスクリプト選択
nr
# 前回のコマンドを再実行
nr -
一時的なパッケージ実行
# npx相当の機能
nlx create-next-app
# 特定バージョンを指定
nlx typescript@5.0.0 --version
パッケージの更新
# インタラクティブに更新
nup
# 特定パッケージを更新
nup vite
パッケージのアンインストール
# パッケージを削除
nun axios
# 開発依存から削除
nun @types/node -D
クリーンインストール
# node_modulesを削除してから再インストール
nci
これはCI環境でよく使いますね。npm ciやyarn install --frozen-lockfileに相当。
実践的なユースケース
複数プロジェクトを行き来する開発
これがniの真骨頂。
# プロジェクトA(pnpm)
cd ~/projects/project-a
ni # pnpm install が実行される
nr dev # pnpm dev が実行される
# プロジェクトB(yarn)
cd ~/projects/project-b
ni # yarn install が実行される
nr dev # yarn dev が実行される
何も考えなくていい。
OSSコントリビュート
初めてcloneしたリポジトリでも、READMEのインストール方法を確認せずにとりあえずniを打てばいい。
git clone https://github.com/someone/awesome-project
cd awesome-project
ni
nr dev
ロックファイルを見て適切なパッケージマネージャーが使われる。
チーム開発での統一
チームで「niを使う」と決めておけば、ドキュメントに書くコマンドも統一できます。
## セットアップ
ni
nr dev
新メンバーがnpmを使っていても、yarnを使っていても、pnpmを使っていても、同じ手順でOK。
実行前にコマンドを確認したい場合
「どのパッケージマネージャーが使われるのか」を確認したいときは、末尾に?を付けます。
$ ni ?
pnpm install
$ nr dev ?
pnpm run dev
実行せずにコマンドを表示してくれる。初めてのプロジェクトで「何が実行されるか確認したい」ときに便利。
設定
~/.nircファイルで挙動をカスタマイズできます。
# ロックファイルがない場合のデフォルト(通常は対話的に聞かれる)
defaultAgent=npm
# グローバルインストール時に使うパッケージマネージャー
globalAgent=npm
また、環境変数でも設定可能です:
export NI_DEFAULT_AGENT=pnpm
export NI_GLOBAL_AGENT=npm
環境変数のほうが優先度が高いので、CI環境で一時的に変えたい場合などに使えます。
注意点
パッケージマネージャーの不一致
niは「正しいパッケージマネージャーを使う」ツールなので、間違ったパッケージマネージャーでインストールしようとすると警告が出ます。
例えば、pnpm-lock.yamlがあるプロジェクトでnpm install axiosを打つと、niは「pnpmを使うべき」と判断します。これは意図した挙動。
ロックファイルがない場合
ロックファイルがない状態でniを実行すると、対話的にどのパッケージマネージャーを使うか聞かれます。
$ ni
? Choose the agent ›
npm
yarn
pnpm
bun
~/.nircでdefaultAgentを設定しておけば、聞かれずに進められます。
まとめ
niは「パッケージマネージャーを意識しない開発体験」を提供してくれるツールです。
- ロックファイルを見て自動的に正しいパッケージマネージャーを実行
- npm、yarn、pnpm、bun、denoに対応
ni、nr、nlxなど複数のコマンドをカバー- 対話的なスクリプト選択機能
- コマンド確認用の
?オプション
正直なところ、これを知る前は「パッケージマネージャーの違い」をいちいち意識していました。このプロジェクトはyarnだから...、あっちはpnpmだから...と。
niを使い始めてから、その思考が完全になくなった。
30代になって思うのは、認知負荷を下げることの大切さ。覚えておくべきことを減らして、本当に考えるべきことに集中する。niはまさにそれを実現してくれるツールです。
インストールは1分で終わるので、試してみる価値はあると思いますよ。