package-lock.jsonファイルの役割について

# ■はじめに

はじめまして。[白水（しらみず）](https://lit.link/js226)と申します。
普段は不動産スタートアップでフロントエンドエンジニアとしてお仕事しています。
今回は「package-lock.jsonファイルの役割」について記事にしました。
良ければご覧ください。

[Shiramizu\_Junya lit\.link\(リットリンク\)](https://lit.link/js226)

# ■環境

- Mac
    - チップ：Apple M2 Max
    - OS：macOS Sonoma バージョン14.6.1
- npm：10.8.2

# ■環境構築

```terminal
// SSH
❯ git clone --filter=blob:none --no-checkout git@github.com:shiramizu-junya/private-tech-blog.git && cd private-tech-blog && git sparse-checkout set --cone && git 
checkout main && git sparse-checkout set 2024-09-23-sample

// HTTPS
❯ git clone --filter=blob:none --no-checkout https://github.com/shiramizu-junya/private-tech-blog.git && cd private-tech-blog && git sparse-checkout set --cone && 
git checkout main && git sparse-checkout set 2024-09-23-sample
```

上記コマンドを実行して、リポジトリをCloneします。
`package.json`ファイルの作り方がわからない人は利用ください。

# ■パッケージの情報を確認

### ◆パッケージの情報を調べる方法

```terminal
❯ npm view babel-cli
```

![スクリーンショット 2024-09-22 17.04.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/77a41cff-bd6c-eb4f-2b7d-17d02a4a0d1b.png)


まずは、パッケージの情報を調べてみます。

`npm view <パッケージ名>`でパッケージの情報を確認する事ができます。

- babel-cli@6.26.0
    - パッケージ名と現在の安定バージョン
- MIT
    - ライセンス
- deps: 15
    - dependenciesで依存しているパッケージの数
- versions: 75
    - NPMレジストリに公開されているパッケージのバージョン数
- https://babeljs.io/
    - パッケージのホームページ
- https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz
    - パッケージのダウンロードに使用されるURL
- dependencies
    - dependenciesで依存しているパッケージの一覧
- latest: 6.26.0
    - 現在の安定バージョン
- next: 7.0.0-beta.3
    - 次の公開バージョン

### ◆パッケージバージョン一覧を調べる方法

```terminal
❯ npm view babel-cli versions
```

![スクリーンショット 2024-09-23 16.35.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/b86cffac-e02a-ed31-626d-3472af6f2751.png)


`npm view <パッケージ名> versions`とコマンドを打つと、パッケージのバージョンを一覧で確認できます。

`npm view babel-cli`と打ったときの表示と、バージョン一覧が対応している事がわかります。

ここで表示されているいずれかのバージョンのパッケージをインストールすることができます。

# ■package.lock.jsonとは？

npmでパッケージをインストールすると、インストールしたパッケージと、インストールしたパッケージが依存している、パッケージもインストールされます。

例えば、babel-cliをインストールすると、babel-cliは１５個の依存関係があったので、１５個の依存パッケージもインストールされます。

package-lock.jsonには、インストールしたパッケージと、依存関係にあるパッケージのバージョンなどが記録されます。

npmバージョン「5.0.0」から自動で`package-lock.json`ファイルが作成されるようになりました。

お店でものを購入した際に発行される「レシート」のような役割を担うファイルです。


# ■package-lock.jsonファイルが無い場合の問題点

![スクリーンショット 2024-09-23 17.00.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/dfa09c78-b7be-4ab8-12d2-793aa1c31e6e.png)


`package.lock.json`ファイルが無いプロジェクトがあったとします。

Aさんが「babel-cli」の「6.4.0」をインストールして、プロジェクトのベースコードを作成しました。

その後、Bさんがチームに加入して、Bさんが`git clone`して`npm install`コマンドを実行しました。

このときはまだ、「babel-cli」の「6.4.0」が安定バージョンだったため、「6.4.0」がBさんのローカルにインストールされました。

月日が流れ、Cさんがチームに加入しました。

Cさんが`git clone`して`npm install`コマンドを実行しました。

このとき、「babel-cli」がバージョンアップされていて、「6.8.0」が安定バージョンだったと仮定します。

すると、「^」はマイナーバージョンの変更までは許容するので、Cさんのローカルには「6.8.0」がインストールされます。

マイナーバージョンの更新は、いくつかの新機能が追加されるとマイナーバージョンが上がるので、Cさんは新しい機能が使えて、

AさんとBさんは使えないという状況になり、コード内に「6.8.0」の新機能コードが入っていると、AさんとBさんのローカルプロジェクトはエラーになります。

また、`package.json`には「babel-cli」が更に依存している他の子孫パッケージのバージョンなどは記載されていないため、子孫パッケージのバージョンアップが起こった際も、バグが発生する可能性があります。

これらの人によってバージョンが変わる＝環境の差異が出ることを解決するのが「package-lock.json」ファイルです。

「package-lock.json」には「package.json」ファイルに記載されている「^6.4.0」のような曖昧なバージョンではなく、

固定されたバージョンが記載されます。

そのため、「package-lock.json」があると、`npm install`コマンドを実行した際に、「package-lock.json」に記載されているパッケージのバージョンをインストールするため「Aさん・Bさん・Cさん」のローカル環境に差異が出ません。

# ■実際にやってみる

```terminal
❯ npm install babel-cli@6.4.0
```

![スクリーンショット 2024-09-23 17.36.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/3b9563bb-c878-7357-6954-a760b071a9ac.png)

`npm install babel-cli@6.4.0`コマンドを実行すると、`package-lock.json`ファイルには、キャレット無しの「6.4.0」が記載されています。

そのため、現在「babel-cliの6.4.0」がインストールされています。

![スクリーンショット 2024-09-23 17.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/8bc72024-c662-a7a3-e16e-99793a6094c4.png)

`node_modules`配下の`babel-cli`ディレクトリ内の`package.json`を確認しても、バージョンが「6.4.0」になっていることがわかります。

![スクリーンショット 2024-09-23 17.41.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/65db221a-7a9f-65a6-3a32-bfe872b9df0b.png)

ここで`node_modules`と`package-lock.json`ファイルを削除して、再度`npm install`コマンドを実行してみます。

`pacakge.json`ファイルのみ残っています。

![スクリーンショット 2024-09-23 17.43.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/fd8937b8-2dba-9d69-bdfd-0a644c689f3f.png)

すると、「babel-cli」の「6.26.0」がインストールされました。

`package-lock.json`ファイルがないと、`package.json`ファイルを見て、「^6.4.0」と記載されているので、マイナーバージョンの中で最新の安定版である「6.26.0」がインストールされます。

もし、別の人がインストールした際に「6.30.0」がリリースされていたら、「6.30.0」がインストールされます。

このように`package-lock.json`ファイルがないと、`npm install`コマンドを実行する時期のバージョンに応じて、ここのローカル環境が変わってしまいます。

![スクリーンショット 2024-09-23 18.11.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/e4d1483e-a985-8af6-1cd8-eb1e151808c5.png)

逆に、`package-lock.json`ファイルがある状態で、`npm install`コマンドを実行すると、`package-lock.json`に記載されているバージョンのパッケージがインストールされるため、環境に差異が出ません。

# ■package-lock.jsonファイルの中身を確認してみる

```terminal
❯ npm install mocha -D
```

![スクリーンショット 2024-09-23 17.59.01 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307408/81371edc-d43e-6bc9-dc92-296fae6865f5.png)


- `"version": "10.7.3",`
    - インストールされているバージョン
- `"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz",`
    - インストールに使用されたURL
- `"dev": true,`
    - devDependenciesでインストールされた場合は、`"dev": true,`になる。
        
        mochaが依存しているパッケージも全て`"dev": true,`になる。
        
        dependenciesでインストールすると、`"dev": true,`は無くなります。
        
- dependencies
    - mochaが依存しているパッケージの一覧
        
        `node_modules/mocha/package.json`のdependenciesに記載されているパッケージが表示されています。
        
        そのためdevDependenciesはインストールされていません。

# ■【おまけ】node_modulesディレクトリ配下の容量を確認してみる

```terminal
❯ du -hs node_modules/
```

上記コマンドで、`node_modules/`配下の容量を確認できます。

# ■まとめ

`package-lock.json`ファイルがあることで、プロジェクトの環境構築で人によって差異が出ないことという役割がわかりました。
また、`package-lock.json`ファイルを確認すれば、どのパッケージがどのバージョンでインストールされているのかもわかります。
そのため、package-lock.jsonもGitの管理下にcommitする必要があります。