ウェブエンジニア問題集
第3章

npmとpackage.jsonの読み方 — 依存管理・scripts・lockファイル

9
この章の目次開く

Node.jsのプロジェクトは、ほぼ必ず package.json を持っています。npm installnpm run devnpm run build のようなコマンドも、裏側では package.json と npm の仕組みによって動いています。

package.json が読めないと、「どのライブラリに依存しているのか」「開発サーバーはどのコマンドで起動するのか」「Node.jsのモジュール方式はどちらか」「なぜlockファイルをコミットするのか」が見えません。

package.json は、Node.jsプロジェクトの説明書であり、依存関係と実行コマンドの入口です。
学習者学習者

npm install はよく打ちます。でも package.json の中身は、正直あまり読んでいません。消したらまずそう、くらいの認識です。

先生先生

まずは全部覚えなくていいよ。scriptsdependenciesdevDependenciestypeengines が読めるだけで、実務ではかなり困りにくくなる。

npmとは

npmは、Node.js向けのパッケージマネージャーです。外部ライブラリをインストールし、プロジェクトの依存関係を管理し、登録済みのスクリプトを実行します。

用途コマンド例
パッケージを追加するnpm install express
開発用パッケージを追加するnpm install -D vitest
依存関係をインストールするnpm install
scriptを実行するnpm run build
パッケージを削除するnpm uninstall express

npm以外にも pnpm や Yarn がありますが、package.json の基本的な読み方は共通です。この章では npm を基準に説明します。

package.jsonの基本形

最小限の package.json は、たとえば次のような形です。

{
  "name": "my-node-app",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "node src/server.js",
    "test": "node --test"
  },
  "dependencies": {
    "express": "^5.1.0"
  },
  "devDependencies": {
    "vitest": "^3.2.0"
  },
  "engines": {
    "node": ">=22"
  }
}
json

よく見るフィールドを整理します。

フィールド説明
nameパッケージ名。公開しないアプリでもプロジェクト識別に使う
versionパッケージのバージョン
type.js ファイルをES Modulesとして扱うかCommonJSとして扱うかを決める
scriptsnpm run ... で実行できるコマンド集
dependencies本番実行に必要な依存パッケージ
devDependencies開発・テスト・ビルドに必要な依存パッケージ
engines想定するNode.jsやnpmのバージョン

scripts — npm runで実行するコマンド

scripts は、プロジェクトでよく使うコマンドに名前を付ける場所です。

{
  "scripts": {
    "dev": "node src/server.js",
    "test": "node --test",
    "build": "tsc"
  }
}
json

実行するときは npm run を使います。

npm run dev
npm run test
bash

構文: npm run <script-name> [-- <args>]

引数説明
<script-name>package.jsonscripts に定義した名前
-- <args>(省略可)scriptに渡す追加引数。-- 以降が実行コマンド側へ渡る

戻り値: シェルコマンドとしての終了コード。成功なら通常 0、失敗なら 0 以外

npm run test -- --watch
bash

scripts に入れておくと、チーム全員が同じコマンドで開発・テスト・ビルドできます。READMEに「この長いコマンドを打ってください」と書くより、npm run dev に寄せる方が運用しやすくなります。

dependenciesとdevDependencies

依存関係には、大きく2種類あります。

フィールド入れるもの
dependenciesアプリを本番で動かすために必要なものexpress, mysql2, zod
devDependencies開発・テスト・ビルドでだけ必要なものvitest, typescript, eslint

たとえばExpressアプリを本番で動かすなら、Expressは dependencies です。一方、テストランナーやリンターは本番実行時には不要なので devDependencies に入れます。

npm install express
npm install -D vitest
bash

構文: npm install [package-spec ...] [options]

引数・オプション説明
package-specインストールするパッケージ名。例: express, vitest@latest
-D, --save-devdevDependencies に追加する
省略時パッケージ名を省略すると、package.json とlockファイルに基づいて依存関係をインストールする

戻り値: インストール結果を示す終了コード。成功なら通常 0

「本番でアプリが起動するために必要か」で dependenciesdevDependencies を分けます。

バージョン指定の読み方

dependencies には、パッケージ名とバージョン範囲が書かれます。

{
  "dependencies": {
    "express": "^5.1.0",
    "zod": "~3.25.0"
  }
}
json

代表的な記号は次の通りです。

書き方意味
1.2.3ちょうど 1.2.3
^1.2.3互換性がある範囲で新しいバージョンを許可する。多くの場合 1.x.x の範囲
~1.2.3パッチ更新を中心に許可する。多くの場合 1.2.x の範囲
latest最新版。アプリの依存として固定的に使うには避けたい

実際にインストールされた厳密なバージョンは、次の package-lock.json に記録されます。

package-lock.jsonの役割

package-lock.json は、依存関係ツリーの実際に解決されたバージョンを記録するファイルです。

package.json が「この範囲のバージョンを使ってよい」という宣言なら、package-lock.json は「今回はこの厳密なバージョンを使った」という記録です。

ファイル役割
package.json人間が読む依存関係とコマンドの定義
package-lock.jsonnpmが解決した厳密な依存関係ツリー
node_modules/実際にインストールされたパッケージ本体

アプリケーション開発では、package-lock.json は原則コミットします。チームやCIで同じ依存バージョンを再現しやすくするためです。

npm installとnpm ciの使い分け

ローカル開発では npm install を使う場面が多いですが、CIでは npm ci がよく使われます。

コマンド用途
npm install依存追加やローカル開発。lockファイルを更新することがある
npm ciCIや本番ビルド。lockファイルに厳密に従ってクリーンインストールする

npm cipackage-lock.json があることを前提に、より再現性の高いインストールを行います。CIで「手元では動くのにCIで依存が違う」を減らすためのコマンドです。

この章のまとめ

package.json は、Node.jsプロジェクトの入口です。

  • npmはNode.jsのパッケージ管理とscript実行を担う
  • scripts はチーム共通の実行コマンドを定義する
  • dependencies は本番実行に必要な依存
  • devDependencies は開発・テスト・ビルド用の依存
  • package-lock.json は実際に解決された依存バージョンを固定する
  • CIでは npm ci がよく使われる

次章では、package.json"type" と深く関係する、CommonJSとES Modulesの違いを見ていきます。

参考リンク

Node.jsクイズに挑戦するこの章で学んだNode.jsの知識を、4択クイズでアウトプットして定着させよう