Over deze pagina
In De basis van packageontwikkeling zagen we dat service providers en facades automatisch worden geregistreerd zodra je de sectieextra.laravel in composer.json opneemt. Deze pagina legt de achterkant daarvan uit: hoe de klasse Illuminate\Foundation\PackageManifest werkt, op broncodeniveau.
Deze pagina is een zusterpagina van De basis van packageontwikkeling. We raden je aan eerst het basisgebruik van automatische detectie te lezen.
Het totaalbeeld van automatische detectie
De PackageManifest-klasse
De kern van de automatische detectie is Illuminate\Foundation\PackageManifest. Hieronder staat de implementatie (samengevat) zoals in framework 13.x.
- Het manifest wordt na één keer inlezen in het geheugen gecachet (de property
$this->manifest). Ook als jeproviders()binnen één request meerdere keren aanroept, is er maar één keer bestands-I/O. build()wordt alleen uitgevoerd als het manifestbestand niet bestaat. In normaal gebruik wordt het dus niet elke keer opnieuw opgebouwd.- Het bestand zelf is een simpel PHP-bestand dat een array
returnt (bootstrap/cache/packages.php) — het snelst mogelijke formaat, dat je met alleen eenrequirekunt inladen.
Het buildproces van het manifest
Debuild()-methode is het deel dat daadwerkelijk de informatie uit composer.json samenvoegt.
composer.json wordt geparset, maar dat vendor/composer/installed.json wordt gelezen. Dit is het metadatabestand van alle geïnstalleerde packages dat Composer genereert bij composer install / composer update. Omdat de extra-secties uit de composer.json van elk package hier zijn samengebracht, leest Laravel alleen informatie die onder beheer van Composer staat.
installed.json staat normaal gesproken in .gitignore, dus bij de eerste setup (zonder vendor/) werkt de automatische detectie niet. Pas na afronding van composer install wordt de cache voor het eerst opgebouwd.De twee manieren om dont-discover te schrijven
dont-discover kun je zowel in de composer.json van het package als in die van de applicatie zetten, maar de betekenis verschilt.
composer.json aan de packagekant
composer.json aan de applicatiekant
build() bekijkt, wordt de $ignore-array opgebouwd door de configuration['dont-discover'] van elk package via array_merge te verzamelen. Dat betekent dat een package technisch gezien ook “de automatische detectie van zijn eigen dependencies kan uitschakelen” (bijvoorbeeld als je niet wilt dat de provider van een intern gebruikt subpackage dubbel wordt geregistreerd). In de praktijk gebruik je meestal de uitschakeling aan de applicatiekant.
* opgeven bij dont-discover
Als de array die packagesToIgnore() teruggeeft * bevat, wordt $ignoreAll = true en wordt de automatische detectie van alle packages volledig uitgeschakeld. Dit gebruik je als je de overhead van automatische detectie wilt vermijden in CI- of testomgevingen, of als je alles volledig handmatig wilt beheren via bootstrap/providers.php.
Wat er in het cachebestand staat
getCachedPackagesPath() geeft de waarde van de environment variable APP_PACKAGES_CACHE terug als die bestaat, en anders bootstrap/cache/packages.php.
returnt.
php artisan package:discover controleren “welke packages er zijn gedetecteerd”.
Wanneer de cache opnieuw wordt opgebouwd
Illuminate\Foundation\ComposerScripts haakt in op drie Composer-events, die allemaal dezelfde clearCompiled() aanroepen.
composer install, composer update of composer dump-autoload worden de configcache, servicecache en packagecache allemaal in één keer verwijderd. Bij de eerstvolgende start van Laravel draait PackageManifest::build() en wordt alles opnieuw opgebouwd vanuit de actuele staat van installed.json.
Dit is het standaardgedrag van een Laravel-project, geregistreerd in de scripts van composer.json.
composer.json van een Laravel-app (fragment)
Handmatig opnieuw opbouwen met php artisan package:discover
Als de cache verouderd is, of als je vendor/ rechtstreeks hebt gewijzigd zonder Composer te gebruiken, kun je met het package:discover-commando handmatig opnieuw opbouwen.
$manifest->build() aan en toont het resultaat; commandospecifieke logica is er nauwelijks. In situaties waarin Composer-events niet worden afgevuurd — bijvoorbeeld als je in een CI-pipeline composer install --no-scripts gebruikt — moet je dit commando expliciet aanroepen.
Aandachtspunten bij deployen
Bij een productiedeploy voer je meestalcomposer install --no-dev --optimize-autoloader uit, maar als je --no-scripts toevoegt, wordt de packagecache niet bijgewerkt. Het is veiliger om een expliciete herbouwstap in je deployscript op te nemen.
package:discover uit vóór config:cache. Als de configcache eerst wordt aangemaakt, kan later toegevoegde packageconfiguratie (zoals configuratie die via mergeConfigFrom wordt geregistreerd) niet meer worden meegenomen.
Samenvatting
- Automatische detectie werkt niet op basis van de statische inhoud van
composer.json, maar door het door Composer gegenereerdevendor/composer/installed.jsonte lezen. - Het resultaat wordt als een platte PHP-array gecachet in
bootstrap/cache/packages.phpen supersnel ingeladen met alleen eenrequire. - De cache wordt bij elk van de events
composer install/update/dump-autoloadautomatisch verwijderd en bij de volgende start opnieuw opgebouwd. - In omgevingen waarin je Composer met
--no-scriptsdraait, moet jephp artisan package:discoverexpliciet aanroepen. - Met
*bijdont-discoverschakel je de volledige automatische detectie uit.
Gerelateerde pagina’s
- De basis van packageontwikkeling — het basisgebruik van service providers en
extra.laravel - Deferred service providers — het laadmoment van gedetecteerde providers optimaliseren
- Packages testen met Orchestra Testbench — het Testbench-specifieke
package:discover-commando