[JavaScript講座] npmとパッケージ管理

当ページのリンクには広告が含まれています。
目次

npm とは何か?

npm の役割

npm はざっくり説明すると、「JavaScript / Node.js 用のパッケージ(ライブラリ)の配布・管理システム」です。

  • npm レジストリ:パッケージが公開されている巨大な倉庫(オンラインサービス)
  • npm CLI(コマンド):npm install などのコマンドでパッケージを取得・更新するツール
  • Node.js をインストールすると、通常 npm も一緒に入る

パッケージとは?

  • 再利用可能なコードのまとまり
  • 1つのパッケージ = 1つのフォルダ+package.json(メタ情報)
  • 例:
    • Webフレームワーク:express, next, nuxt
    • ビルドツール:webpack, vite, rollup
    • テスト:jest, vitest
    • ユーティリティ:lodash, dayjs など

package.json の役割と構造

npm プロジェクトの中心になるのが package.json ファイル です。

npm init で作る

新しいフォルダを作って、そこで:

npm init -y

を実行すると、最小限の package.json が生成されます。

例:

{
  "name": "my-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

よく使うフィールド

最低限、次を押さえておけばOKです。

  • "name":パッケージ名(公開しないローカルプロジェクトでも一応必要)
  • "version":バージョン番号(セマンティックバージョニング)
  • "main":Node.js 環境で require されたときのエントリーポイント(ESM だと "exports""type": "module"など別の話も出てくるが、ここでは深追いしない)
  • "scripts"npm run XXX で実行できるコマンドエイリアス
  • "dependencies":本番環境でも必要な依存パッケージ
  • "devDependencies":開発中だけ必要な依存パッケージ(テスト、ビルドツール等)

依存関係:dependencies / devDependencies

npm install で依存を追加

npm install dayjs

これを実行すると:

  1. npm レジストリから dayjs パッケージがダウンロードされる
  2. プロジェクト内に node_modules/dayjs として展開される
  3. package.jsondependenciesdayjs が追加される
  4. package-lock.json が更新される(後で解説)

package.json の例:

{
  "dependencies": {
    "dayjs": "^1.11.10"
  }
}

開発用だけの依存 --save-dev

npm install --save-dev jest
# または省略形
npm i -D jest

package.json

{
  "devDependencies": {
    "jest": "^29.7.0"
  }
}
  • テストフレームワーク、ビルドツール、型チェッカー、リンターなどは 通常 devDependencies に入れる
  • フロントエンドのビルド後にはバンドルされるので、「本番環境に npm があるかどうか」とは別の話になりますが、管理の観点として「開発にだけ必要か?」で分けておくと分かりやすい

セマンティックバージョニング(SemVer)の基本

"^1.11.10""~2.3.4" のような書き方は、SemVer(セマンティックバージョニング) に基づく「許容バージョン範囲」の指定です。

バージョン番号の意味:MAJOR.MINOR.PATCH

例:1.11.10

  • 1:MAJOR バージョン
  • 11:MINOR バージョン
  • 10:PATCH バージョン

基本ルール:

  • MAJOR:仕様変更(後方互換性が崩れる可能性)
  • MINOR:機能追加(後方互換性あり)
  • PATCH:バグ修正(後方互換性あり)

^~ の違い(よく見る2つ)

"^1.11.10"

  • 1.x.x の範囲で更新を許可(=MAJOR が変わらない範囲)
  • 例:1.11.101.12.01.99.99 まではOK、2.0.0 はNG

"~1.11.10"

  • 1.11.x の範囲で更新を許可(=MINOR は固定)
  • 例:1.11.101.11.111.11.99 はOK、1.12.0 はNG

ざっくりした感覚:

  • ^:ある程度柔軟にアップデートを許可(デフォルト)
  • ~:MINOR を固定したい(慎重寄り)

実務ではデフォルトの ^ をそのまま使いつつ、
「どうしても壊れたら困るパッケージ」は厳しめにピン留め、などの戦略をとることが多いです。

node_modules とロックファイル(package-lock.json)

node_modules の役割

npm install すると、プロジェクト内に node_modules フォルダ ができます。

  • この中に、インストールしたパッケージと、そのパッケージがさらに依存するパッケージ…が全部入る
  • 非常に巨大になりがち(数万ファイルになることも普通)
  • Git では通常 .gitignore に入れてコミットしない

package-lock.json の役割

npm install 時に自動生成される「ロックファイル」です。

  • 実際にインストールされた各パッケージの 正確なバージョン が記録される
  • チームメンバーが同じ package-lock.json を使って npm cinpm install すると、
    同じバージョンセットが再現 できる

イメージ:

  • package.json
    dayjs の 1系なら何でもいいよ(^1.11.10)」という緩い希望
  • package-lock.json
    「実際には dayjs の 1.11.10 と、その依存の …」という具体的な確定情報

npm install / npm ci / npm update の違い

  • npm install
    • package.json を見て、依存がなければ新しく入れる
    • 既にある場合は、package-lock.json との兼ね合いで更新したりしなかったり
    • 開発中に新しいパッケージを追加するときに使う
  • npm ci
    • 「ロックファイルに厳密に従って」node_modules を作り直す
    • CI環境(自動テスト)などでよく使う
  • npm update
    • package.json の範囲内で、依存パッケージを新しいバージョンに上げていく
    • アップデートの検証が必要

最初のうちはまず npm install パッケージ名 だけ覚えておけば十分です。
そのあと、実務に近づいてきた段階で npm cinpm update の意味を整理すると良いです。

scripts と npm run

scripts でコマンドのショートカットを定義

package.json

{
  "scripts": {
    "start": "node index.js",
    "test": "node test.js",
    "build": "node build.js"
  }
}

これで、

npm run start
npm run test
npm run build

のように実行できます。

特別扱いされるスクリプト名もあります:

  • npm startnpm run start
  • npm testnpm run test

など。

ローカルインストールされたCLIの呼び出し

たとえば eslintdevDependencies にインストールしているとします:

npm install --save-dev eslint

node_modules/.bin/eslint という実行ファイル(スクリプト)ができるのですが、
npm run 経由なら PATH を気にせず呼び出せます。

{
  "scripts": {
    "lint": "eslint src"
  }
}

npm run lint
  • グローバルインストールなしで、プロジェクト固有のバージョンの eslint を実行できる
  • 「プロジェクトごとにツールのバージョンを固定したい」という要件を満たす

npx の役割

npx は、「npm パッケージに含まれるコマンドを一時的に実行するためのツール」

とイメージすると分かりやすいです。

公式テンプレートなどの実行に使う

例:React アプリのテンプレートを作る create-react-app(古典例)

npx create-react-app my-app
  • 手元に create-react-app がなくても、その場でダウンロードして実行してくれる
  • グローバルにツールが溢れないので、環境が汚れにくい

ローカルの CLI 実行にも使える

プロジェクトにローカルインストールしたCLIツールを、
npx で直接呼ぶこともできます:

npx eslint src
  • 実質的には「node_modules/.bin/eslint をいい感じに探して実行」してくれる
  • 最近の Node / npm 環境では、npm runnpx を使っておけば大体困らない

Node / npm バージョン管理

  • 実務では「プロジェクトAは Node 18、プロジェクトBは Node 20」などバージョンが違うことが普通
  • 1つのマシンに複数の Node バージョンを入れて、プロジェクトごとに切り替える
    nvm / fnm / asdf などのツールが使われる

今は:

  • 「Node と npm のバージョンはプロジェクトごとに意識して分けることがある」
  • package.json"engines" フィールドに node のバージョンを書いておく場合がある」

くらいの理解で十分です。

{
  "engines": {
    "node": ">=18.0.0"
  }
}

<<前へ(動的インポートとモジュール情報)

>>次へ(JavaScriptの実行モデルとマイクロタスク)

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次