Composer Local Packages for Dummies

3 min

Mon, Dec 25, 2017

X comments

Edit Post

This is the simplest way to start using /packages directory in your application, that leads to cleaner code, maintainable architecture and is the best to start testing.

I wrote about pros and cons of local packages before. After year of using this in practice and mentorings I polished this approach to even simpler version that is easy to start with.

Do You Have?

monolithic code in /app

no unit tests

code that is using 3rd party services, like payments, invoice API and coding standards

namespaces

old application you maintain for many years

Do You Want to?

start testing

have decoupled code

board new programmer with no explaining

understand how to scale architecture by decreasing code complexity





There is no need to use Github, love open-source, understand package design or understand composer beyond PSR-4. No symlink issues, no forgotten composer update . Anyone can start using this!

4 Steps to first Dummy Local Package

Your application now looks similar to this:

/app /temp /vendor composer.json

1. Create Packages directory

/app /temp +/packages /vendor composer.json

2. Create First Package

Start with something simple like filesystem or string utils.

/app /temp /packages + /file-system + /src /vendor composer.json

3. Move first Class to new package directory

/app /temp /packages /file-system /src + FileSystem.php /vendor composer.json





The best practise is to use your company or application name as namespace, e.g. EntryDo . Second part of namespace will be package name ( file-system ) in CamelCaps format.

namespace EntryDo\FileSystem; final class FileSystem { public function readFile(string $filePath): string { // is file or directory? // is readable? // ... } }

You're awesome! Congratulations, you've just made your first local packages and you're definitely not a dummy anymore.

4. Autoload with Composer

The class is now decoupled. Now we have to tell composer where to find it!

This is your composer.json :

{ "require": { "favorite/framework": "^4.0" }, "autoload": { "classmap": "app" } }

Maybe your already have PSR-4 structure (great job if you do!), but let's say you maintain an old application.





Add our new package:

{ "require": { "favorite/framework": "^4.0" }, "autoload": { "classmap": "app", + "psr-4": { + "EntryDo\FileSystem\": "packages/file-system/src + } } }





And now the answer to most questions on StackOverflow around this topic- rebuild the composer autoload file ( /vendor/autoload.php ) from CLI:

composer dump # which is shortcut for: # composer dump-autoload

That's it. You are ready to go!

5. Bonus: Add Your First Test

Add test for a class was never easier. Create Test file for FileSystem class:

/app /temp /packages /file-system /src FileSystem.php + /tests + FileSystemTest.php /vendor composer.json





Add \Tests to EntryDo\FileSystem namespace:

namespace EntryDo\FileSystem\Tests; use PHPUnit\Framework\TestCase; final class FileSystemTest extends TestCase { public function testReadFile(): void { // test readFile() method } }





Update phpunit.xml to cover all tests of local packages:

<phpunit bootstrap="vendor/autoload.php" colors="true"> <testsuite> <directory>packages/*/tests</directory> </testsuite> </phpunit>





And run tests:

vendor/bin/phpunit





So this is the easiest way how to use composer local packages in 2018. I hope you enjoy it the same way your application does.





Happy packaging!