Parts
go to part...
To start create a new folder for your package - you can call it whatver you want, it doesn't matter. Then run composer init
inside the new folder in your terminal. Composer will prompt you with a bunch of questions and then generate the composer.json
file for your future package.
The prompt questions are pretty self-explanatory. Don't worry if you make a mistake - you'll be able to correct it manually later. Possible prompt answers:
Package name (<vendor>/<name>) [***/***]: voerro/simple-package
Description []: A dead simple Laravel package
Author [***, n to skip]: Alexander Zavyalov <alexander@email.com>
Minimum Stability []: stable
Package Type (e.g. library, project, metapackage, composer-plugin) []: library
License []: MIT
Would you like to define your dependencies (require) interactively [yes]? n
Would you like to define your dev dependencies (require-dev) interactively [yes]? n
Do you confirm generation [yes]? yes
Minimum Stability stable
means that whenever someone tries to install your package they will get the stable version and not the dev version. If there's no stable version they will get an error explaining that there's no suitable version of the package available.
For the package type
you should choose library
since that's what we're going to implement. You can read more about different package types in the Composer's documentation.
Now we have a single file in our folder, which is composer.json
. You should also initialize a git
repository there. Let's open the file.
{
"name": "voerro/simple-package",
"description": "A dead simple Laravel package",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Alexander Zavyalov",
"email": "alexander@email.com"
}
],
"minimum-stability": "stable",
"require": {}
}
We skipped the requirements earlier in the prompt and now we'll add them manually. First let's add php
. Since we're developing a Laravel 5.5 package and it requires php of at least version 7.0, that's what we're going to require as well. Then for our development we're going to required phpunit/phpunit
and orchestra/testbench
. This is what the require
section looks like now:
"require": {
"php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.5",
"orchestra/testbench": "^3.5"
}
Since we're not inside a Laravel project here, we need orchestra/testbench
which allows you to write your tests as if you were working inside a typical Laravel application. Below the requirements we need to add autoloading specifying aliases for the folders inside our project.
"autoload": {
"psr-4": {
"Voerro\\SimplePackage\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Voerro\\SimplePackage\\Test\\": "tests/"
}
},
You can call your aliases whatever you want, but it's better to make them relevant to your package. These point to the src
and tests
folders respectively. Create those folders. The last thing we need to add is the extra
section which is used by the Laravel 5.5 package autodiscovery. SimplePackage
inside the aliases
object is what your package's main class going to be called.
"extra": {
"laravel": {
"providers": [
"Voerro\\SimplePackage\\SimplePackageServiceProvider"
],
"aliases": {
"SimplePackage": "Voerro\\SimplePackage\\SimplePackageFacade"
}
}
}
Now create 3 files inside the src
folder (SimplePackageServiceProvider.php
, SimplePackageFacade.php
, and SimplePackage.php
) with the following content.
SimplePackageFacade.php
<?php
namespace Voerro\SimplePackage;
use Illuminate\Support\Facades\Facade;
class SimplePackageFacade extends Facade
{
protected static function getFacadeAccessor()
{
return 'simple-package';
}
}
SimplePackageServiceProvider.php
<?php
namespace Voerro\SimplePackage;
use Illuminate\Support\ServiceProvider;
class SimplePackageServiceProvider extends ServiceProvider
{
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->singleton(SimplePackage::class, function () {
return new SimplePackage();
});
$this->app->alias(SimplePackage::class, 'simple-package');
}
}
SimplePackage.php
<?php
namespace Voerro\SimplePackage;
class SimplePackage
{
//
}
SimplePackage.php
is where the main code of your package will be.
The service provider SimplePackageServiceProvider.php
is the connection between your package and Laravel.
The facade SimplePackageFacade.php
provides a "static" interface to your package's main class.
As you might have noticed, the facade and the service provider use
two classes from the Illuminate\Support
namespace. You should add this package to the require
section of your composer.json file. You should also add there any of the (Laravel) packages you will be using in the future.
"require": {
"php": ">=7.0",
"illuminate/support": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "^6.5",
"orchestra/testbench": "^3.5"
},
We'll just make a single static method inside our main class to show how things work. The method will simply add two numbers and return the result.
<?php
namespace Voerro\SimplePackage;
class SimplePackage
{
public static function add($a, $b) {
return $a + $b;
}
}
Now let's move on to testing. This is the only way to verify everything works in a package that's running outside Laravel or any other project. Create a file called TestCase.php
inside the tests
folder. This will be the parent class for our tests which in turn extends from orchestra/testbench
.
<?php
namespace Voerro\SimplePackage\Test;
use Voerro\SimplePackage\SimplePackageFacade;
use Voerro\SimplePackage\SimplePackageServiceProvider;
use Orchestra\Testbench\TestCase as OrchestraTestCase;
class TestCase extends OrchestraTestCase
{
/**
* Load package service provider
* @param \Illuminate\Foundation\Application $app
* @return Voerro\SimplePackage\SimplePackageServiceProvider
*/
protected function getPackageProviders($app)
{
return [SimplePackageServiceProvider::class];
}
/**
* Load package alias
* @param \Illuminate\Foundation\Application $app
* @return array
*/
protected function getPackageAliases($app)
{
return [
'SimplePackage' => SimplePackageFacade::class,
];
}
}
Create another file called SimplePackageTest.php
for the actual tests. Extend the class inside from our TestCase
class and write the tests the way you normally would inside a Laravel application. The test for our package will be simple.
<?php
namespace Voerro\SimplePackage\Test;
use Voerro\SimplePackage\SimplePackage;
class SimplePackageTest extends TestCase
{
public function testAddition()
{
$result = SimplePackage::add(17, 3);
$this->assertEquals(20, $result);
}
}
Finally, create the phpunit.xml
file in the root of your package with the following content:
<?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="Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
</phpunit>
The boilerplate is ready. Go to the terminal and run composer install
to download all the required packages. After that run phpunit
(or vendor/bin/phpunit
if you don't have a gloval PHPUnit installation) and make sure all the tests pass. From this point you may continue developing your package.
All the materials at voerro are absolutely free and are worked on in the author's spare time. If you found any of the tutorials helpful, please consider supporting the project. Thank you!