How to develop and test Laravel package in isolation?

How to develop and test Laravel package in isolation?

Written by jeblister on Nov 28th, 2021 Views Report Post

composer

In this post, I go over how to create a php package/library project with Composer and test it on Laravel. This would be a great addition to any Laravel workflow.

Initialize your package

In PHP world Composer is currently the industry standard handling third-party packages. It allows us to automatically download the code libraries from Packagist along with all of their dependencies.

To Initializing your first package, create an empty directory. It is not necessary to nest packages in an existing Laravel project. I store my packages in ~/packages/ and my Laravel apps live in ~/sites/.

The command composer init on your package directory will generatecomposer.json file code like  this :

{
  "name": "acme/my-package",
  "description": "A demo package",
  "type": "library",
  "license": "MIT",
  "authors": [
    {
      "name": "acme",
      "email": "[email protected]"
    }
  ],
"autoload": {
        "psr-4": {
            "Acme\\MyPackage\\": "src"
        }
    },
  "require": {},
{
    "minimum-stability": "dev",
    "prefer-stable": true,
}
}

So you need a package name, the type``, the PSR-4 autoload definition that maps the namespace to the src folder (or wherever the source code of your package lives) .

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.

<!-- src/MyPackageServiceProvider -->
<?php

namespace acme\MyPackage;

use Illuminate\Support\ServiceProvider;
class MyPackageServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     *@return void
     */
    public function boot()
    {    }    /**
     * 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.

<!-- src/MyPackage -->
<?php
namespace acme\MyPackage;
class MyPackage
{
    public function whatever($foo)
    {
        return $foo;
    }
}

Autoloading

To automatically register it with a Laravel project using Laravel's package auto-discovery we add our service provider to the "extra"> "laravel"> "providers" key in our package's composer.json:

<!-- ~packages/acme/MyPackage/composer.json  -->
{
  ...,

  "autoload": { ... },

  "extra": {
      "laravel": {
          "providers": [
              "acme\\MyPackage\\MyPackageServiceProvider"
          ]
      }
  }
}

Import the Package Locally

To help with development, Just add the package repository as “path” in the Laravel applications composer.json and require your package with the version “dev-master”.

<!-- ~sites/myproject/composer.json  -->
{
    "name": "laravel/laravel",
    "type": "project",

    ...

    "repositories": [
        {
            "type": "path",
            "url": "../../packages/acme/*",
            "options": {
                "symlink": true
            }
        }
    ],
		"require": {
		    "acme/my-package": "dev-master"
		}
}

The above snippet tells Composer to include a new “repository” which contains your package and symlink it to your working code folder. By writing "type": "path" Composer knows that you would like to reference a local repository and the url defines its location (the path can be relative or absolute).

With this require snippet the package will be pulled in as a dev package on the master branch (dev-master). If you want to pull another branch you can change it by using dev-[branchname] instead.

Now all that’s left is to run the command composer update acme/my-package --prefer-source. This will tell Composer to bring in your new local package and prefer the source (local repository) version instead of a distribution build.

You will now have a symlink’d Composer package local to your project which can be edited directly from your /vendor directory, allowing you to make changes and immediately test the results in your main project.

Resources

laravelpackage

Laravel Package Boilerplate

Getting started on Laravel package development

Comments (0)