Reactのpackage.jsonとは?初心者が知るべき基本項目

Reactプロジェクトのpackage.jsonファイルの基本を解説。dependencies、scripts、devDependenciesなど重要な項目を実例とともに詳しく説明します。

Learning Next 運営
52 分で読めます

みなさん、こんなことありませんか?

「Reactプロジェクトを始めたけど、package.jsonって何?」 「dependenciesとdevDependenciesの違いがわからない」 「scriptsセクションの使い方がよくわからない」

Reactプロジェクトを始めたとき、package.jsonファイルを見て困ったことがある方も多いでしょう。 このファイルには、なにやらたくさんの設定が書かれていて、何から理解すればいいのか迷ってしまいますよね。

でも大丈夫です! この記事では、Reactプロジェクトにおけるpackage.jsonファイルの基本について詳しく解説します。

ファイルの役割から各項目の意味、実際の設定例まで、React初心者が知っておくべき内容を実際のコード例とともに学んでいきましょう。 読み終わる頃には、package.jsonが怖くなくなるはずです!

package.jsonって何?

package.jsonは、Node.jsプロジェクトの設定ファイルです。 Reactアプリケーションも内部的にNode.jsを使用しているため、このファイルが必要になります。

package.jsonの基本的な役割

{
  "name": "my-react-app",
  "version": "1.0.0",
  "description": "私の最初のReactアプリケーション",
  "main": "index.js",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^13.5.0"
  }
}

このファイルの仕組みを説明しますね。

nameは、プロジェクトの名前です。 versionは、現在のバージョンを表しています。

scriptsには、実行できるコマンドが定義されています。 例えば、npm startを実行すると、react-scripts startが実行されます。

dependenciesには、アプリの実行に必要なライブラリが書かれています。 devDependenciesには、開発時だけ必要なツールが書かれています。

package.jsonが管理する主な情報

package.jsonファイルでは、以下の情報を管理します:

  1. プロジェクトの基本情報(名前、バージョン、説明)
  2. 依存関係(dependencies、devDependencies)
  3. 実行可能なコマンド(scripts)
  4. プロジェクトの設定(browser、homepage など)
  5. 作者情報(author、license)

これらの情報により、プロジェクトの管理と開発が効率的になります。

Create React Appで作成されるpackage.json

Create React Appでプロジェクトを作成すると、自動的にpackage.jsonが生成されます。

npx create-react-app my-app
cd my-app

生成されるpackage.jsonの例を見てみましょう。

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Create React Appが自動的に設定してくれるので、最初は何も考えなくても動きます。 でも、中身を理解しておくと、後で役に立ちますよ。

基本情報の項目

package.jsonの基本的な項目について詳しく見ていきましょう。

プロジェクト名とバージョン

{
  "name": "my-react-blog",
  "version": "1.2.3",
  "description": "個人ブログのReactアプリケーション",
  "private": true
}

各項目の説明をしますね。

nameは、プロジェクトの名前です。 npmパッケージ名としても使用されるので、重複しない名前にします。

versionは、プロジェクトのバージョンです。 1.2.3のような形式で書きます。

descriptionは、プロジェクトの説明です。 何を作っているかを簡潔に書きましょう。

privatetrueにすると、npmに公開されません。 通常のアプリケーションでは、trueに設定しておきます。

セマンティックバージョニングの理解

{
  "version": "1.2.3"
}

バージョン番号の意味を説明しますね。

1.2.3
│ │ └── パッチバージョン(バグ修正)
│ └──── マイナーバージョン(新機能追加、後方互換性あり)
└────── メジャーバージョン(大きな変更、後方互換性なし)

1.2.3から1.2.4へのアップデートは、バグ修正です。 1.2.3から1.3.0へのアップデートは、新機能の追加です。 1.2.3から2.0.0へのアップデートは、大きな変更です。

この仕組みを理解しておくと、ライブラリの更新時に安全性を判断できます。

作者情報とライセンス

{
  "author": {
    "name": "田中太郎",
    "email": "tanaka@example.com",
    "url": "https://tanaka-portfolio.com"
  },
  "license": "MIT",
  "keywords": [
    "react",
    "blog",
    "javascript",
    "frontend"
  ],
  "homepage": "https://my-react-blog.com",
  "repository": {
    "type": "git",
    "url": "https://github.com/tanaka/my-react-blog.git"
  }
}

これらの項目は、プロジェクトの詳細情報です。

authorには、作者の情報を書きます。 licenseには、ライセンスの種類を書きます。MITライセンスがよく使われます。

keywordsには、プロジェクトに関連するキーワードを書きます。 検索しやすくなりますね。

homepagerepositoryには、ウェブサイトとソースコードの場所を書きます。

エントリーポイントの設定

{
  "main": "index.js",
  "browser": "src/index.js"
}

項目の意味を説明しますね。

mainは、Node.js環境でのエントリーポイントです。 browserは、ブラウザ環境でのエントリーポイントです。

Reactアプリケーションでは、通常src/index.jsがエントリーポイントになります。 ここから、アプリケーション全体が始まるんです。

scriptsセクションの使い方

scriptsセクションでは、プロジェクトで実行可能なコマンドを定義します。

標準的なReactのscripts

{
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
}

各コマンドの使い方を説明しますね。

# 開発サーバーを起動
npm start
# または
npm run start

# 本番用ビルドを作成
npm run build

# テストを実行
npm test
# または
npm run test

# Create React Appの設定を取り出す(非可逆)
npm run eject

npm startで開発サーバーが起動します。 ブラウザでhttp://localhost:3000にアクセスすると、アプリが表示されます。

npm run buildで、本番用のファイルが作成されます。 buildフォルダに、最適化されたファイルが生成されます。

npm testで、テストが実行されます。 コードが正しく動いているかチェックできます。

カスタムスクリプトの追加

{
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    
    "dev": "npm start",
    "build:prod": "npm run build && serve -s build",
    "test:watch": "npm test -- --watchAll",
    "test:coverage": "npm test -- --coverage --watchAll=false",
    "lint": "eslint src/**/*.{js,jsx}",
    "lint:fix": "eslint src/**/*.{js,jsx} --fix",
    "format": "prettier --write src/**/*.{js,jsx,css,md}",
    "clean": "rm -rf build node_modules",
    "reinstall": "npm run clean && npm install"
  }
}

カスタムスクリプトの使い方を説明しますね。

devは、開発サーバー起動の短縮版です。 build:prodは、ビルド後にローカルサーバーで確認できます。

test:coverageは、テストカバレッジを確認できます。 どのくらいコードがテストされているかが分かります。

lintlint:fixは、コードの品質をチェック・修正します。 formatは、コードの整形をします。

cleanreinstallは、環境をリセットしたい時に使います。 問題が起きた時の最終手段ですね。

環境変数を使ったスクリプト

{
  "scripts": {
    "start": "react-scripts start",
    "start:prod": "REACT_APP_ENV=production npm start",
    "build": "react-scripts build",
    "build:staging": "REACT_APP_ENV=staging npm run build",
    "build:analyze": "npm run build && npx webpack-bundle-analyzer build/static/js/*.js"
  }
}

環境変数を使うことで、異なる設定で実行できます。

REACT_APP_ENV=productionで、本番環境の設定で開発サーバーを起動できます。 REACT_APP_ENV=stagingで、ステージング環境用のビルドができます。

build:analyzeは、ビルドされたファイルの大きさを分析します。 どのライブラリが重いか確認できて便利ですよ。

複数コマンドの組み合わせ

{
  "scripts": {
    "prestart": "npm run lint",
    "start": "react-scripts start",
    "poststart": "echo 'サーバーが起動しました'",
    
    "prebuild": "npm run test:coverage",
    "build": "react-scripts build",
    "postbuild": "npm run build:analyze",
    
    "deploy": "npm run build && npm run deploy:s3",
    "deploy:s3": "aws s3 sync build/ s3://my-bucket --delete",
    
    "full-test": "npm run lint && npm run test:coverage && npm run build"
  }
}

複数のコマンドを組み合わせることで、自動化できます。

prepostを付けることで、前後の処理を自動実行できます。 npm startを実行すると、自動的にprestartstartpoststartの順で実行されます。

&&でコマンドを繋げることで、順番に実行できます。 前のコマンドが成功した場合のみ、次のコマンドが実行されます。

Windows対応のスクリプト

{
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "clean": "rimraf build node_modules",
    "clean:win": "if exist build rmdir /s /q build && if exist node_modules rmdir /s /q node_modules",
    "env:set": "cross-env REACT_APP_ENV=production npm start"
  },
  "devDependencies": {
    "cross-env": "^7.0.3",
    "rimraf": "^3.0.2"
  }
}

WindowsとMac/Linuxでは、コマンドが異なることがあります。

rimrafは、クロスプラットフォームで削除できるツールです。 cross-envは、環境変数をクロスプラットフォームで設定できます。

これらのツールを使うことで、どのOSでも同じように動くスクリプトが書けます。

dependenciesとdevDependenciesの違い

依存関係の管理は、package.jsonの重要な役割の一つです。

dependenciesの役割

{
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "axios": "^0.27.2",
    "styled-components": "^5.3.5",
    "lodash": "^4.17.21"
  }
}

dependenciesに含めるものを説明しますね。

  • 本番環境で必要なライブラリ
  • アプリケーションの実行に必須のパッケージ
  • ユーザーに提供する機能に直接関わるライブラリ

reactreact-domは、Reactアプリの実行に必須です。 react-router-domは、ページ遷移機能で使います。 axiosは、API通信で使います。

これらはすべて、アプリが動くために必要なライブラリです。

devDependenciesの役割

{
  "devDependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^13.5.0",
    "eslint": "^8.19.0",
    "prettier": "^2.7.1",
    "@types/react": "^18.0.15",
    "@types/react-dom": "^18.0.6",
    "webpack-bundle-analyzer": "^4.5.0"
  }
}

devDependenciesに含めるものを説明しますね。

  • 開発時のみ必要なツール
  • テスト関連のライブラリ
  • コード品質を保つためのツール(ESLint、Prettier)
  • 型定義ファイル(TypeScript使用時)
  • ビルドツールや開発サーバー関連

これらは、開発中だけ使うツールです。 本番環境では不要なので、devDependenciesに分類します。

具体的な分類例

{
  "dependencies": {
    // UI関連
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    
    // スタイリング
    "styled-components": "^5.3.5",
    "material-ui": "^4.12.4",
    
    // データ取得
    "axios": "^0.27.2",
    "swr": "^1.3.0",
    
    // ユーティリティ
    "lodash": "^4.17.21",
    "date-fns": "^2.28.0",
    
    // 状態管理
    "redux": "^4.2.0",
    "react-redux": "^8.0.2"
  },
  "devDependencies": {
    // ビルドツール
    "react-scripts": "5.0.1",
    "vite": "^3.0.0",
    
    // テスト
    "@testing-library/react": "^13.3.0",
    "@testing-library/jest-dom": "^5.16.4",
    "jest": "^28.1.3",
    
    // コード品質
    "eslint": "^8.19.0",
    "prettier": "^2.7.1",
    "@typescript-eslint/eslint-plugin": "^5.30.7",
    
    // 型定義
    "@types/react": "^18.0.15",
    "@types/lodash": "^4.14.182",
    
    // 開発ツール
    "webpack-bundle-analyzer": "^4.5.0",
    "source-map-explorer": "^2.5.2"
  }
}

この分類を見ると、違いがよく分かりますね。

dependencies側は、ユーザーが使う機能に関連するライブラリです。 devDependencies側は、開発者が使うツールです。

パッケージのインストール方法

# 本番依存関係としてインストール
npm install react react-dom
npm install --save react-router-dom

# 開発依存関係としてインストール
npm install --save-dev @testing-library/react
npm install -D eslint prettier

# 既存パッケージの更新
npm update react react-dom

# 特定のバージョンをインストール
npm install react@17.0.2

# パッケージの削除
npm uninstall styled-components

インストール方法によって、どちらに分類されるかが決まります。

npm installだけだと、dependenciesに追加されます。 --save-dev-Dを付けると、devDependenciesに追加されます。

間違えて分類した場合は、package.jsonを直接編集して修正できます。

バージョン指定の理解

package.jsonでのバージョン指定方法について詳しく見ていきましょう。

基本的なバージョン指定

{
  "dependencies": {
    "react": "18.2.0",           // 完全一致
    "react-dom": "^18.2.0",      // キャレット範囲
    "axios": "~0.27.2",          // チルダ範囲
    "lodash": "*",               // 任意のバージョン
    "moment": "latest"           // 最新バージョン
  }
}

それぞれの記号の意味を説明しますね。

18.2.0は、完全一致です。 このバージョンでしか動かない場合に使います。

^18.2.0は、キャレット範囲です。 マイナーバージョンまでの更新を許可します。

~0.27.2は、チルダ範囲です。 パッチバージョンのみの更新を許可します。

バージョン指定記号の意味

{
  "dependencies": {
    // 完全一致(推奨されない)
    "package-a": "1.2.3",
    
    // キャレット(^): マイナーバージョンまでの更新を許可
    "package-b": "^1.2.3",  // 1.2.3 <= version < 2.0.0
    
    // チルダ(~): パッチバージョンのみの更新を許可
    "package-c": "~1.2.3",  // 1.2.3 <= version < 1.3.0
    
    // 範囲指定
    "package-d": ">=1.2.3 <2.0.0",
    "package-e": "1.2.x",   // 1.2.0 <= version < 1.3.0
    
    // GitHubリポジトリから
    "package-f": "github:user/repo#v1.2.3",
    
    // ローカルパッケージ
    "package-g": "file:../my-local-package"
  }
}

キャレット(^)が最もよく使われます。 新機能は使えるけど、破壊的変更は避けられるからです。

チルダ(~)は、より慎重なアップデートです。 バグ修正だけを受け入れたい場合に使います。

実際のReactプロジェクトでの例

{
  "dependencies": {
    // Reactコア(安定版を使用)
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    
    // ルーティング(マイナーアップデートOK)
    "react-router-dom": "^6.3.0",
    
    // UIライブラリ(慎重にアップデート)
    "material-ui": "~4.12.4",
    
    // ユーティリティ(積極的にアップデート)
    "lodash": "^4.17.21",
    
    // API関連(セキュリティ重要)
    "axios": "^0.27.2"
  },
  "devDependencies": {
    // ビルドツール(Create React App管理)
    "react-scripts": "5.0.1",
    
    // テストツール(安定バージョン)
    "@testing-library/react": "^13.3.0",
    
    // 開発ツール(最新機能使用)
    "eslint": "^8.19.0",
    "prettier": "^2.7.1"
  }
}

ライブラリの重要度に応じて、バージョン指定を変えています。

Reactのコア部分は安定版を使います。 開発ツールは最新機能を使いたいので、キャレット指定にします。

UIライブラリは破壊的変更が多いので、チルダ指定で慎重にします。

package-lock.jsonとの関係

// package.json
{
  "dependencies": {
    "react": "^18.2.0"
  }
}

// package-lock.json(自動生成)
{
  "name": "my-app",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "node_modules/react": {
      "version": "18.2.0",
      "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
      "integrity": "sha512-...",
      "dependencies": {
        "loose-envify": "^1.1.0"
      }
    }
  }
}

package-lock.jsonの役割を説明しますね。

  • 正確なバージョンを記録
  • 依存関係の依存関係も固定
  • チーム全体で同じバージョンを保証
  • 本番環境での一貫性を確保

package.jsonは「範囲」を指定し、package-lock.jsonは「具体的なバージョン」を記録します。 これで、誰が実行しても同じ環境になります。

その他の重要な設定項目

package.jsonには、他にも重要な設定項目があります。

browserslistの設定

{
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

browserslistの意味を説明しますね。

  • サポート対象ブラウザの指定
  • Babelの変換ルールに影響
  • Autoprefixerの動作に影響
  • 本番環境と開発環境で分けて設定可能

>0.2%は、市場シェア0.2%以上のブラウザです。 not deadは、サポートが終了していないブラウザです。

開発環境では最新ブラウザのみ、本番環境では幅広いブラウザをサポートしています。

ESLint設定

{
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "rules": {
      "no-console": "warn",
      "no-unused-vars": "error",
      "react-hooks/exhaustive-deps": "warn"
    },
    "overrides": [
      {
        "files": ["src/**/*.test.js"],
        "rules": {
          "no-console": "off"
        }
      }
    ]
  }
}

ESLintは、コードの品質をチェックするツールです。

extendsで、基本的なルールセットを継承します。 rulesで、個別のルールをカスタマイズできます。

overridesで、特定のファイルだけ異なるルールを適用できます。 テストファイルではconsole.logを許可するなどですね。

Prettier設定

{
  "prettier": {
    "semi": true,
    "trailingComma": "es5",
    "singleQuote": true,
    "printWidth": 80,
    "tabWidth": 2
  }
}

Prettierは、コードを自動整形するツールです。

semiは、セミコロンを付けるかどうかです。 singleQuoteは、シングルクォートを使うかどうかです。

チーム全体で同じ設定にすることで、コードの見た目が統一されます。

homepage設定(デプロイ用)

{
  "name": "my-react-app",
  "homepage": "https://username.github.io/my-react-app",
  "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
  },
  "devDependencies": {
    "gh-pages": "^4.0.0"
  }
}

homepageを設定することで、GitHub Pagesなどにデプロイできます。

npm run deployを実行すると、自動的にビルドしてデプロイしてくれます。 とても便利ですね。

proxy設定(開発時のAPI連携)

{
  "name": "my-react-app",
  "proxy": "http://localhost:3001",
  "scripts": {
    "start": "react-scripts start"
  }
}

この設定により、開発時に/api/*のリクエストがhttp://localhost:3001にプロキシされます。

バックエンドのAPIサーバーと連携する時に便利です。 CORSエラーを回避できます。

実践的なpackage.json例

実際のプロジェクトで使用される、より複雑なpackage.jsonの例を見てみましょう。

中規模Reactアプリケーションの例

{
  "name": "react-todo-app",
  "version": "2.1.0",
  "description": "高機能なTodoアプリケーション",
  "private": true,
  "homepage": "https://my-todo-app.com",
  "author": {
    "name": "田中太郎",
    "email": "tanaka@example.com"
  },
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/tanaka/react-todo-app.git"
  },
  "keywords": [
    "react",
    "todo",
    "productivity",
    "javascript",
    "typescript"
  ],
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "test:coverage": "npm test -- --coverage --watchAll=false",
    "test:ci": "CI=true npm test -- --coverage --watchAll=false",
    "eject": "react-scripts eject",
    
    "lint": "eslint src/**/*.{js,jsx,ts,tsx}",
    "lint:fix": "eslint src/**/*.{js,jsx,ts,tsx} --fix",
    "format": "prettier --write src/**/*.{js,jsx,ts,tsx,css,md}",
    "type-check": "tsc --noEmit",
    
    "build:analyze": "npm run build && npx webpack-bundle-analyzer build/static/js/*.js",
    "build:staging": "REACT_APP_ENV=staging npm run build",
    "build:production": "REACT_APP_ENV=production npm run build",
    
    "predeploy": "npm run build:production",
    "deploy": "gh-pages -d build",
    "deploy:staging": "npm run build:staging && aws s3 sync build/ s3://my-app-staging",
    "deploy:production": "npm run build:production && aws s3 sync build/ s3://my-app-production",
    
    "clean": "rimraf build coverage",
    "reinstall": "rimraf node_modules package-lock.json && npm install",
    "prepare": "husky install"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.1",
    
    "@reduxjs/toolkit": "^1.8.3",
    "react-redux": "^8.0.2",
    "redux-persist": "^6.0.0",
    
    "@mui/material": "^5.8.7",
    "@mui/icons-material": "^5.8.4",
    "@emotion/react": "^11.9.3",
    "@emotion/styled": "^11.9.3",
    
    "axios": "^0.27.2",
    "react-query": "^3.39.2",
    
    "date-fns": "^2.28.0",
    "lodash": "^4.17.21",
    "uuid": "^8.3.2",
    
    "react-hook-form": "^7.33.1",
    "yup": "^0.32.11",
    "@hookform/resolvers": "^2.9.1",
    
    "react-toastify": "^9.0.5",
    "react-helmet-async": "^1.3.0"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^13.5.0",
    "@testing-library/react-hooks": "^8.0.1",
    
    "@types/react": "^18.0.15",
    "@types/react-dom": "^18.0.6",
    "@types/lodash": "^4.14.182",
    "@types/uuid": "^8.3.4",
    "@types/jest": "^28.1.6",
    "typescript": "^4.7.4",
    
    "eslint": "^8.19.0",
    "@typescript-eslint/eslint-plugin": "^5.30.7",
    "@typescript-eslint/parser": "^5.30.7",
    "eslint-plugin-react": "^7.30.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-jsx-a11y": "^6.6.0",
    "eslint-plugin-import": "^2.26.0",
    
    "prettier": "^2.7.1",
    "husky": "^8.0.1",
    "lint-staged": "^13.0.3",
    
    "webpack-bundle-analyzer": "^4.5.0",
    "source-map-explorer": "^2.5.2",
    
    "gh-pages": "^4.0.0",
    "rimraf": "^3.0.2",
    "cross-env": "^7.0.3"
  }
}

この例では、実際のプロジェクトで使われる様々な機能が含まれています。

状態管理にRedux、UIにMaterial-UI、フォームにreact-hook-formを使っています。 TypeScript、ESLint、Prettierで開発環境を整えています。

テストやデプロイ、分析など、開発に必要な機能が一通り揃っています。

TypeScript + Viteを使用した例

{
  "name": "react-vite-typescript-app",
  "version": "1.0.0",
  "type": "module",
  "description": "Vite + TypeScript + Reactアプリケーション",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest --coverage",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "format": "prettier --write src/**/*.{ts,tsx,css}"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.37",
    "@types/react-dom": "^18.0.11",
    "@typescript-eslint/eslint-plugin": "^5.59.0",
    "@typescript-eslint/parser": "^5.59.0",
    "@vitejs/plugin-react": "^4.0.0",
    "eslint": "^8.38.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.3.4",
    "typescript": "^5.0.2",
    "vite": "^4.3.9",
    "vitest": "^0.32.0",
    "@vitest/ui": "^0.32.0",
    "prettier": "^2.8.8"
  }
}

ViteはCreate React Appより高速なビルドツールです。 TypeScriptと組み合わせることで、より安全な開発ができます。

"type": "module"により、ES Modulesを使用します。 モダンなJavaScript環境での開発ですね。

package.jsonの管理のベストプラクティス

効率的なpackage.json管理のためのベストプラクティスを紹介します。

1. 依存関係の定期的な更新

# 古いパッケージを確認
npm outdated

# 安全な更新(semver範囲内)
npm update

# 特定パッケージの更新
npm install react@latest

# すべてを最新版に更新(注意が必要)
npx npm-check-updates -u
npm install

定期的な更新で、セキュリティと機能を最新に保てます。

npm outdatedで、更新可能なパッケージを確認できます。 赤色で表示されるものは、大きなバージョンアップが必要です。

npm updateは、semver範囲内での安全な更新です。 破壊的変更は含まれないので、安心して実行できます。

2. セキュリティ監査

# セキュリティ脆弱性の確認
npm audit

# 自動修正(可能な場合)
npm audit fix

# 強制修正(注意が必要)
npm audit fix --force

セキュリティ脆弱性を定期的にチェックしましょう。

npm auditで、既知の脆弱性を確認できます。 npm audit fixで、自動修正できる場合があります。

ただし、--forceは破壊的変更を含む可能性があるので注意が必要です。

3. 不要なパッケージの削除

# 未使用パッケージの検出
npx depcheck

# 特定パッケージの削除
npm uninstall package-name

# devDependenciesから削除
npm uninstall --save-dev package-name

不要なパッケージを削除することで、プロジェクトを軽量化できます。

depcheckは、使われていないパッケージを検出してくれます。 ただし、完璧ではないので、削除前に確認しましょう。

4. パッケージサイズの監視

{
  "scripts": {
    "analyze": "npm run build && npx webpack-bundle-analyzer build/static/js/*.js",
    "size-check": "npm run build && npx bundlesize"
  },
  "bundlesize": [
    {
      "path": "./build/static/js/*.js",
      "maxSize": "300 kB"
    },
    {
      "path": "./build/static/css/*.css",
      "maxSize": "50 kB"
    }
  ]
}

パッケージサイズを監視することで、パフォーマンスを維持できます。

webpack-bundle-analyzerで、どのライブラリが重いか確認できます。 bundlesizeで、サイズ制限を自動チェックできます。

5. 環境別の設定管理

{
  "scripts": {
    "start": "react-scripts start",
    "start:prod": "REACT_APP_ENV=production npm start",
    "build:dev": "REACT_APP_ENV=development npm run build",
    "build:staging": "REACT_APP_ENV=staging npm run build",
    "build:prod": "REACT_APP_ENV=production npm run build"
  },
  "config": {
    "development": {
      "api_url": "http://localhost:3001"
    },
    "staging": {
      "api_url": "https://api-staging.example.com"
    },
    "production": {
      "api_url": "https://api.example.com"
    }
  }
}

環境別の設定を管理することで、デプロイが簡単になります。

開発・ステージング・本番環境で、異なる設定を使えます。 APIのURLやデバッグフラグなどを切り替えられます。

6. チーム開発での統一

{
  "engines": {
    "node": ">=16.0.0",
    "npm": ">=8.0.0"
  },
  "volta": {
    "node": "18.16.0",
    "npm": "9.5.1"
  }
}

チーム全体で同じ環境を使うことで、トラブルを減らせます。

enginesで、最低限必要なバージョンを指定できます。 voltaで、推奨バージョンを固定できます。

これで、「私の環境では動くのに...」という問題を回避できます。

よくあるトラブルと解決方法

package.jsonに関連するよくある問題とその解決方法を紹介します。

1. バージョン競合の問題

# エラー例
npm ERR! peer dep missing: react@^18.0.0, required by @mui/material@5.8.7

# 解決方法1: 正しいバージョンをインストール
npm install react@^18.0.0

# 解決方法2: peer dependenciesを無視(推奨されない)
npm install --legacy-peer-deps

peer dependenciesの不一致でエラーが起きることがあります。

基本的には、要求されているバージョンをインストールしましょう。 --legacy-peer-depsは、一時的な回避策として使います。

2. package-lock.jsonの問題

# package-lock.jsonとpackage.jsonの不整合
npm ERR! Cannot resolve dependency tree

# 解決方法: 再インストール
rm package-lock.json
rm -rf node_modules
npm install

package-lock.jsonが壊れることがあります。

その場合は、package-lock.jsonとnode_modulesを削除して、再インストールしましょう。 時間はかかりますが、確実に修復できます。

3. scriptsが動かない問題

{
  "scripts": {
    // Windows環境での問題
    "clean": "rm -rf build",  // Windowsで動かない
    
    // 解決方法
    "clean": "rimraf build",
    "clean:win": "if exist build rmdir /s /q build"
  },
  "devDependencies": {
    "rimraf": "^3.0.2"
  }
}

WindowsとMac/Linuxでコマンドが異なることがあります。

クロスプラットフォーム対応のツールを使いましょう。 rimrafcross-envなどが便利です。

4. 環境変数の問題

{
  "scripts": {
    // 環境変数が設定されない
    "start:prod": "NODE_ENV=production npm start",  // Windowsで動かない
    
    // 解決方法
    "start:prod": "cross-env NODE_ENV=production npm start"
  },
  "devDependencies": {
    "cross-env": "^7.0.3"
  }
}

環境変数の設定方法も、OSによって異なります。

cross-envを使うことで、どのOSでも同じように設定できます。 チーム開発では必須のツールですね。

5. メモリ不足の問題

{
  "scripts": {
    // ビルド時のメモリ不足
    "build": "react-scripts build",
    
    // 解決方法: メモリ上限を増やす
    "build": "node --max_old_space_size=4096 node_modules/.bin/react-scripts build"
  }
}

大きなプロジェクトでは、ビルド時にメモリ不足になることがあります。

--max_old_space_sizeで、Node.jsのメモリ上限を増やせます。 4096MB(4GB)程度に設定すると、大抵の問題は解決します。

6. プロキシ設定の問題

{
  // 単純なプロキシ(限定的)
  "proxy": "http://localhost:3001",
  
  // 複雑なプロキシ設定が必要な場合
  // src/setupProxy.js ファイルを作成
}
// src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:3001',
      changeOrigin: true,
    })
  );
  
  app.use(
    '/auth',
    createProxyMiddleware({
      target: 'http://localhost:3002',
      changeOrigin: true,
    })
  );
};

複雑なプロキシ設定が必要な場合は、setupProxy.jsファイルを作成します。

複数のバックエンドサーバーにプロキシしたり、パスを変更したりできます。 より柔軟な設定が可能になります。

まとめ:package.jsonをマスターしよう

Reactプロジェクトにおけるpackage.jsonファイルの基本について詳しく解説しました。

覚えておきたいポイント

  1. 基本情報 - プロジェクト名、バージョン、説明などの基本設定
  2. scripts - 開発、ビルド、テストなどのコマンド定義
  3. 依存関係 - dependencies(本番用)とdevDependencies(開発用)の違い
  4. バージョン管理 - セマンティックバージョニングと適切な指定方法

これらを理解することで、Reactプロジェクトの管理が格段に楽になります。

実践的なアドバイス

dependenciesとdevDependenciesを正しく使い分ける 本番環境で必要かどうかで判断しましょう。

バージョン指定記号(^、~)の意味を理解する 適切なバージョン範囲を指定することで、安全性と利便性を両立できます。

package-lock.jsonの重要性を理解する チーム全体で同じ環境を保つために必要です。

定期的な依存関係の更新とセキュリティ監査を行う セキュリティと機能を最新に保てます。

今日から始めよう

package.jsonを正しく理解し管理することで、Reactプロジェクトの開発効率と品質を大幅に向上させることができます。 チーム開発においても、統一された設定により一貫した開発環境を構築できます。

最初は複雑に見えるかもしれませんが、一つずつ理解していけば大丈夫です。 ぜひ実際のプロジェクトでこれらの知識を活用してみてください。

きっと、「package.jsonってこんなに便利だったんだ!」と実感できるはずです。

関連記事