Azis Hapidin
Membuat Package Laravel Sendiri dan Publish ke Packagist

Pembukaan

Apa itu Laravel Package

Ketika membangun sebuah aplikasi apalagi dengan skala menengah keatas, sangat sulit jika kita harus menulis semua kode dari 0 — selesai. Selain akan memakan banyak waktu, juga kita akan sangat kesulitan maintenance karena kode yang kita tulis sudah terlalu banyak.

Untuk itu maka ketika membuat sebuah project para developer biasanya memisahkan beberapa bagian menjadi sebuah package tersendiri, manfaatnya adalah agar ketika suatu saat membutuhkan fungsi tersebut tinggal pakai saja package tadi, agar tidak melakukan pekerjaan yang sama secara berulang-ulang.

Jika kita cek di dokumentasi Laravel, kita akan menemuka penjelasan bahwa: “ Packages are the primary way of adding functionality to Laravel. “. Jadi kurang lebih package ini merupakan sekumpulan class atau fungsi yang bisa kita gunakan berkali-kali (reusable) untuk membantu proses development aplikasi berbasis Laravel.

Setelah package selesai dibuat dan berjalan lancar, kita bisa memutuskan apakah package tersebut mau tetap hanya digunakan oleh internal perusahaan/pribadi atau di-publish untuk dijadikan Open Source. Rugi dong kita yang bikin orang lain yang pake? Enggak juga sih, faktanya bukankah sebagian besar pekerjaan kita sekarang juga dibantu oleh library/package buatan orang lain? Selain itu, dengan menjadikan sebuah package Open Source maka ada kemungkinan orang lain akan ikut contribute ke package yang kita buat tadi. Seperti package azishapidin/indoregion, awalnya cuman iseng-iseng buat personal project aja, ternyata ditengah-tengah ada aja yang ikut contribute.

Beberapa package Laravel yang sangat sering digunakan antara lain: Laravel Debugbar, Laravel Socialite, Laravel Mix, dan masih banyak lagi.

Di Laravel sendiri, manajemen package akan dibantu oleh Dependency Manager bernama Composer, bahkan untuk install framework Laravel sendiri kita harus pake Composer.

Kenapa harus dibuat Package

Pertama, seperti yang disebutkan diatas, agar kita tidak melakukan pekerjaan berulang/repetitif. Jika kode tersebut hanya digunakan pada 1 project mungkin masih oke, tapi jika ternyata ada beberapa project yang kita atau team kerjakan dan didalamnya ada bagian-bagian yang memiliki fungsi yang sama maka kita akan cukup kerepotan dalam menulis ulang kodenya.

Kan tinggal copas aja code-nya?

Oke, masuk ke alasan kedua, misal pada sebuah project kita sudah buat kode untuk integrasi dengan sebuah aplikasi pihak ketiga, beberapa bulan kemudian ternyata project baru kita juga butuh module tersebut, akhirnya kita copas dan di sesuaikan dengan project baru kita. Ditengah-tengah ternyata kita menemukan beberapa bug dan celah keamanan. Akrinya mau tidak mau kita update satu per satu project tadi. Malesin sekali, bandingkan jika module tadi kita jadikan package, maka yang harus kita lakukan adalah update package-nya saja tanpa perlu update core project.

Prasyarat

Sebelum melanjutkan tutorial ini, akan lebih bagus jika temen-temen sudah:

  • Punya dasar PHP yang cukup, minimal faham tentang konsep OOP.
  • Memahami basic Laravel dan bagaimana cara kerja Laravel.
  • Sudah terinstall Composer di komputer teman-teman.
  • Sudah terinstall GIT di komputer teman-teman + paham basic GIT.

Membuat Package

Perencanaan

Pada tutorial kita akan membuat sebuah package kalkulator yang terdiri dari 2 class yaitu: BasicCalculator dan AdvanceCalculator yang masing-masing berisi 2 static method.

Isi dari package ini dibuat sesederhana mungkin agar kita bisa fokus ke step by step bagaimana proses pembuatan package-nya.

Siapkan Project Laravel

Oke pertama, kita siapkan project Laravel, jika belum ada bisa dengan menjalankan perintah dibawah:

composer create-project laravel/laravel belajarbikinpackage

Setelah selesai maka kita akan mendapat 1 project fresh Laravel dengan struktur kurang lebih seperti ini:

Buat Direktori untuk Packages

Selanjutkanya kita buat direktori packages pada direktori utama project Laravel kita. Kemudian di dalam packages tersebut kita buat direktori package yang kita akan buat dengan format: namavendor/namapackage. Jadi jika nama vendor-nya adalah azishapidin dan nama package-nya adalah kalkulator, maka strukturnya akan seperti ini:

Nantinya semua source code package kita akan disimpan pada folder kalkulator tersebut.

Buat file Composer untuk Package

Selanjutnya kita harus membuat file composer.json pada direktori kalkulator tadi dengan menjalankan composer init, silahkan diisi sesuai keinginan teman-teman.

Perintah diatas akan menghasilkan file composer.json seperti ini:

{
    "name": "azishapidin/kalkulator",
    "description": "Disini deskripsi package",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Azis Hapidin",
            "email": "[email protected]"
        }
    ],
    "require": {}
}

Selanjutnya secara manual kita harus menambahkan script autoload dibawah pada file composer.json yang sudah kita buat diatas:

"autoload": {
    "psr-4": {
        "AzisHapidin\\Kalkulator\\": "src/"
    }
}

Script diatas berfungsi untuk memberitahu composer untuk melakukan autoloading pada direktori src (akan kita buat di bagian selanjutnya), sehingga kita tidak perlu lagi secara manual melakukan include atau require. Setelah diubah, maka file composer.json tadi kurang lebih menjadi seperti ini:

{
    "name": "azishapidin/kalkulator",
    "description": "Disini deskripsi package",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Azis Hapidin",
            "email": "[email protected]"
        }
    ],
    "require": {},
    "autoload": {
        "psr-4": {
            "AzisHapidin\\Kalkulator\\": "src/" 
        } 
    }
}

Sebagai sedikit bocoran, AzisHapidin\Kalkulator\ diatas akan menjadi namespace untuk package yang kita buat, jadi nanti ketika kita ingin import sebuah kelas pada package bisa dengan kode seperti ini:

use AzisHapidin\Kalkulator\NamaKelas;

Isi Package

Oke seperti dibahas dibagian sebelumnya, pada tutorial ini kita akan membuat 2 class yaitu class BasicCalculator dan AdvanceCalculator. Pertama kita buat dulu folder src pada folder kalkulator, kemudian pada folder src tersebut kita buat 2 file dibawah:

BasicCalculator.php:

<?php
 
namespace AzisHapidin\Kalkulator;
 
/**
 * Basic Calculator.
 * 
 */
class BasicCalculator
{
    /**
     * Menjumlahkan semua data dalam sebuah array.
     *
     * @param array $data
     * @return integer
     */
    public static function add(array $data)
    {
        return array_sum($data);
    }
 
    /**
     * Mengalikan semua data dalam sebuah array.
     *
     * @param array $data
     * @return integer
     */
    public static function multiply(array $data)
    {
        return array_product($data);
    }
}

AdvanceCalculator.php:

<?php
 
namespace AzisHapidin\Kalkulator;
 
/**
 * Advance Calculator.
 * 
 */
class AdvanceCalculator
{
    /**
     * Convert dari integer/desimal ke biner.
     *
     * @param integer $number
     * @return string
     */
    public static function decimalToBinary(int $number)
    {
        return decbin($number);
    }
 
    /**
     * Convert dari Biner ke Decimal.
     *
     * @param string $string
     * @return float
     */
    public static function binaryToDecimal(string $string)
    {
        return bindec($string);
    }
}

Jadi sekarang strukturnya kurang lebih menjadi seperti ini:

Testing

Sebelum ngetes, karena package kita masih berada di direktori packages, kita tambahkan dulu beberapa baris pada file composer.json di project laravel kita (bukan file composer.json yang package). Pada bagian psr-4 di autoload tambahkan "AzisHapidin\Kalkulator\": "packages/azishapidin/kalkulator/src". Kurang lebih jadinya seperti ini (perhatikan baris ke 7):

{
    "name": "laravel/laravel",
    // Kode lain
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "AzisHapidin\\Kalkulator\\": "packages/azishapidin/kalkulator/src"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    // Kode lain
}

Setelah itu silahkan jalankan: composer dump-autoload, selanjutnya untuk mengetes class yang ada di package diatas cara paling mudah adalah kita panggil di route. Pada routes/web.php silahkan tambahkan ini:

<?php

// Route lain
 
Route::get('/testing', function () {
 
    $array = [2, 89, 99, 150, 89, 64, 39];
    echo implode(' + ', $array) . ' = ' . \AzisHapidin\Kalkulator\BasicCalculator::add($array) . '<br>';
 
    $array = [2, 4,8];
    echo implode(' * ', $array) . ' = ' . \AzisHapidin\Kalkulator\BasicCalculator::multiply($array) . '<br>';
 
    $number = rand(10, 100);
    $binary = \AzisHapidin\Kalkulator\AdvanceCalculator::decimalToBinary($number);
    echo $number . ' dalam biner: ' . $binary . '<br>';
 
    $hex = \AzisHapidin\Kalkulator\AdvanceCalculator::binaryToDecimal($binary);
    echo $binary . ' dalam desimal: ' . $hex . '<br>';
    
});

Kemudian kita buka route tersebut via browser:

Yosh, sampai sini berarti package yang kita buat sudah bekerja dengan baik. Jika temen-temen mau test yang lebih simple bisa juga test lewat php artisan tinker seperti dibawah:

Contoh pada tutorial ini hanya contoh kecil saja. Tentu nantinya kasus yang akan dihadapi teman-teman akan jauh lebih rumit dari ini.

Oke selanjutnya kita tinggal..

Publish ke Packagist

Buat Repository Git

Pertama-tama kita harus menyiapkan terlebih dahulu repository Git-nya, untuk project open source biasanya saya pake GitHub. Jadi silahkan teman-teman siapkan sebuah respository ya.

Disini saya sudah menyiapkan repository ini:

Push Kode ke Repository Git

Selanjutnya kita harus push package yang kita buat ke repository tadi, pada direktori package (dalam kasus ini adalah direktori kalkulator) jalankan perintah dibawah:

git init
git remote add origin [email protected]:azishapidin/kalkulator.git
git add .
git commit -m 'initialize'
git push origin master

Silahkan ganti [g](https://azishapidin.com/cdn-cgi/l/email-protection)[email protected]:azishapidin/kalkulator.git dengan remote url repository temen-temen.

Kemudian pastikan bahwa semua kode sudah ada di halaman repository.

Daftar Packagist

Silahkan temen-temen daftar akun di Packagist, jika sudah temen-temen bisa langsung loncat ke bagian berikutnya.

Submit Package

Silahkan masuk ke halaman ini https://packagist.org/packages/submit, pada bagian Repository URL (Git/SVN/HG) silahkan isi url git yang sudah kita buat tadi. Setelah itu silahkan klik Check, jika tidak ada masalah maka akan muncul tombol Submit, langsung klik tombol tersebut.

Sampai disini harusnya package sudah berhasil dipublish di Packagist.

Setting Auto Update dengan Git Hook (Opsional)

Pada screenshot terakhir kita mendapatkan warning:

This package is not auto-updated. Please set up the GitHub Hook for Packagist so that it gets updated whenever you push!

Jika dibiarkan maka Packagist tidak akan tau jika nanti ada update pada package kita. Jadi yang harus kita lakukan adalah setting WebHook pada pengaturan di repository github kita. Jika temen-temen sudah pernah menghubungkan akun GitHub dengan akun Packagist, seharusnya temen-temen tidak lagi melihat pesan ini karena sudah di setting secara otomatis.

Pada halaman repository di GitHub, silahkan masuk ke halaman Settings -> Webhooks -> Add Webhook kemudian isi seperti dibawah:

  • Pada field Payload URL https://packagist.org/api/github?username=azishapidin, silahkan ganti azishapidin dengan username Packagist teman-teman.
  • Pada field Secret silahkan isi dengan API Token akun Packagist teman-teman, cek disini https://packagist.org/profile/.

Setelah itu klik Add webhook, sampai sini jika tidak ada masalah maka warning tadi harusnya sudah hilang, GitHub akan otomatis mengirimkan Hook ke Packagist ketika ada push (agar di Packagist ikut terupdate).

Coba Install Package pake Composer

Selanjutnya mari kita coba bagian akhir, kita test install pake Composer package yang sudah kita buat. Untuk memastikan bahwa package bekerja dengan baik, saya sarankan coba install di project yang berbeda dengan project sebelumnya.

Silahkan coba-coba class pada package yang kita buat tadi, jika tidak ada masalah harusnya sekarang sudah bisa digunakan.

Penutup

Kesimpulan

Untuk membuat package laravel ini sama seperti membuat class PHP pada umumnya, tinggal atur-atur file composer.json dan beberapa konfigurasi di dalamnya. Sedangkan untuk publish package-nya, cukup dengan membuat repository Git lalu daftarkan ke Packagist.

Selanjutnya Apa?

Sebetulnya tutorial diatas adalah tutorial untuk membuat Package Composer biasa, cara diatas juga bisa coba teman-teman terapkan pada framework lain atau PHP Native (asalakan sudah pake Composer).

Untuk menyelami hal-hal lain seperti Package Discovery, ServicerProvider, Facade dan hal lainnya teman-teman bisa coba baca-baca di https://laravel.com/docs/7.x/packages atau bisa coba cari-cari referensi lain di internet. Atau jika temen-temen banyak yang berminat bisa juga saya buatkan tutorialnya diblog ini.

Sekian tutorial kali ini, semoga bermanfaat, terima kasih.
Jika ada yang perlu di diskusikan ditunggu di kolom komentar 🙂

Referensi:

  1. https://ajaro.id/blog/2019/06/11/tutorial-membuat-php-package-sendiri-bagian-1/
  2. https://medium.com/simplex-internet-blog/build-your-own-laravel-package-in-10-minutes-using-composer-867e8ef875dd
  3. https://devdojo.com/tutorials/how-to-create-a-laravel-package
  4. https://pusher.com/tutorials/build-laravel-packages
  5. https://pusher.com/tutorials/publish-laravel-packagist