Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?

My process for writing Laravel packages



Introduction

On my machine, I’ve a bundle folder. From right here I make a folder for every bundle.

I then load these into my initiatives utilizing composer.json

Within the require part load the bundle by its vendor identify adopted by the bundle identify then utilizing @dev to load the principle model

"dcblogdev/laravel-module-generator": "@dev"
Enter fullscreen mode

Exit fullscreen mode

Subsequent with a purpose to load this, inform composer the place to seek out the information domestically utilizing a repository path:

"repositories": [
    {
        "type": "path",
        "url": "../../packages/laravel-module-generator"
    }
]
Enter fullscreen mode

Exit fullscreen mode

On this case, I would like composer to look two folders above the present Laravel venture.

Now run composer replace to put in the bundle into your venture.

Whats good about this method is you are able to do this with third-party packages. That is helpful as you possibly can run assessments and add options that you just plan to boost pull requests for.



Construct a bundle

You need to use bundle starter kits similar to https://github.com/spatie/package-skeleton-laravel

I have a tendency to construct packages from scratch or copy certainly one of my present packages and take away what I dont want.

On this submit, I am imagining constructing a bundle known as laravel-tags.

The folder construction shall be:

Package Structure



license.md

For the license, I exploit The MIT licence which permits customers to freely use, copy, modify, merge, publish, distribute, sublicense, and promote the software program and its related documentation.

this file comprises:

# The license

The MIT License (MIT)

Copyright (c) 2023 dcblogdev

Permission is hereby granted, freed from cost, to any particular person acquiring a duplicate
of this software program and related documentation information (the "Software program"), to deal
within the Software program with out restriction, together with with out limitation the rights
to make use of, copy, modify, merge, publish, distribute, sublicense, and/or promote
copies of the Software program, and to allow individuals to whom the Software program is
furnished to take action, topic to the next situations:

The above copyright discover and this permission discover shall be included in
all copies or substantial parts of the Software program.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Enter fullscreen mode

Exit fullscreen mode



composer.json

I will begin by including a composer.json file that comprises:

{
  "identify": "dcblogdev/laravel-tags",
  "description": "A Laravel bundle for including tags to your content material",
  "license": "MIT",
  "authors": [
    {
      "name": "David Carr",
      "email": "dave@dcblog.dev",
      "homepage": "https://dcblog.dev"
    }
  ],
  "homepage": "https://github.com/dcblogdev/laravel-tags",
  "key phrases": [
    "Laravel",
    "Tags"
  ],
  "require-dev": {
    "orchestra/testbench": "^8.0",
    "pestphp/pest": "^v2.24.2",
    "pestphp/pest-plugin-type-coverage": "^2.4",
    "laravel/pint": "^1.13",
    "mockery/mockery": "^1.6"
  },
  "autoload": {
    "psr-4": {
      "DcblogdevTags": "src/",
      "DcblogdevTagsChecks": "assessments"
    }
  },
  "autoload-dev": {
    "classmap": [
      "tests/TestCase.php"
    ]
  },
  "additional": {
    "laravel": {
      "suppliers": [
        "DcblogdevTagsTagsServiceProvider"
      ],
      "aliases": {
        "Tags": "DcblogdevTagsFacadesTags"
      }
    }
  },
  "config": {
    "allow-plugins": {
      "pestphp/pest-plugin": true
    }
  },
  "scripts": {
    "pest": "vendor/bin/pest --parallel",
    "pest-coverage": "vendor/bin/pest --coverage",
    "pest-type": "vendor/bin/pest --type-coverage",
    "pint": "vendor/bin/pint"
  }
}
Enter fullscreen mode

Exit fullscreen mode

Breaking this down, first, the bundle wants a reputation within the conference of vendor identify and bundle identify dcblogdev/laravel-tags in my case the seller identify is dcblogdev and bundle identify is laravel-tags

Add a require part in case your bundle has dependencies

In a require-dev part, I import these third-party packages for improvement solely

testbench bundle lets you use Laravel conventions for testing.

pest is my testing framework of selection

pint to use styling conventions to my codebase.

"orchestra/testbench": "^8.0",
"pestphp/pest": "^v2.24.2",
"pestphp/pest-plugin-type-coverage": "^2.4",
"laravel/pint": "^1.13",
"mockery/mockery": "^1.6"
Enter fullscreen mode

Exit fullscreen mode

Inside autoload to any folders that you really want composer to autoload. I’ve a folder known as src which can comprise the courses and assessments for all of the assessments

One vital side of this bundle identify I will usually give the bundle a nickname to make use of so as a substitute of utilizing laravel-tags I will use tags

I will do that by utilizing Tags in any courses namespace and creating an alias:

"additional": {
  "laravel": {
    "suppliers": [
      "DcblogdevTagsTagsServiceProvider"
    ],
    "aliases": {
      "Tags": "DcblogdevTagsFacadesTags"
    }
  }
}
Enter fullscreen mode

Exit fullscreen mode



Checks

Now I’ll create 2 folders:

  1. src

  2. assessments

Inside assessments I will create these information:

TestCase.php

<?php

namespace DcblogdevTagsTests;

use DcblogdevTagsTagsServiceProvider;
use OrchestraTestbenchTestCase as Orchestra;

class TestCase extends Orchestra
{
    protected perform getPackageProviders($app)
    {
        return [
            TagsServiceProvider::class,
        ];
    }

    protected perform getEnvironmentSetUp($app)
    {
        $app['config']->set('database.default', 'mysql');
        $app['config']->set('database.connections.mysql', [
            'driver' => 'sqlite',
            'host' => '127.0.0.1',
            'database' => ':memory:',
            'prefix' => '',
        ]);
    }

    protected perform defineDatabaseMigrations()
    {
        $this->loadLaravelMigrations();

        $this->loadMigrationsFrom(dirname( __DIR__ ).'/src/database/migrations');
    }
}
Enter fullscreen mode

Exit fullscreen mode

The strategies getEnviromentSetup and defineDatabaseMigrations aren’t wanted by default. They’re solely required if you want to use a database and cargo migrations.

Inside getPackageProviders the principle bundle service supplier is loaded.

Now create a file known as Pest.php

<?php

use DcblogdevTagsTestsTestCase;

makes use of(TestCase::class)->in( __DIR__ );
Enter fullscreen mode

Exit fullscreen mode

This file calls a makes use of() perform to load the assessments case I will use __DIR__ contained in the in() methodology to make Pest use the TestCase class within the root of this listing.

Contained in the bundle root create a phpunit.xml file containing:

<?xml model="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         colours="true"
>
  <supply>
    <embrace>
      <listing suffix=".php">src/</listing>
    </embrace>
  </supply>
  <testsuites>
    <testsuite identify="Take a look at">
      <listing suffix="Take a look at.php">./assessments</listing>
    </testsuite>
  </testsuites>
  <php>
    <env identify="APP_KEY" worth="base64:2fl+Ktv64dkfl+Fuz4Qp/A75G2RTiWVA/ZoKZvp6fiiM10="/>
  </php>
</phpunit>
Enter fullscreen mode

Exit fullscreen mode

This units the placement for assessments to learn from, it is uncommon this file will have to be modified from this default.

I set an APP_KEY as normal for working assessments, its worth shouldn’t be vital.



Pint

To setup discover create a folder within the bundle root known as pint.json I exploit the Laravel preset:

{ 
    "preset": "laravel" 
}
Enter fullscreen mode

Exit fullscreen mode



ReadMe

contained in the venture root create a file known as readme.md to doc the venture, I sometimes use this format:

# Laravel Tags

Clarify what the bundle does.

# Documentation and set up directions 
[https://dcblog.dev/docs/laravel-tags](https://dcblog.dev/docs/laravel-tags)

## Change log

Please see the [changelog][3] for extra info on what has modified not too long ago.

## Contributing

Contributions are welcome and shall be absolutely credited.

Contributions are accepted through Pull Requests on [Github][4].

## Pull Requests

- **Doc any change in behaviour** - Be sure that the `readme.md` and another related documentation are saved up-to-date.

- **Contemplate our launch cycle** - We attempt to observe [SemVer v2.0.0][5]. Randomly breaking public APIs shouldn't be an choice.

- **One pull request per function** - If you wish to do multiple factor, ship a number of pull requests.

## Safety

In the event you uncover any safety associated points, please electronic mail dave@dcblog.dev electronic mail as a substitute of utilizing the problem tracker.

## License

license. Please see the [license file][6] for extra info.





Enter fullscreen mode

Exit fullscreen mode



ServiceProvider

Inside src create the service supplier in my case TagsServiceProvider.php

<?php

namespace DcblogdevTags;

use IlluminateSupportServiceProvider;

class TagsServiceProvider extends ServiceProvider
{
    public perform boot(): void
    {
        $this->configurePublishing();
    }

    public perform configurePublishing(): void
    {
        if (! $this->app->runningInConsole()) {
            return;
        }

        $this->publishes([
            __DIR__.'/../config/tags.php' => config_path('tags.php'),
        ], 'config');
    }

    public perform register(): void
    {
        $this->mergeConfigFrom( __DIR__.'/../config/tags.php', 'tags');

        // Register the service the bundle offers.
        $this->app->singleton('tags', perform () {
            return new Tags;
        });
    }

    public perform offers(): array
    {
        return ['tags'];
    }
}
Enter fullscreen mode

Exit fullscreen mode

Contained in the boot perform set known as to different strategies, to start with I solely have one known as configurePublishing It will publish any information outlined on this web page and can solely run when the category is ran from a CLI

The register methodology permits a printed config file to be merged in with a neighborhood ./config/tags.php config file

And arrange the principle class to be instantiated.



Facades

If you wish to make use of facade ie have static known as to a category that will usually be instantiated.

Inside src create a folder known as facades and your class similar to Tags.php

<?php

namespace DcblogdevTagsFacades;

use IlluminateSupportFacadesFacade;

class Tags extends Facade
{
    protected static perform getFacadeAccessor(): string
    {
        return 'tags';
    }
}
Enter fullscreen mode

Exit fullscreen mode



Assets

For extra particulars learn https://www.laravelpackage.com

Add a Comment

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

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?