npm、npx、bunの使い分け:実践ガイド
はじめに
JavaScriptの開発環境では、npm
、npx
、bun
などのツールを日常的に使用しています。
しかし、これらの違いや適切な使い分けについて、明確に理解している開発者は意外と少ないかもしれません。
特にnode_modules
フォルダの肥大化や、似たようなコマンドの混在に悩んだ経験はありませんか?
この記事では、これらのツールの仕組みと適切な使い分けについて、実際のユースケースに基づいて解説します。
ツールの仕組みを理解する
npm(Node Package Manager)
npmはNode.jsのパッケージ管理システムで、以下の特徴があります:
-
パッケージの保存場所:
node_modules
フォルダ(プロジェクトローカルまたはグローバル) -
設定ファイル:
package.json
(依存関係の一覧)とpackage-lock.json
(正確なバージョン情報) - 主な用途:パッケージのインストール、更新、削除、スクリプトの実行
# パッケージをインストール
npm install react
# 開発用パッケージをインストール
npm install --save-dev typescript
# グローバルにインストール
npm install -g typescript
# スクリプトを実行
npm run build
npx(Node Package Execute)
npxはnpmに含まれるツールで、パッケージを一時的に実行するために使用します:
-
検索順序:
- ローカルの
node_modules/.bin
ディレクトリ - グローバルにインストールされたパッケージ
- npmレジストリ(オンライン)から一時的にダウンロード
- ローカルの
-
主な用途:
- インストールせずにパッケージを一時的に実行
- ローカルにインストールされたツールを簡単に実行
- 特定バージョンのツールを試す
# create-react-appを一時的に実行(インストールなし)
npx create-react-app my-app
# ローカルにインストールされたeslintを実行
npx eslint .
# 特定バージョンを指定して実行
npx typescript@4.5.5 tsc --version
bun
bunは新しいJavaScript/TypeScriptランタイムとパッケージマネージャーで、高速な処理が特徴です:
-
パッケージの保存場所:
node_modules
フォルダ(最適化されたバイナリキャッシュも使用) -
設定ファイル:
package.json
とbun.lockb
(バイナリ形式のロックファイル) - 主な用途:高速なパッケージ管理、JavaScriptの実行、ビルド、テスト
# パッケージをインストール(npmより高速)
bun install
# JavaScriptやTypeScriptを直接実行
bun index.ts
# 開発サーバーを起動(ホットリロード付き)
bun --hot index.ts
# テストを実行
bun test
ユースケース別の使い分け
1. GitHubから他人のリポジトリを一度だけ試す場合
基本的なアプローチ
# リポジトリをクローン
git clone https://github.com/username/repository.git
cd repository
# 依存関係をインストール
npm install # または bun install(高速)
# 実行
npm run dev # または bun run dev
ツールの選択ポイント
- npm:互換性を重視する場合
- bun:速度を重視する場合(特に大規模プロジェクト)
-
npx:プロジェクト内のツールを実行する場合(例:
npx jest
)
実際の例
# Reactプロジェクトを試す場合
git clone https://github.com/facebook/create-react-app.git
cd create-react-app
npm install
cd packages/cra-template
npm run start
# プロジェクト内のツールを実行
npx jest # ローカルのnode_modules/.binからjestを探して実行
ここでのポイントは、npxがまずローカルのnode_modules/.bin
を探すという点です。プロジェクトにインストールされたツールを簡単に実行できます。
2. 新しいプロジェクトを作成する場合
基本的なアプローチ
# Reactプロジェクトを作成
npx create-react-app my-app
# または Next.jsプロジェクトを作成
npx create-next-app my-next-app
# または Viteプロジェクトを作成
npx create-vite my-vite-app
ツールの選択ポイント
- npx:一度だけ使うツールに最適(プロジェクト作成ツールなど)
-
bunx:高速な実行が必要な場合(
bunx
はnpx
の高速版)
実際の例
# TypeScriptを使ったReactプロジェクトを作成
npx create-react-app my-app --template typescript
# 作成したプロジェクトに移動
cd my-app
# 開発サーバーを起動
npm start
ここでのポイントは、npxがオンラインからツールを一時的にダウンロードして実行するという点です。
プロジェクト作成後は不要になるツールなので、インストールする必要がありません。
3. 本番開発で継続的に使用する場合
基本的なアプローチ
# プロジェクト初期化
npm init -y
# 必要なパッケージをインストール
npm install react react-dom
npm install --save-dev typescript @types/react
# package.jsonにスクリプトを追加
# "scripts": {
# "start": "react-scripts start",
# "build": "react-scripts build",
# "test": "react-scripts test"
# }
# 開発
npm run start
ツールの選択ポイント
- npm:安定性と互換性を重視する場合
- bun:開発速度を重視する場合
- npx:ローカルツールの実行や特定バージョンのテストに
実際の例
# 開発中にTypeScriptの特定バージョンを試す
npx typescript@4.5.5 tsc --version
# ローカルにインストールされたESLintを実行
npx eslint src/ --fix
# 本番ビルド
npm run build
ここでのポイントは、npmでプロジェクトの依存関係を管理しつつ、npxで特定のツールを柔軟に実行できるという点です。
node_modulesの管理と最適化
問題点
-
node_modules
フォルダは非常に大きくなる(数GB) - 同じパッケージの複数バージョンが含まれることがある
- プロジェクト間で重複するパッケージが多い
解決策
-
Gitから除外する:
# .gitignore node_modules/
-
定期的に整理する:
# 不要なパッケージを削除 npm prune # キャッシュをクリアする npm cache clean --force
-
bunを使用して効率化:
# npmの代わりにbunを使用 bun install
bunは依存関係をより効率的に管理し、インストール速度も大幅に向上します。
-
pnpmの使用を検討:
# pnpmをインストール npm install -g pnpm # pnpmでインストール pnpm install
pnpmはシンボリックリンクを使用して、パッケージを共有ストレージに保存します。
npxの高度な使い方
特定バージョンの実行
# TypeScriptの特定バージョンを実行
npx typescript@4.5.5 tsc --version
# Reactの古いバージョンのcreate-react-appを使用
npx create-react-app@4.0.0 my-old-app
オプションの活用
# ローカルとグローバルのみを使用(オンラインからダウンロードしない)
npx --no-install eslint .
# ローカルとグローバルを無視して常に最新をダウンロード
npx --ignore-existing create-react-app my-app
GitHubリポジトリから直接実行
# GitHubのリポジトリから直接実行
npx github:user/repo
# または
npx https://github.com/user/repo/archive/main.tar.gz
チーム開発での使い分け
複数のツールが混在する場合
-
package.jsonでスクリプトを統一:
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test" }
これにより、npm、yarn、bunのどれを使っても同じコマンドで実行できます。
-
CIパイプラインでの実行環境を固定:
# GitHub Actions例 steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' cache: 'npm' - run: npm ci - run: npm test
-
チームでのルールを決める:
- 開発環境:個人の好みのツール(npm/bun/pnpm)を使用可
- CI/CD:特定のツール(例:npm)に統一
- lockファイル:どのファイルを優先するか決める
まとめ:状況別おすすめツール
一度だけ使うツール
- ベストチョイス: npx
-
使用例:
npx create-react-app my-app
- 理由: インストール不要で一時的に実行できる
プロジェクトの依存関係管理
- 安定性重視: npm
- 速度重視: bun
- ディスク容量重視: pnpm
-
使用例:
npm install
/bun install
/pnpm install
ローカルツールの実行
- ベストチョイス: npx
-
使用例:
npx eslint .
- 理由: パスを指定せずに簡単に実行できる
高速な開発環境
- ベストチョイス: bun
-
使用例:
bun --hot index.ts
- 理由: 高速な実行とホットリロード
大規模プロジェクト
- ベストチョイス: bun または pnpm
-
使用例:
bun install
/pnpm install
- 理由: 効率的な依存関係管理と高速なインストール
最終的な選択
これらのツールは、それぞれ異なる目的と強みを持っています。重要なのは、プロジェクトの要件や状況に応じて適切に使い分けることです。
- npm: 安定性と互換性を重視する場合
- npx: 一時的な実行や特定バージョンのテストに
- bun: 高速な開発環境と効率的な依存関係管理に
これらを適切に組み合わせることで、より効率的なJavaScript/TypeScript開発が可能になります。
Discussion