3

I am trying to develop a new Laravel package locally installed via Composer.

These are my steps:

  • I install a new Laravel application with composer create-project laravel/laravel my-application

  • I create a new directory in the root with the following content:

    packages/randolf/custom-package/composer.json

    {
        "name": "randolf/custom-package",
        "description": "My new Custom Package",
        "type": "library",
        "license": "MIT",
        "require": {},
        "autoload": {
            "psr-4": {
                "Randolf\\CustomPackage\\" : "src/"
            }
        },
        "extra": {
            "laravel": {
                "providers": [
                    "Randolf\\CustomPackage\\CustomPackageServiceProvider"
                ],
                "aliases": {
                    "CustomPackage": "Randolf\\CustomPackage\\Facades"
                }
            }
        }
    }
    

    packages/randolf/custom-package/src/CustomPackage.php

    <?php
    
    namespace Randolf\CustomPackage;
    
    class CustomPackage
    {
        public function sayHi()
        {
            return "Hi from class!";
        }
    }
    

    packages/randolf/custom-package/src/CustomPackageServiceProvider.php

    <?php
    
    namespace Randolf\CustomPackage;
    
    use Illuminate\Support\ServiceProvider;
    
    class CustomPackageServiceProvider extends ServiceProvider
    {
        public function boot()
        {
    
        }
    
        public function register()
        {
            $this->app->bind('custom-package', function()
            {
                return new CustomPackage();
            });
        }
    }
    

    packages/randolf/custom-package/src/Facades/CustomPackageFacade.php

    <?php
    
    namespace Randolf\CustomPackage\Facades;
    
    use Illuminate\Support\Facades\Facade;
    
    class CustomPackageFacade extends Facade
    {
    
        /**
        * Get the registered name of the component.
        *
        * @return string
        */
        protected static function getFacadeAccessor() { return 'custom-package'; }
    }
    
  • I add my package in Laravel with composer, adding the repositories key: /composer.json

    "repositories": {
        "randolf/custom-package": {
            "type": "path",
            "url": "packages/randolf/custom-package",
            "options": {
                "symlink": true
            }
        }
    },
    "require": {
        ...
        "randolf/custom-package": "@dev"
    },
    
  • I run composer update and the install, package discover and dump-autoload works correctly:

    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 1 install, 0 updates, 0 removals
    - Locking randolf/custom-package (dev-master)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 1 install, 0 updates, 0 removals
    - Installing randolf/custom-package (dev-master): Junctioning from packages/randolf/custom-package
    Generating optimized autoload files
    > Illuminate\Foundation\ComposerScripts::postAutoloadDump
    > @php artisan package:discover --ansi
    Discovered Package: facade/ignition
    Discovered Package: fideloper/proxy
    Discovered Package: fruitcake/laravel-cors
    Discovered Package: laravel/sail
    Discovered Package: laravel/tinker
    Discovered Package: nesbot/carbon
    Discovered Package: nunomaduro/collision
    Discovered Package: randolf/custom-package
    Package manifest generated successfully.
    73 packages you are using are looking for funding.
    Use the `composer fund` command to find out more!
    
  • I create a route in routes/web.php to test the facade:

    Route::get('/test-facade', function () {
        echo CustomPackage::sayHi();
    });
    

Result: laravel facade error

Randolf
  • 367
  • 1
  • 14
  • 1
    you forgot to add the class name of your actual facade to the namespace where you are adding the alias in the composer.json file ... you aliased the namespace not the facade itself – lagbox Dec 22 '20 at 11:05
  • ‍♂️‍♂️‍♂️‍♂️‍♂️‍♂️ Tested and working. If you reply as an answer, I will be able to accept it. Thank you so much!! – Randolf Dec 22 '20 at 11:17
  • Nice tutorial! But you're invoking your method `sayHi()` as static, so you need to define it as static: `public function sayHi()` ⇒ `public static function sayHi()`. – DevonDahon Feb 11 '21 at 16:03
  • Why do you set `$this->app->bind` in your provider's `register()` method ? Not using it seems to work fine too... – DevonDahon Feb 12 '21 at 09:14
  • @DevonDahon it´s a feature called `Facades` in Laravel. You can call non-static method as static methods. First bind a new instance of your class in the provider with a name (`custom-package` in this example). Then, create the Facade that return this same name (`CustomPackageFacade` and therefore the instance of your class) and finally, you register and Alias to the facade in your `composer.json`. Thus you call `CustomPackage::sayHi()` that it´s the same as `(new CustomPackage())->sayHi()`. More info: https://laravel.com/docs/master/facades – Randolf Feb 12 '21 at 10:02

1 Answers1

3

Adjust the alias in the composer.json to point to the Facade instead of its namespace:

"CustomPackage": "Randolf\\CustomPackage\\Facades\\CustomPackageFacade"
lagbox
  • 48,571
  • 8
  • 72
  • 83