バージョン管理の考え方とNPMとpackage.jsonの役割

## はじめに
**Node.js**を学び始めました。**npm** に初めて触れるときは、**package.json** がどういう役割をもっているのか、パッケージをインポートするとはどういうことなのか、概要をつかむのが大変だと思います。

**Node.js**プロジェクトの設定ファイルである**package.json**で、プロジェクトのメタデータ、依存関係、スクリプト、バージョン情報などを定義がどのようなものであるのか、整理したかったので、内容をまとめてみました。

:::note info
**NPMは、Node.js用のJavaScriptパッケージを管理するためのツールです。**
**package.jsonは、Node.jsプロジェクトに関する情報を記述するJSON形式のファイルです。**

NPMとpackage.jsonは、密接に連携して動作します。NPMは、package.jsonに記述された情報に基づいて、パッケージのインストールやスクリプトの実行を行います。一方、package.jsonは、NPMコマンドで生成したり、手動で編集したりすることができます。

つまり、**NPMはパッケージの管理ツール、package.jsonはプロジェクトに関する情報を記述するファイル**という関係性になります。
:::

## バージョンは「.」で区切られた 3 つの数字から構成されている

バージョンは`.`で区切られた3つの数字で構成されていますが、これは **SemVer** (Semantic Versioning) と呼ばれる規則に基づいています。SemVerは、ソフトウェアのバージョン番号を解釈し、互換性を判断するためのルールです。

バージョン管理を適切に行うことで、変更履歴の追跡、バグの修正、機能の追加、CI/CD、リリースの管理が容易になります。

:::note info
**バージョンの書き方**
     - `1.0.0`: 初回リリース
     - `1.1.0`: 新機能の追加
     - `1.1.1`: バグ修正
:::

**SemVer形式**

```
MAJOR.MINOR.PATCH
```
| バージョンの構成 | 説明 |
|------------------|------|
| **MAJOR** | **重大な変更や互換性のない変更が行われた場合に増加します。**<br>APIが大きく変更されたり、互換性を保てない新機能が追加された場合などに上げられます。 |
| **MINOR** | **新機能が追加されたが、互換性が保たれている場合に増加します。**<br>バグ修正や既存機能の改善など、互換性を保ちながら機能が拡張された場合などに上げられます。 |
| **PATCH** | **バグ修正や小さな改善が行われた場合に増加します。**<br>既存の機能やAPIを変更せずに、問題を修正した場合などに上げられます。 |


* **1.1.0:** 新機能が追加されたが、互換性は保たれている

* **1.2.3:** 既存の機能の不具合を修正した

* **2.0.0:** APIが大きく変更された。これは、API に非互換性の変更があることを示します。





## バージョン管理の基本概念

3. **ブランチ**
   - **ブランチ**: 開発の異なるラインを並行して進めるための機能です。例えば、新機能の開発やバグ修正のためにブランチを作成します。


4. **タグ**
   - タグは、特定のコミットに対してラベルを付ける機能です。リリースバージョンを示すために使用されます。例えば、`v1.0.0`のようにタグを付けます。

## バージョン管理の実践


1. **Gitフロー (Git Flow)**
   - Gitフローは、Gitを使用したブランチ戦略の一つです。
     - **main**: 安定したリリースバージョンを管理するブランチ。
     - **develop**: 次のリリースに向けた開発を行うブランチ。
     - **feature**: 新機能の開発を行うブランチ。
     - **release**: リリース準備を行うブランチ。
     - **hotfix**: 緊急のバグ修正を行うブランチ。

2. **リリース管理**
   - リリース管理は、ソフトウェアの新しいバージョンをリリースするプロセスです。リリースノートを作成し、変更点や新機能、バグ修正を記載します。
   - リリースタグを作成し、特定のコミットに対してタグを付けます。例えば、`v1.2.0`のようにタグを付けます。


## package.json とは


`package.json` ファイルは、Node.jsプロジェクトにおいて、そのプロジェクトの情報や依存関係、スクリプトなどの設定を記述するためのファイルです。Node.jsのプロジェクトは、外部のパッケージを利用することが一般的であり、`package.json` はそのプロジェクトがどのようなパッケージを使用し、どのバージョンを利用しているかを管理するために不可欠です。適切に設定することで、プロジェクトの開発、ビルド、デプロイがスムーズに行えるようになります。このファイルは、プロジェクトのルートディレクトリに配置され、npm（Node Package Manager）やyarnなどのパッケージマネージャーによって使用されます。

**主な役割**

| 項目 | 説明 |
|------|------|
| **依存関係の管理** | プロジェクトが依存する外部パッケージをリストアップし、それぞれのバージョンを指定します。これにより、プロジェクトに必要なすべてのパッケージが確実にインストールされ、バージョンによる動作の違いを防ぎます。 |
| **バージョン管理** | 依存関係パッケージのバージョン範囲を指定することで、メジャーバージョンアップによる互換性の破綻を防ぎ、安定した開発環境を維持することができます。 |
| **スクリプト実行** | テストの実行、ビルド、アプリケーションの起動など、プロジェクトに関わるさまざまなタスクを自動化するためのスクリプトを定義することができます。 |
| **メタ情報の提供** | プロジェクト名、説明、ライセンス、著者などの情報を記述することで、プロジェクトに関する基本的な情報を共有することができます。 |
| **タスクの自動化** | テストの実行、ビルド、アプリケーションの起動など、プロジェクトに関わるさまざまなタスクを自動化することができます。 |
| **プロジェクト情報の共有** | プロジェクト名、説明、ライセンス、著者などの情報を記述することで、プロジェクトに関する基本的な情報を共有することができます。 |
| **再現性の向上** | 異なる開発環境でも、同じ設定でプロジェクトをセットアップすることができます。 |


**package.json の作成と利用**

`package.json` ファイルは、テキストエディタで直接作成することができます。また、Node.jsの初期化コマンド `npm init` を使用して、対話形式で作成することもできます。

作成された `package.json` ファイルは、プロジェクトのルートディレクトリに配置する必要があります。その後、`npm install` コマンドを実行することで、依存関係パッケージをインストールすることができます。

`package.json` ファイルに定義されたスクリプトは、`npm run` コマンドを使用して実行することができます。


**package.json の構成**

| フィールド | 説明 |
|------------|------|
| **name** | プロジェクトの名前。小文字で、スペースや特殊文字を含まないようにします。 |
| **version** | プロジェクトのバージョン。セマンティックバージョニング（例: 1.0.0）を使用します。 |
| **description** | プロジェクトの簡単な説明。 |
| **main** | エントリーポイントとなるJavaScriptファイル。通常は`index.js`が指定されます。 |
| **scripts** | プロジェクトで使用するスクリプトを定義します。例えば、`start`や`test`などのスクリプトを設定できます。 |
| **keywords** | プロジェクトに関連するキーワードのリスト。検索エンジンでの発見性を高めるために使用されます。 |
| **author** | プロジェクトの作者情報。 |
| **license** | プロジェクトのライセンス情報。 |
| **repository** | プロジェクトのリポジトリ情報。通常はGitリポジトリのURLを指定します。 |
| **bugs** | プロジェクトのバグ報告用のURLやメールアドレスを指定します。 |
| **homepage** | プロジェクトのホームページURLを指定します。 |
| **engines** | プロジェクトが動作するNode.jsのバージョンを指定します。 |
| **browserslist** | プロジェクトがサポートするブラウザのリストを指定します。フロントエンドプロジェクトでよく使用されます。 |

### **依存関係**
- **dependencies**: プロジェクトが動作するために必要なパッケージを指定します。これらのパッケージは、`npm install`コマンドでインストールされます。
- **devDependencies**: 開発環境でのみ必要なパッケージを指定します。例えば、テストフレームワークやビルドツールなどが含まれます。
- **peerDependencies**: プロジェクトが動作するために必要な、他のパッケージと一緒にインストールされるべきパッケージを指定します。
- **optionalDependencies**: インストールが必須ではないが、存在すれば利用されるパッケージを指定します。


### **例: `package.json`**


```json
{
  "name": "my-project",
  "version": "1.0.0",
  "description": "A simple Node.js project",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "node",
    "project"
  ],
  "author": "Your Name",
  "license": "MIT",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.7"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/yourusername/my-project.git"
  },
  "bugs": {
    "url": "https://github.com/yourusername/my-project/issues"
  },
  "homepage": "https://github.com/yourusername/my-project#readme"
}
```

## **スクリプトの例**
`package.json`の`scripts`フィールドには、プロジェクトでよく使うコマンドを定義できます。

```json
"scripts": {
  "start": "node index.js",
  "test": "mocha",
  "build": "webpack --config webpack.config.js",
  "lint": "eslint .",
  "dev": "nodemon index.js"
}
```

- **start**: プロジェクトを起動するためのスクリプト。
- **test**: テストを実行するためのスクリプト。
- **build**: プロジェクトをビルドするためのスクリプト。
- **lint**: コードの静的解析を行うためのスクリプト。
- **dev**: 開発環境でプロジェクトを実行するためのスクリプト。

#### 読んで頂き、ありがとうございました。


アプリケーション開発に集中するための方法を模索した
本記事はQmonus Value Streamの投稿キャンペーン記事です。