Expansion package development
brief introduction
Expansion packs are the main way to add additional functionality to Larvel. The expansion package can provide any function as small as the processing date, such as Carbon , as large as the whole BDD test framework, such as Behat 。
Of course, there are many different types of expansion packs. Some expansion packs are independent of Larvel, which means they can be used in any framework, not just Larvel. For example, Carbon and Behat are independent expansion packages. All these expansion packs can be accessed through the composer.json
Declared in the file for use by Laravel.
On the other hand, other dependent expansion packages can only be used with Larvel. These packages may have specific routes, controllers, views, and configurations to enhance the functions of Larvel. This document mainly discusses the expansion packages that can only be used in Larvel.
Notes on the facade
When writing Larravel applications, whether you use contract still Facade , usually doesn't matter, because both provide basically the same level of testability. However, when writing an expansion package, you cannot access all Laravel test auxiliary functions in the expansion package. If you want to write expansion package tests freely like in the expansion package, just like in the Larravel application, you can use Orchestral Testbench Expansion pack.
Package auto discovery
Configuration file applied in Laravel config/app.php
Medium, providers
The configuration item defines a list of service providers that will be loaded by Larave. After installing the new expansion pack, you need to add the service provider of the expansion pack to this list in the old version so that it can be used by Larvel. Starting from Laravel 5.5, we don't have to manually add service providers to the list, but define them under the expansion package composer.json
Filed extra
Option, in addition to service providers, we can also register in this way Facade :
"extra": { "laravel": { "providers": [ "Barryvdh\\Debugbar\\ServiceProvider" ], "aliases": { "Debugbar": "Barryvdh\\Debugbar\\Facade" } } },
After the definition, Larvel will automatically register the corresponding service provider and facade after installing the extension package, so as to provide a more convenient installation experience for the extension package user.
Select Package Discovery
If you are a user of the package and do not want to use the package auto discovery function, you can use it in the application like this composer.json
Filed section
The package name is listed in the option:
"extra": { "laravel": { "dont-discover": [ "barryvdh/laravel-debugbar" ] } },
You can also dont-discover
Wildcard characters are used in configuration items *
Disable auto discovery of all expansion packs:
"extra": { "laravel": { "dont-discover": [ "*" ] } },
Service Provider
Service Provider It is the link between the expansion package and Laravel. The service provider is responsible for binding objects to the Service Container It also tells Laravel where to load package resources such as views, configurations, and localization files.
Service provider inherits from Illuminate\Support\ServiceProvider
Class and contains two methods: register
and boot
。 ServiceProvider
The base class is in the Composer package illuminate/support
。 To learn more about service providers, see file 。
resources
to configure
Usually, you need to publish the expansion package configuration file to the config
Directory, which will allow extension package consumers to easily override the default configuration options. To publish a configuration file, just click the boot
Method publishes
Method:
/** * Perform post-registration booting of services. * * @return void */ public function boot(){ $this->publishes([ __DIR__.'/ path/to/config/courier.php' => config_path('courier.php'), ]); }
Now, when the expansion pack user executes Laravel's Artisan command vendor:publish
Your files will be copied to the specified location. Of course, after the configuration is published, it can be accessed in the same way as other configuration options:
$value = config('courier.option');
Note: Do not define the closure in the configuration file, because when the user executes the Artisan command config:cache
Closures will not be serialized correctly when.
Default expansion pack configuration
You can also choose to merge your own expansion pack configuration file into the published copy of the application, which allows users to introduce only the configuration options they actually want to overwrite in the application configuration file. To merge the two configurations, click the register
Method mergeConfigFrom
Method:
/** *Register binding in container * * @return void */ public function register(){ $this->mergeConfigFrom( __DIR__.'/ path/to/config/courier.php', 'courier' ); }
Note: This method is only incorporated into the first dimension of configuration data. If the user has defined a multidimensional configuration array, the missing part cannot be merged.
route
If the expansion package contains routes, you can use loadRoutesFrom
Method to load them. This method will automatically determine whether the application route has been cached. If the route has been cached, the route file will not be loaded:
/** * Perform post-registration booting of services. * * @return void */ public function boot() { $this->loadRoutesFrom(__DIR__.'/routes.php'); }
transfer
If your expansion package contains Database migration , you can use loadMigrationsFrom
Method tells Larravel how to load them. loadMigrationsFrom
The method receives the migration path of the expansion package as its only parameter:
/** * Perform post-registration booting of services. * * @return void */ public function boot() { $this->loadMigrationsFrom(__DIR__.'/path/to/migrations'); }
After the expansion pack migration registration is completed php artisan migrate
Automatically run when. You do not need to export them to the database/migrations
catalog.
factory
If the expansion package contains Database Factory , you can use loadFactoriesFrom
Method tells Larravel how to load them. loadFactoriesFrom
The method receives the factory directory path in the expansion package as the only parameter:
/** * Bootstrap any application services. * * @return void */ public function boot() { $this->loadFactoriesFrom(__DIR__.'/path/to/factories'); }
After the factory in the expansion package is registered, it can be used in applications:
factory(Package\Namespace\Model::class)->create();
translate
If your expansion package contains Translate files , you can use loadTranslationsFrom
Method tells Larravel how to load them. For example, if your extension package is named courier
, you should add the following code to the boot
method:
/** * Perform post-registration booting of services. * * @return void */ public function boot(){ $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier'); }
Expansion pack translation uses the form package::file.line
Syntax. So, you can use the following methods from messages
Load in file courier
Packaged welcome
that 's ok:
echo trans('courier::messages.welcome');
Publish Translation File
If you want to release the expansion package translated into the application resources/lang/vendor
Directory, you can use the service provider's publishes
Method, which receives a package path and corresponding publishing path array parameters, for example, to publish courier
The translation file of the expansion package can be:
/** * Perform post-registration booting of services. * * @return void */ public function boot(){ $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier'); $this->publishes([ __DIR__.'/ path/to/translations' => resource_path('lang/vendor/courier'), ]); }
In this way, users can execute Artisan commands vendor:publish
Publish the expansion pack translation file to the specified directory of the application.
view
To register an expansion pack in Larravel view , you need to tell Larravel where the view is, and you can use the loadViewsFrom
Method. loadViewsFrom
Method receives two parameters: the path of the view template and the expansion package name. For example, if your expansion pack name is courier
, add the following code to the boot
Method:
/** * Perform post-registration booting of services. * * @return void */ public function boot(){ $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); }
The expansion pack view uses the package::view
Syntax. Therefore, you can load it as follows courier
On expansion packs admin
View:
Route::get('admin', function () { return view('courier::admin'); });
Overwrite expansion pack view
When you use loadViewsFrom
Method, Laravel actually registers two storage locations for views: one is resources/views/vendor
The other is the directory you specified. So, take courier
For example: when requesting an expansion pack view, Larave first checks whether the developer is in the resources/views/vendor/courier
A customized version of the view is provided. If the view does not exist, Larvel will search for you to call loadViewsFrom
Method. This mechanism allows end users to easily customize/overwrite the expansion pack view.
Publish View
If you want the view to be published to the application resources/views/vendor
Directory, you can use the service provider's publishes
method. This method receives the package view path and its corresponding release path array as parameters:
/** * Perform post-registration booting of services. * * @return void * @translator laravelacademy.org */ public function boot(){ $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); $this->publishes([ __DIR__.'/ path/to/views' => base_path('resources/views/vendor/courier'), ]); }
Now, when the user executes the Laravel Artisan command vendor:publish
The expansion pack view will be copied to the specified path.
View Components
If your expansion package contains View Components , you can use loadViewComponentsAs
Method tells Larravel how to load them. loadViewComponentsAs
Method receives two parameters: the label prefix of the view component and the view component class array. For example, if your expansion pack prefix is courier
And have Alert
and Button
Two view components can be found in the service provider's boot
Methods introduce them like this:
/** * Bootstrap any application services. * * @return void */ public function boot() { $this->loadViewComponentsAs('courier', [ Alert::class, Button::class, ]); }
After the view component is registered in the service provider, it can be used in the view:
<x-courier-alert /> <x-courier-button />
command
To register the Artisan command of the expansion package through Laravel, you can use commands
method. This method needs to pass in the command name array. After the registration number command, you can use the Artisan CLI Execute them:
/** * Bootstrap the application services. * * @return void */ public function boot() { if ($this->app->runningInConsole()) { $this->commands([ FooCommand::class, BarCommand::class, ]); } }
Publish front-end resources
Your expansion package may contain JavaScript, CSS and pictures. You need to publish these front-end resources to the public
Directory, you can use the service provider's publishes
method. In this example, we add a front-end resource group tag public
, used to publish related front-end resource groups:
/** * Perform post-registration booting of services. * * @return void */ public function boot(){ $this->publishes([ __DIR__.'/ path/to/assets' => public_path('vendor/courier'), ], 'public'); }
Now, when the user executes vendor:publish
When the command is given, the front-end resources will be copied to the specified location. Since the front-end resources need to be overwritten every time the package is updated, you can use the --force
identification:
php artisan vendor:publish --tag=public --force
Publish File Group
Sometimes you may want to publish the front-end resources and business resources (configuration, view, etc.) of the extension package separately. For example, you may want the consumer to publish the configuration of the extension package without publishing the front-end resources, which can be called in the service provider of the extension package publishes
Method. Next, we will check the extension package service provider's boot
Two publishing groups are defined in the method:
/** * Perform post-registration booting of services. * * @return void */ public function boot(){ $this->publishes([ __DIR__.'/../ config/package.php' => config_path('package.php') ], 'config'); $this->publishes([ __DIR__.'/../ database/migrations/' => database_path('migrations') ], 'migrations'); }
Now you can use Artisan commands vendor:publish
The two groups are published separately by referencing the tag name:
php artisan vendor:publish --tag=config