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など
- Webフレームワーク:
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これを実行すると:
- npm レジストリから
dayjsパッケージがダウンロードされる - プロジェクト内に
node_modules/dayjsとして展開される package.jsonのdependenciesにdayjsが追加されるpackage-lock.jsonが更新される(後で解説)
package.json の例:
{
"dependencies": {
"dayjs": "^1.11.10"
}
}開発用だけの依存 --save-dev
npm install --save-dev jest
# または省略形
npm i -D jestpackage.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.10→1.12.0→1.99.99まではOK、2.0.0はNG
"~1.11.10":
1.11.xの範囲で更新を許可(=MINOR は固定)- 例:
1.11.10→1.11.11→1.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 ciやnpm installすると、
同じバージョンセットが再現 できる
イメージ:
package.json:
「dayjsの 1系なら何でもいいよ(^1.11.10)」という緩い希望package-lock.json:
「実際にはdayjsの 1.11.10 と、その依存の …」という具体的な確定情報
npm install / npm ci / npm update の違い
npm installpackage.jsonを見て、依存がなければ新しく入れる- 既にある場合は、
package-lock.jsonとの兼ね合いで更新したりしなかったり - 開発中に新しいパッケージを追加するときに使う
npm ci- 「ロックファイルに厳密に従って」
node_modulesを作り直す - CI環境(自動テスト)などでよく使う
- 「ロックファイルに厳密に従って」
npm updatepackage.jsonの範囲内で、依存パッケージを新しいバージョンに上げていく- アップデートの検証が必要
最初のうちはまず npm install パッケージ名 だけ覚えておけば十分です。
そのあと、実務に近づいてきた段階で npm ci や npm 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 start→npm run startnpm test→npm run test
など。
ローカルインストールされたCLIの呼び出し
たとえば eslint を devDependencies にインストールしているとします:
npm install --save-dev eslintnode_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 runかnpxを使っておけば大体困らない
Node / npm バージョン管理
- 実務では「プロジェクトAは Node 18、プロジェクトBは Node 20」などバージョンが違うことが普通
- 1つのマシンに複数の Node バージョンを入れて、プロジェクトごとに切り替える
→nvm/fnm/asdfなどのツールが使われる
今は:
- 「Node と npm のバージョンはプロジェクトごとに意識して分けることがある」
- 「
package.jsonで"engines"フィールドにnodeのバージョンを書いておく場合がある」
くらいの理解で十分です。
{
"engines": {
"node": ">=18.0.0"
}
}
コメント