Node.jsとは何かで触れたとおり、Node.jsにはnpm(Node Package Manager)というパッケージ管理の仕組みが標準で付いてきます。この記事では、npmが実際に何をしているのかを見ていきます。
ライブラリとは、誰かが書いた「借り物」
ソフトウェアを作るとき、必要な機能をすべて自分でゼロから書くことは、まずありません。「日付を扱う」「文字列を安全な形に整える」「画面の部品を組み立てる」——こうしたよくある処理は、すでに誰かが書いて、無料で公開してくれています。この、再利用できる形で公開されたコードのかたまりを「ライブラリ」または「パッケージ」と呼びます。
たとえばXSSの防ぎ方で紹介したDOMPurify(危険なHTMLを無害化するライブラリ)も、ReactやVue自体も、すべて「誰かが書いて公開した、借りて使えるコード」という意味では同じ仲間です。npmは、この「借り物」を自分のプロジェクトに取り込むための仕組みです。
package.jsonという「持ち物リスト」
Node.jsのプロジェクトには、たいていpackage.jsonというファイルがあります。ここに、このプロジェクトがどのライブラリに依存しているかが書かれています。
{
"name": "my-app",
"dependencies": {
"react": "^18.2.0"
}
}
"react": "^18.2.0"は「reactというライブラリの、18.2.0以降・19未満の版を使う」というおおまかな指定です(先頭の^は「大きな変更を伴わない範囲でなら新しい版でもよい」という意味の記号で、詳しい版の指定方法は別記事で改めて扱います)。このpackage.jsonさえあれば、同じ持ち物リストを、別のパソコンでもそのまま再現できます。
npm installと、node_modules
npm install(短縮形npm i)というコマンドを実行すると、package.jsonに書かれたライブラリを、インターネット経由でまとめてダウンロードしてきます。ダウンロードされた中身は、プロジェクトの中のnode_modulesという名前のフォルダに置かれます。
このnode_modules、ライブラリがさらに別のライブラリに依存している連鎖のせいで、あっという間に巨大になることで知られています。数個のライブラリを指定しただけのつもりでも、実際には数百個のフォルダが並ぶ、というのはNode.jsを使うプロジェクトではよくある光景です。むやみに増やしすぎない、というのが1つの心がけどころになります(依存ライブラリの脆弱性とサプライチェーン攻撃にも関わる話です)。
バージョンを固定する、もう1つのファイル
npm installを実行すると、package-lock.jsonというファイルも自動的に作られます。これは、「実際にどの版がインストールされたか」を1つずつ細かく記録したファイルです。package.jsonのおおまかな指定だけでは、実行するタイミングによって微妙に違う版がインストールされてしまうことがありますが、package-lock.jsonがあれば誰の環境でも寸分違わず同じ版を再現できます。このファイルは、通常はGitで一緒に管理します。
npmだけではない
Node.jsに標準で付いてくるのはnpmですが、同じ役割を果たす道具としてYarnやpnpmもよく使われます。どれも「package.jsonを読んで、必要なライブラリを取り込む」という基本の役割は共通していて、プロジェクトによってどれを使うかが決まっています。
エージェントに頼む時代の向き合い方
エージェントに「ログイン機能を作って」のように頼むと、その裏でnpm installが何度も走り、見覚えのないライブラリが次々と増えていきます。それぞれが何をしているのか全部を追う必要はありませんが、「これは他人のコードを大量に取り込んでいる」という感覚だけは持っておくと安心です。 既知の脆弱性がないかを確認するnpm auditのようなコマンドについては、依存ライブラリの脆弱性とサプライチェーン攻撃にまとめています。
まとめ
- ライブラリ(パッケージ)は、誰かが書いて公開した、再利用できるコードのかたまり
- npmは、それを自分のプロジェクトに取り込むための管理の仕組み。Node.jsに標準で付いてくる
package.jsonが「持ち物リスト」、npm installで実際にダウンロード、中身はnode_modulesフォルダに置かれるpackage-lock.jsonが、誰の環境でも同じ版を再現するための記録- Yarnやpnpmといった、npm以外の選択肢もある