Initiliazing your package

We will start off by creating a new folder and setting up the initial composer.json.

mkdir mypackage

cd mypackage

composer init

The composer config generator will then ask you a bunch of questions. Most of them are self explanatory but for example choosing the license might be tricky if you are not familiar with Open Source licenses and standards. Fortunately there is a helpful web site that helps you make this decision. You can always update these in the composer.json later.

Add PSR-4 autoloading for your package

After you have initiliazed the composer.json you have to add your namespace to the composers autoload section. Basically it binds together the namespace and the relative path in the packages folder.

{

"name": "lasselehtinen/mypackage",

"description": "My awesome Laravel package",

"type": "library",

"license": "MIT",

"authors": [

{

"name": "Lasse Lehtinen",

"email": "lasse.lehtinen@foobar.com"

}

],

"require": {},

"autoload": {

"psr-4": {

"lasselehtinen\\MyPackage\\": "src"

}

},

}

Create new service provider

As the official documentation states the packages service provider connects your package with Laravel and defines the assets it provides. Your package might include custom migrations, routes or views. All those are defined in the service provider.

Service providers are the connection points between your package and Laravel. A service provider is responsible for binding things into Laravel’s service container and informing Laravel where to load package resources such as views, configuration, and localization files.

So start creating a new service provider in the packages src directory. Please note the registering of the singleton and creating the alias for the facade that is created on the later stage.

<?php namespace lasselehtinen\MyPackage; use Illuminate\Support\ServiceProvider;

{

/**

* Bootstrap the application services.

*

*

*/

public function boot()

{ class MyPackageServiceProvider extends ServiceProvider/*** Bootstrap the application services. @return void*/public function boot() }

* Register the application services.

*

*

*/

public function register()

{

$this->app->singleton(MyPackage::class, function () {

return new MyPackage();

}); /*** Register the application services. @return void*/public function register()$this->app->singleton(MyPackage::class, function () {return new MyPackage();}); $this->app->alias(MyPackage::class, 'my-package');

}

}

Create new package class

Since this is a very simple package only containing one method for multiplying, we will have only one single class. So create this class in your src directory.

<?php namespace lasselehtinen\MyPackage;

{

/**

* Multiplies the two given numbers

*

*

*

*/

public function multiply($a, $b)

{

return $a * $b;

}

} class MyPackage/*** Multiplies the two given numbers @param int $a @param int $b @return int*/public function multiply($a, $b)return $a * $b;

Create a facade

The facade clues the service class and the alias together. So use the same return value for the alias as in the service provider.

<?php namespace lasselehtinen\MyPackage; use Illuminate\Support\Facades\Facade; class MyPackageFacade extends Facade

{

protected static function getFacadeAccessor()

{

return 'my-package';

}

}

Testing your package

We wouldn’t want to release anything that is not covered with tests wouldn’t we? So let’s include phpunit and orchestra/testbench for our package. orchestra/testbench is an awesome package that helps testing Laravel spesific packages. Basically it launches a full Laravel application so you can test that your package works correctly with Laravel. Our simple package would go fine with just with phpunit, but I included orchestra/testbench since it is very useful if you provide routes or views in your package. In the example below, we are just testing the service provider and alias.

composer require --dev phpunit/phpunit

composer require --dev orchestra/testbench

Add namespaces for your tests in composer.json

"autoload-dev": {

"psr-4": {

"lasselehtinen\\MyPackage\\Test\\": "tests/"

}

}

Create phpunit.xml

<?xml version="1.0" encoding="UTF-8"?>

<phpunit bootstrap="vendor/autoload.php"

backupGlobals="false"

backupStaticAttributes="false"

colors="true"

verbose="true"

convertErrorsToExceptions="true"

convertNoticesToExceptions="true"

convertWarningsToExceptions="true"

processIsolation="false"

stopOnFailure="false">

<testsuites>

<testsuite name="MyPackage Test Suite">

<directory>tests</directory>

</testsuite>

</testsuites>

<filter>

<whitelist>

<directory suffix=".php">src/</directory>

</whitelist>

</filter>

</phpunit>

Create base testcase in tests\TestCase.php. The getPackageProviders and getPackageAliases methods are equivalent of adding your service provider and alias to your Laravel applications config/app.php. So now the test case is creating a Laravel application that has the service provider and alias loaded.

<?php namespace lasselehtinen\MyPackage\Test; use lasselehtinen\MyPackage\MyPackageFacade;

use lasselehtinen\MyPackage\MyPackageServiceProvider;

use Orchestra\Testbench\TestCase as OrchestraTestCase;

{

/**

* Load package service provider

*

*

*/

protected function getPackageProviders($app)

{

return [MyPackageServiceProvider::class];

} class TestCase extends OrchestraTestCase/*** Load package service provider @param \Illuminate\Foundation\Application $app @return lasselehtinen\MyPackage\MyPackageServiceProvider*/protected function getPackageProviders($app)return [MyPackageServiceProvider::class];

* Load package alias

*

*

*/

protected function getPackageAliases($app)

{

return [

'MyPackage' => MyPackageFacade::class,

];

}

} /*** Load package alias @param \Illuminate\Foundation\Application $app @return array*/protected function getPackageAliases($app)return ['MyPackage' => MyPackageFacade::class,];

Create the actual test.

<?php namespace lasselehtinen\MyPackage\Test; use MyPackage;

{

/**

* Check that the multiply method returns correct result

*

*/

public function testMultiplyReturnsCorrectValue()

{

$this->assertSame(MyPackage::multiply(4, 4), 16);

$this->assertSame(MyPackage::multiply(2, 9), 18);

}

} class MyPackageFunctionTest extends TestCase/*** Check that the multiply method returns correct result @return void*/public function testMultiplyReturnsCorrectValue()$this->assertSame(MyPackage::multiply(4, 4), 16);$this->assertSame(MyPackage::multiply(2, 9), 18);

Then run vendor/bin/phpunit and the tests should have passed.

But my package needs to provide views/routes/commands/migrations!

In case your package needs additional assets that need to be published, I suggest you turn to the official documentation. Those are covered pretty well.

But I want to develop my package in a Laravel application!

In case using TDD with orchestra/testbench does not feel natural for you, fortunately you can use of the composers repository features to link your local package to an existing Laravel application. Just add the package repository as “path” in the Laravel applications composer.json and require your package with the version “dev-master”. Then run composer update, which symlinks the package folder in your vendor directory. Then soon as you have made changes in the package, they are reflected in the Laravel application.