ergebnis/composer-normalize
Composer plugin that automatically normalizes composer.json: consistent key ordering, formatting, and whitespace to reduce diffs and style debates. Install as a dev dependency, allow the plugin, and run it in CI to keep composer.json tidy and predictable.
Installation:
composer require --dev ergebnis/composer-normalize
composer config allow-plugins.ergebnis/composer-normalize true
First Use Case: Run in your Laravel project root:
composer normalize
composer.json in-place, ensuring consistent formatting and sorting of keys/values.Where to Look First:
composer.json for existing extra.composer-normalize settings (if any).Pre-Commit Hook:
Integrate with Laravel’s Git hooks (e.g., via laravel/git-hooks) to auto-normalize composer.json before commits:
composer normalize --dry-run # Validate without modifying files
--dry-run in CI/CD pipelines to enforce consistency without side effects.Team Onboarding:
composer normalize to your contributing.md as a required step for PRs.- name: Normalize composer.json
run: composer normalize --dry-run
Custom Formatting:
Configure indentation in composer.json:
{
"extra": {
"composer-normalize": {
"indent-size": 4,
"indent-style": "space"
}
}
}
Multi-Package Projects: Normalize specific files in monorepos:
composer normalize packages/package-a/composer.json
Laravel Mix/Webpack:
Add a script to package.json to normalize during build:
{
"scripts": {
"build": "npm run dev && composer normalize"
}
}
PHPStan/PSR-12:
Combine with tools like php-cs-fixer for a full formatting pipeline:
composer normalize && php-cs-fixer fix
Custom Rules:
Extend the normalizer by subclassing ComposerJsonNormalizer (advanced use case).
Lock File Conflicts:
composer normalize without --no-update-lock may trigger unnecessary composer.lock updates.--no-update-lock in CI to avoid flaky builds.Merge Conflicts:
"require" → "require-dev"). Conflicts may arise if multiple contributors modify composer.json simultaneously.--diff to preview changes.Custom Config Overrides:
--indent-size) are ignored if extra.composer-normalize is set.extra config if CLI behavior is desired.Performance:
composer.json files (e.g., with hundreds of dependencies) may take a few seconds.composer normalize --dry-run and fail fast.Unexpected Changes:
Use --diff to compare before/after:
composer normalize --diff
Plugin Not Running: Verify the plugin is enabled:
composer config --list | grep allow-plugins
allow-plugins.ergebnis/composer-normalize is true.Phar Issues:
If using the .phar version, ensure it’s executable (chmod +x) and PHP’s open_basedir restrictions aren’t blocking it.
Custom Normalization: Override the default normalizer by creating a custom plugin:
use Ergebnis\Json\Normalizer\Vendor\Composer\ComposerJsonNormalizer;
class CustomNormalizer extends ComposerJsonNormalizer {
protected function normalizeExtra(array $extra): array {
// Custom logic for the "extra" section
return parent::normalizeExtra($extra);
}
}
Post-Normalization Hooks:
Use Laravel’s composer.post-autoload-dump script to run additional tasks after normalization:
{
"scripts": {
"post-autoload-dump": [
"@composer normalize",
"php artisan optimize:clear"
]
}
}
Git Attributes:
Add .gitattributes to ignore whitespace changes (if using custom indentation):
composer.json diff=composer-normalize
Atomic Commits:
Normalize composer.json in a separate commit from functional changes to avoid noise in PRs.
Monorepo Projects:
Use find to normalize all composer.json files recursively:
find . -name composer.json -exec composer normalize {} \;
Backup First:
Always commit or stash changes before running composer normalize in production-like environments.
CI Caching:
Cache composer.lock and composer.json in CI to avoid redundant normalization:
- uses: actions/cache@v3
with:
path: |
composer.lock
composer.json
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
How can I help you explore Laravel packages today?