Categories
Composer Guides Laravel Resources

Creating a Composer Package for Laravel

Build Composer Packages like a pro. Share your code with the world by learning how to make, and distribute, Composer Packages.

Despite using Composer for years I’ve never had to write a package from scratch, until today. I had a few questions before starting so I thought I’d write a primer on creating your first composer package for distribution.

I needed to create a Composer package because I needed to extend classes in Laravel Dusk. You see, I have been building a SaaS application using Laravel and was struggling with automated testing.

The other day I tracked the problem down to the way an external package works.

I knew others might be running into the same issue but it hadn’t been reported yet.

Because my other projects need this fix: I turned my code into a Composer package for Laravel. I also released it on Packagist for anyone to use.

And since I had questions before I started: I am writing this primer to make it easier for others to do the same.

Making a Package for Distribution Using Composer

Composer is a dependency manager for PHP projects. Dependency managers maintain third party libraries you’re using in your project.

Its main configuration file, composer.json, defines your dependencies. It also lists any additional scripts or data that you’ve requested for your project.

When you include a Composer package in your project it will download with its own composer.json file. That file defines source code locations and scripts to run after installation.

When building a new package to share you’ll need a file that does the same thing.

Composer.json for Packages

The composer.json file is easy to set up. There are only two required fields for distribution: name, and description.

/*
Copy and paste this, edit as you see fit.

{
  "name" : "<your-vendor-name>/<your-package-name>",
  "description" : "A short description of your package.",
}
*/

// Here is what it would look like for a package I develop
{
  "name" : "itsjustanthony/example-package",
  "description" : "This is an example package for composer distribution.",
}

You may define other fields, such as requirements, but they are not required.

With that said, here’s mine as an example:

{
  "name" : "itsjustanthony/laravel-dawn",
  "description" : "Extends the Laravel Dusk command to enable server defined $APP_ENV variable",
  "keywords": ["dusk", "laravel", "testing", "webdriver"],
  "license": "MIT",
  "authors": [
    {
      "name": "Anthony Corbelli",
      "email": "[email protected]"
    }
  ],
  "require-dev": {
    "laravel/dusk": "@dev"
  },
  "autoload": {
    "psr-4": {
      "itsjustanthony\\Laravel\\Dawn\\": "src/itsjustanthony/Laravel/Dawn"
    }
  },
  "extra": {
    "laravel": {
      "providers": [
        "itsjustanthony\\Laravel\\Dawn\\Providers\\DawnConsoleProvider"
      ]
    }
  },
  "minimum-stability": "dev",
  "prefer-stable": true
}

I have chosen the license, minimum-stability, and prefer-stable values to match the required package laravel/dusk.

The autoload section tells Composer how to find your code. Because my code follows the PSR-4 standard it was easy with the psr-4 section. The keys here represent root namespaces and values are the directory path where that namespace begins.

Finally: under the extra section I tell Laravel to automatically load a service for me.

Local Composer Repositories

Now that we have our local project set up with a composer.json file in place: how do we test it?

You can build and test locally using repositories.

Let’s assume your project structure looks like this:

- Projects
-- BigClientProject
--- composer.json
-- LittleDevLibrary
--- composer.json

Add a repositories section to the root of your composer.json file like this:

// ...
  "repositories" : [
    "<your-vendor-name>/<your-package-name>" : {
      "type" : "path",
      "url" : "../LittleDevLibrary"
  ],
// ...

<your-vendor-name>/<your-package-name> must match the name defined in LittleDevLibrary/composer.json.

Now run composer update to install your local dependency.

Distributing your Package with Packagist

Packagist is a public repository of Composer packages. Because it can integrate directly with Github and Bitbucket it’s ideal for our needs. Go create an account with them, it’s free and I’ll wait.

If you haven’t yet: first create a git repo for your package, commit the code, and then push it to your repo.

Once your git repo has been updated log in to your Packagist account and head to their submission page.

Now just paste the URL to your public repository in the box and submit it for distribution!

Testing your Newly Distributed Package

You need to make sure that everything works as expected, so head back to your project folder.

Run rm -rf vendor/<your-vendor-name> to clear out the code from your local repository.

Remove the repositories section from your composer.json file, or just the definition for this package if there are others.

Finally: run composer update again. You should see your package downloaded from the internet along with the others.

Test your code to ensure that it downloaded and autoloads properly:

composer require <your-vendor-name>/<your-package-name>

# mine was for testing so now I would run
# phpunit && php artisan dawn
# to ensure it worked

And then you’re all done!

Making your First Composer Package for Distribution

If I had a dollar for every dependency manager available you’d never see my rich butt again.

Since every dependency manager operates differently, you might have the same questions I did.

Mainly: is there a different set of requirements for a composer.json file that you build for distribution vs. the ones used to define project dependencies?

The answer is largely no, at least for a package this simple.

My simple package can be found on Packagist under itsjustanthony/laravel-dawn. It extends framework testing classes (Browser Testing by Laravel Dusk) to support setting environment variables on a server level (eg., EXPORT APP_ENV=testing).

To use it in your project, run composer require itsjustanthony/laravel-dawn.

The provided artisan commands are dawn and dawn:fails. They extend dusk and dusk:fails respectively.

Have questions or need help? Then let me know!

Leave a Reply

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