【初心者向け】npmの使い方とパッケージの管理方法について徹底解説

## 概要
フロントエンド開発でよくnpmという単語が出てくるかと思います
今回はnpmとは何か、npmの使い方について解説していきたいと思います

## 前提
- npmおよびnodeをインストール済み

## そもそもnpmって何？
npmはNode.jsのパッケージ(ライブラリ)を管理するパッケージ管理ツールです
npmを使うことでパッケージの依存関係や競合関係を管理してくれるので
パッケージを追加、更新する際は基本的にnpm経由で行うことになります

## アプリケーションを作成
npmを使ってアプリケーションを作成する際は
```
npx create-react-app frontend
```
コマンドを使って作成します
今回はアプリケーション名をfrontendに指定します
作成が完了したらこのような構成になるかと思います
```
tree
.
└── frontend
    ├── .gitignore
    ├── README.md
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── public
    └── src
```

## package.json
アプリケーション作成後にpackage.jsonが作成されます
package.jsonはインストールされたパッケージが記載されたファイルです
このファイルがあることで複数人で開発しても同じパージョンのパッケージを使って開発を行うことができる上に
パッケージの一覧を網羅できるのでとても便利です
下記がpackage.jsonの構成例です

```json:package.json(構成例)
{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build && next export",
    "start": "next start",
    "lint": "next lint",
    "format": "prettier --write './**/*.{ts,tsx,json}'",
    "lint:fix": "eslint --ext .js,jsx,.ts,.tsx --fix",
    "test": "jest"
  },
  "dependencies": {
    "@mui/icons-material": "^5.11.16",
    "@mui/material": "^5.13.5",
    "next": "^13.4.6",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^29.5.2",
    "@types/js-cookie": "^3.0.3",
    "@types/next": "^9.0.0",
    "@types/node": "^20.3.1",
    "@types/react": "^18.2.13",
    "@types/react-dom": "^18.2.6",
    "eslint": "^8.43.0",
    "jest": "^29.5.0",
    "prettier": "^2.8.8",
    "tailwindcss": "^3.3.2",
    "typescript": "^5.1.3"
  }
}
```

## package-lock.json
package.jsonやnode_modulesの構成が変わった際に自動的に生成されます
package-lock.jsonに各パッケージの依存関係が記されています
npmはそれを元にパッケージの依存関係などを調べるため、とても重要です
GitHub Actionsで自動テストやデプロイをする際にpackage-lock.json(lockファイル)を元に
Cacheを使ってパッケージのインストールを高速化させることができるのでpackage.jsonと同様にバージョン管理するのが一般的です

## dependenciesとdevDependencies
package.json内にdependenciesとdevDependenciesが記載されていますが
パッケージの分類分けの際に利用します
違いは以下の通りです
パッケージのインストール方法については後述のパッケージのインストールで解説します

### dependencies
アプリケーションの実行に必要なパッケージやライブラリを指定します
一般的に
- react
- next

など、本番環境でも使用するパッケージはすべてdependenciesに入れます

### devDependencies
開発やテストの実行時に必要なパッケージやライブラリを指定します
一般的に
- jest
- eslint
- prettier

など、開発環境でのみ使用するパッケージはすべてdevDependenciesに入れます
ビルド時にCSSにコンパイルされるTailwindcssや
コンパイル時に型チェックを行うTypescriptなど
実行時に必要ないパッケージもdevDependenciesに入れるのが一般的です

## パッケージのインストール
### dependencies
パッケージのインストールをする際は下記のコマンドを実行します
このインストールされたパッケージはすべてdependenciesに属します
```
npm install <パッケージ名>
```

```terminal:例
npm install next
```

### devDependencies
devDependenciesにパッケージをインストールする際は下記のように--save-devオプションをつけてインストールします
```
npm install --save-dev <パッケージ名>
```

```terminal:例
npm install --save-dev typescript
```

### dependenciesのみインストールするとき
本番環境でデプロイする際は本番環境に必要なパッケージのみインストールしたいため、下記のコマンドを実行します
```
npm ci --omit=dev
```

GitHub ActionsなどCI/CD上ではパッケージの依存関係を解決せずにインストールする
```
npm ci
```

を使うのが一般的です
詳細は下記の公式ドキュメントを参照してください

https://docs.npmjs.com/cli/v8/commands/npm-ci

## scripts
コマンドを実行したい際はscriptsに記載します
下記ではNext.jsを使用しているので公式ドキュメントに従って以下のように記載しています
例えばNext.jsを起動したい場合は
```
npm run dev
```
などnpm経由で実行します
よく使うコマンドなどはscriptsに記載することでプロジェクトメンバー全員が共通のコマンドを使用できるのでとても便利です

```package.json
  "scripts": {
    "dev": "next dev",
    "build": "next build && next export",
    "start": "next start",
    "lint": "next lint",
    "format": "prettier --write './**/*.{ts,tsx,json}'",
    "lint:fix": "eslint --ext .js,jsx,.ts,.tsx --fix",
    "test": "jest"
  },
```

## パッケージのアップデート
npm outdatedを使って古いパッケージを検出して指定したパッケージをアップデートするのが一般的です
```
npm outdated
Package                      Current  Wanted  Latest  Location                                  Depended by
@testing-library/react        13.4.0  13.4.0  14.0.0  node_modules/@testing-library/react       code
@testing-library/user-event   13.5.0  13.5.0  14.4.3  node_modules/@testing-library/user-event  code
web-vitals                     2.1.4   2.1.4   3.3.2  node_modules/web-vitals                   code
```

下記のコマンドを使ってパッケージをアップデートすることができます
```
npm update <パッケージ名>
```

```terminal:例
npm update @testing-library/react
```

## パッケージのアンインストール
下記のコマンドを使ってパッケージをアンインストールすることができます

```
npm uninstall <パッケージ名>
```

```terminal:例
npm uninstall react-scripts
```

## まとめ
npmを使うとフロントエンド開発で使用するパッケージの管理方法などについて知ることができました
他に便利な機能があれば随時追加していきたいと思います

## 参考
https://qiita.com/chihiro/items/ca1529f9b3d016af53ec

https://www.fenet.jp/infla/column/technology/%E3%80%90npm%E3%80%91%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AEupdate%E6%96%B9%E6%B3%95%E3%82%92%E7%B4%B9%E4%BB%8B%E3%81%97%E3%81%BE%E3%81%99/

https://nextjs-ja-translation-docs.vercel.app/docs/getting-started

https://kosuke-space.com/package-json-npm