- package.jsonとcomposer.jsonは似ているが「目的」が違う
- まず確認:両方とも依存関係を管理するファイル
- 最大の違い:JavaScriptは実行環境、PHPは配布コード
- autoloadが意味するもの
- devDependencies と require-dev の違い
- lockファイルの扱いが文化を表す
- よくある事故:npm感覚でcomposer updateする
- まとめ:同じJSONでも役割は別物
package.jsonとcomposer.jsonは似ているが「目的」が違う
Node.jsのpackage.jsonとPHPのcomposer.json。
どちらも依存関係を書くJSONファイルで、見た目もかなり似ています。
しかし、実際に運用すると印象は大きく変わります。
結論から言うと、package.jsonは「アプリケーションの設定ファイル」、composer.jsonは「コード構造の契約書」に近いです。
同じパッケージ管理でも、想定しているプロジェクトの形が違うため、使い方を間違えると違和感や事故が起きます。
まず確認:両方とも依存関係を管理するファイル
それぞれの基本的な役割は共通しています。
依存関係の宣言
Node.jsではこう書きます。
{ "dependencies": { "express": "^4.18.0" } }
Composerではこうです。
{ "require": { "monolog/monolog": "^3.0" } }
どちらも「このライブラリが必要です」という宣言です。
インストールも似ています。
npm install
composer install
ここまではほぼ同じです。
しかし、ここから思想の差が出始めます。
最大の違い:JavaScriptは実行環境、PHPは配布コード
Node.jsはアプリケーションを組み立てる文化
Node.jsのpackage.jsonは、アプリケーションの中心にあります。
理由はシンプルで、Node.jsは「実行環境そのもの」だからです。
package.jsonには依存関係以外にも次が入ります。
- 実行スクリプト
- ビルド
- テスト
- Lint
- フォーマット
{ "scripts": { "dev": "node server.js", "build": "webpack" } }
つまりpackage.jsonは、アプリの操作盤です。
開発者はnpmコマンドを入口として作業します。
PHPは配布コードとして動く文化
一方、PHPのcomposer.jsonは違います。
PHPはサーバーに配置された時点で実行されます。
Webサーバーが入口です。
- Apache
- Nginx
- FPM
そのためcomposer.jsonに書かれる内容は、実行ではなく「読み込み規約」です。
{ "autoload": { "psr-4": { "App\\": "src/" } } }
つまりcomposer.jsonの中心はスクリプトではなくautoloadです。
autoloadが意味するもの
ここが最も重要な思想差です。
Node.jsでは必要なファイルを明示的に読み込みます。
const user = require('./User');
または
import user from './User.js';
一方、Composerは明示的に読み込みません。
require __DIR__.'/vendor/autoload.php';
これだけです。
以降、クラスは自動的に解決されます。
これは単なる便利機能ではありません。
コードの配置ルールを強制する仕組みです。
PSR-4という規約に従わないと、そもそもクラスが読まれません。
つまりcomposer.jsonは依存関係ファイルであると同時に、設計規約でもあります。
devDependencies と require-dev の違い
似ている項目としてよく比較されるのがここです。
Node.js:
"devDependencies": { "jest": "^29.0.0" }
Composer:
"require-dev": { "phpunit/phpunit": "^10.0" }
一見同じですが、運用の意味は少し違います。
Node.jsではビルドツールが多いため、devDependenciesは「開発ツール置き場」です。
本番ではビルド済み成果物を使うことが多く、node_modules自体をデプロイしないケースもあります。
一方、PHPはビルド成果物を配布しません。
本番もソースコードです。
そのためComposerでは「本番に入るか」が重要になります。
require-devを誤って本番に含めると、メモリ増加やパフォーマンス低下が起きる場合があります。
lockファイルの扱いが文化を表す
Node.js: package-lock.json
PHP: composer.lock
両方とも存在しますが、重要度の扱いが違います。
Node.jsでは削除しても比較的復旧できます。
しかしComposerでは影響が大きいです。
理由は依存解決の強さです。
Composerは間接依存まで厳密に固定します。
つまりcomposer.lockはキャッシュではありません。
> 「このプロジェクトが成立する唯一の依存状態」
です。
Git管理しないと、同じコードでも動作が変わります。
よくある事故:npm感覚でcomposer updateする
Node.js経験者がやりがちな失敗があります。
composer update
気軽に実行すると、次が起きます。
- 間接依存が更新
- フレームワーク内部が変わる
- 既存コードが動かない
npm updateより影響が広いのが特徴です。
Composerは「プロジェクトの再解決」に近い動きをします。
まとめ:同じJSONでも役割は別物
package.jsonとcomposer.jsonは、形式は似ています。
しかし役割はかなり違います。
- package.json:アプリケーション操作と開発フローの中心
- composer.json:コード構造と依存関係の契約
Node.jsは「実行するための設定」、
PHPは「読み込ませるための規約」。
この違いを理解すると、なぜPHPではautoloadが重要視され、Node.jsではscriptsが中心になるのかが見えてきます。
同じパッケージ管理でも、ツールは言語文化を映します。
そしてcomposer.jsonは、PHPの「どう書くべきか」を定義するファイルでもあるのです。