Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Bootstrapping Packages with spatie/laravel-package-tools

Laravel package maintainers use a service provider, a class Laravel runs during application startup, to register package services and set up features such as routes and views. Spatie’s laravel-package-tools cuts down on repeated setup code in that class. You extend its PackageServiceProvider and list the package resources it should handle. The package follows Laravel’s service-provider model, with conventions for common package tasks.

Package Tools reduces the setup code for configuration, migrations, assets, and other supported resources. You still choose where their files go and whether an application should publish or load them. The configurePackage() method puts those choices in one place.

Declare package resources in one provider

A minimal provider extends PackageServiceProvider and configures a Package object. The package name is required.

use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;

class YourPackageServiceProvider extends PackageServiceProvider
{
    public function configurePackage(Package $package): void
    {
        $package
            ->name('your-package-name')
            ->hasConfigFile()
            ->hasMigration('create_package_tables')
            ->hasAssets();
    }
}

Each method tells the base provider what to do with a resource. Without Package Tools, maintainers commonly write the registration and publishing code for each resource in the service provider. The Package Tools API lets maintainers chain these method calls and see the package’s supported resources together.

The default layout places the provider in src and configuration files in config. It puts migrations in database/migrations and assets in resources/dist; views go in resources/views, and routes in routes. These paths are defaults, not requirements. If you change a path, check the rules for that method. Most paths are resolved relative to the provider’s location in src. discoversMigrations() uses a different rule.

A package name beginning with laravel- has that prefix omitted from publishing names and related conventions. Account for this when choosing the config filename or checking a publish tag.

Use the hooks around Laravel’s lifecycle

Laravel calls a provider’s register() method to register services, then calls its boot() method to prepare features. Package Tools keeps these Laravel methods and adds four hooks around its own work. A hook is a method you can override to run custom code at a specific point.

Package Tools hook When it runs
registeringPackage() At the start of Package Tools’ register() method
packageRegistered() At the end of Package Tools’ register() method
bootingPackage() At the start of Package Tools’ boot() method
packageBooted() At the end of Package Tools’ boot() method

During register(), the base provider calls registeringPackage(), then creates and configures the package. It checks that you supplied a name, registers the package configuration, and calls packageRegistered(). During boot(), it calls bootingPackage(), handles the configured resources, and then calls packageBooted(). The provider implementation and usage documentation explain when each hook runs.

These hooks add to Package Tools’ work and leave Laravel’s register() and boot() methods in place. For example, registeringPackage() runs at the start of the base provider’s registration work. Override a hook to run your package’s custom code before or after that work. Choose the hook based on when that code needs to run.

Register and publish configuration

Put the package’s configuration file in its config directory and declare it with hasConfigFile(). Package Tools registers the configuration for the application and makes the file publishable. Publishing copies the file into the Laravel application, where maintainers can edit their copy.

For a package with multiple configuration files, pass their names as an array to hasConfigFile(). The documented publish tag follows the package name and ends in -config. If the package name starts with laravel-, omit that prefix from the config filename as well.

Ask users to publish the configuration when they need to edit package-specific settings in their application; otherwise, they can use the package defaults without keeping a copy.

Choose how applications handle migrations

Package Tools supports named migrations, multiple named migrations through hasMigrations(), and finding migrations in a directory through discoversMigrations(). By default, migration files live in database/migrations. You can publish registered or discovered migrations with the package’s migrations tag. Package Tools adds a current-datetime prefix to published files.

Publishing and running migrations give package users different levels of control. When an application publishes the files, it copies them into its migrations directory and runs them through its own migration workflow. When the package declares runsMigrations(), it registers the migrations to run without requiring the application to publish copies.

Choose the approach that gives package users the control they need over migration files and upgrades. Publish migrations when application maintainers should own and edit their copies. Use runsMigrations() when the package should run its migrations without creating copies in the application. The package documentation describes both options. The right choice depends on who should manage the migration files.

Publish package assets

Place assets that users can publish in resources/dist and call hasAssets(). Package Tools registers the assets, and users can publish them with the package’s assets tag. The files go to public/vendor/<package-name> in the application that uses the package.

This declaration replaces the manual publishing setup for those assets. The provider does not copy them into the application when it loads. Tell users when to publish the assets and where the files will go so they can reference them from their application.

Extend the same pattern to other resources

The API also supports routes, commands, and views. It supports Blade components, translations, Inertia components, view composers, and shared view data. Users can also publish service providers. The optional hasInstallCommand() method configures a package-specific installer. The installer can combine selected setup tasks, such as publishing resources or asking whether to run migrations. These features extend the same approach to more than configuration, migrations, and assets.

Package Tools is most useful when a package follows its conventions and needs several common resources. A package with a different directory structure can use custom paths. Maintainers still need to know how Laravel loads providers and how each resource gets to the application that uses the package. The library reduces setup code, but maintainers still choose the package structure and who owns each resource.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *