0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

フロントパッケージ管理の 'pnpm' をJava経験者が比較しながら動かしてみる

0
Posted at

image.png

はじめに

仕事で初めて pnpm を利用したので、理解のために自分でもやってみました。

Qiita用にJavaのエコシステム(MavenやGradle)と比較しながら理解してみました。

フロントエンドのパッケージ管理の全体像

概念・役割 Javaの世界 フロントエンドの世界
パッケージ管理ツール Maven, Gradle npm, Yarn, pnpm
設定ファイル pom.xml, build.gradle package.json
依存関係の固定 なし(または各種プラグイン等) package-lock.json, pnpm-lock.yaml
ライブラリの実体保存先 ~/.m2/repository(グローバル) node_modules/(プロジェクト毎)
中央リポジトリ Maven Central npm registry

AIからの補足

  • package.json: プロジェクトの心臓部。Mavenの pom.xml のように、依存関係やビルドスクリプトを記述します。Javaでいう test のように、本番用(dependencies)と開発用(devDependencies)を分けて書きます
  • node_modules: ライブラリの実体が保存されるフォルダ。Javaの .m2 と違い、プロジェクトごとに作成されます
  • Lockファイル: チーム開発で環境差異を防ぐための、依存ツリーの正確なバージョン記録ファイル
  • 現在使われている主なツールは「npm」「Yarn」「pnpm」の3種類です

「pnpm」がnpmの課題を解決

npmの課題

  • ディスク容量の圧迫: プロジェクトごとに node_modules へライブラリを丸ごとコピーするため、同じReactのファイルがPC内に大量に複製され、ストレージを圧迫する
  • ファントム依存関係: パスを短くするため依存関係をフラットに配置しており、package.json に明記していない孫依存ライブラリまで誤ってインポートできてしまう

pnpmの解決策(グローバルストアとシンボリックリンク)

pnpmは、PC上の共通領域(グローバルストア)にライブラリの実体を1つだけ保存し、各プロジェクトには「ハードリンク」を張ります。
これは、JavaのMavenが ~/.m2/repository にJarファイルをキャッシュし、各プロジェクトからそれを参照する仕組みと非常に似ています。これにより、ディスク容量を劇的に節約できます。
また、シンボリックリンクを使って本来の依存ツリーを厳格に構築するため、隠れたバグ(ファントム依存関係)も防ぎます。

パッケージマネージャーを管理する「Corepack」

Corepackは、「パッケージ管理ツール(pnpmやYarn)自体のバージョン」をプロジェクトごとに固定・管理するためのツールです。
Javaエンジニアへの一番わかりやすい例えは、「Gradle Wrapper (gradlew)」や「Maven Wrapper (mvnw)」のフロントエンド版です。

チーム開発で「Aさんはpnpm v8、Bさんはv9」のようにバージョンがバラバラだと、Lockファイルのコンフリクトが頻発します。
Corepackを使うと、package.json に以下のようにバージョンを指定できます。

{
  "name": "my-project",
  "packageManager": "pnpm@9.5.0"
}

【重要】Node.js v25以降の最新事情
かつてCorepackはNode.jsに標準同梱されていましたが、Node.js v25以降では本体から外されました(アンバンドル化)。 そのため、最新環境では最初に npm install -g corepack で手動インストールする必要があります。

pnpmでプロジェクトの初期化(ハンズオン)

pnpm + Corepack + Vite を組み合わせて初期化

Step 1: Corepackの有効化

# Node.js v25以降の場合は事前に npm install -g corepack を実行
corepack enable

Step 2: Viteを使ったプロジェクトの作成

Javaでいう 'mvn archetype:generate' で雛形作成

pnpm create vite@latest my-frontend-app
# (対話形式でReact/Vueなどのフレームワークを選択)

Step 3: プロジェクトへの移動とバージョンの固定(Corepack)

作成したフォルダに移動して、このプロジェクトで使用するpnpmを固定

cd my-frontend-app

# 最新のpnpmバージョンに固定(package.jsonに自動追記される)
corepack use pnpm@latest

Step 4: 依存関係のインストールと起動

# ライブラリのインストール(pnpmの恩恵で超高速!)
pnpm install

# 開発用ローカルサーバーの起動
pnpm dev

起動後、ターミナルに表示される http://localhost:5173/ へアクセスすれば完了。

ここで叩いた 'pnpm dev' などのコマンドは 'package.json' の "scripts" に定義されていて、Mavenの 'mvn spring-boot:run' やGradleのタスクのように機能します。

おわりに

私のようなJava経験者向けに無理やり、JavaのMavenなどと比較して記載してみましたが、一番しっくりきたのはAIに出してもらった下記の 「npmとのコマンド比較」でした。

補足:AI

npmとのコマンド比較

目的・利用シーン npm (従来) pnpm (モダン)
プロジェクトの全パッケージをインストール npm install (または npm i) pnpm install (または pnpm i)
本番用パッケージを追加 npm install <pkg> pnpm add <pkg>
開発用パッケージを追加 (※テストツール等) npm install -D <pkg> pnpm add -D <pkg>
パッケージを削除 npm uninstall <pkg> pnpm remove <pkg> (または pnpm rm)
パッケージを更新 npm update <pkg> pnpm update <pkg> (または pnpm up)
スクリプトの実行 (例: dev, build) npm run dev pnpm dev (※ run は省略可能)
使い捨てコマンドの実行 (※1) npx <コマンド> pnpm dlx <コマンド>
ローカルコマンドの実行 (※1) npx <コマンド> または npm exec pnpm exec <コマンド>

Javaエンジニア向けの重要なポイント(コマンドの違い)

install ではなく add を使う

npmではパッケージを追加する際も npm install <パッケージ名> を使っていましたが、pnpmでは pnpm add <パッケージ名> を使います。
これは、Java(Maven)で言うところの「pom.xml に を追加する(add)」作業と、「プロジェクト全体の依存関係をダウンロードして配置する(install)」作業が、意味合いとして明確に分離されたためです。

魔法のコマンド npx の代替(pnpm dlx と pnpm exec)

ネット上のフロントエンドの記事を読んでいると、頻繁に npx というコマンドが登場します(例:npx create-react-app など)。これは「パッケージをインストールせずに、一時的にインターネットからダウンロードして一回だけ実行する」という便利なコマンドです。
pnpm環境でこれに相当することを行いたい場合は、用途に応じて以下のように使い分けます。

  • pnpm dlx: 手元のプロジェクトにないパッケージを、一時的にダウンロードして1回だけ実行したい場合(ダウンロードして実行(download and execute)の略)
  • pnpm exec: すでにプロジェクト内(node_modules内)にインストールされているパッケージのコマンドを実行したい場合

参考(感謝)

  • AIに聞きながら
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?