Tự viết một Package trong Laravel 8 (Phần 1)

Written by admin
Posted on Sun, 08/29/2021 - 03:31
28 views

Share Everywhere

Table of contents

Package là là một dạng đóng gói tính năng để thêm vào trong các dự án. Package có thể là bất cứ thứ gì từ việc xử lý ngày giờ như Carbon hay nguyên bộ framework như Laravel. Có rất nhiều loại Package, một số Package thì stand-alone, nghĩa là chúng có thể hoạt động với bất kỳ framework nào miễn là sử dụng chung 1 loại ngôn ngữ (Carbon là một ví dụ), một số Package khác thì lại được tạo ra để sử dụng cho 1 framework nhất định.

Bài hướng dẫn này phần lớn sẽ nói về việc phát triển các Package dành cho Laravel và phiên bản mình sử dụng để Hướng dẫn đó là Laravel 7 (Các phiên bản Laravel khác cũng có thể áp dụng). Và ở bài đầu tiên này mình sẽ đưa ra cấu trúc thư mục và khai báo ban đầu cho một Package.

Cấu trúc thư mục Package cơ bản

Một Package cơ bản sẽ gồm có cấu trúc thư mục như sau:

packages
├── demo
│   ├── configs
│   │   └── demo.php
│   ├── helpers
│   │   └── functions.php
│   ├── migrations
│   ├── resources
│   │   └── assets
│   │   └── lang
│   │   └── views
│   ├── routes
│   │   └── routes.php
│   ├── src
│   │   └── Commands
│   │   └── Http
│   │   |   └── Controllers
│   │   |   └── Middlewares
│   │   └── Models
│   │   └── Providers
│   │   |   └── DemoServiceProvider.php
│   ├── composer.json
│   ├── Readme.md
├── demo2
│   ├── ...

Các thư mục tại Package có công dụng giống như các thư mục cùng tên tại thư mục chính. Thư mục "src" có công dụng như thư mục "\app".

Tên các thư mục không nhất thiết phải đặt giống mình nhưng mình khuyến khích các bạn chỉ thay đổi khi đã hiểu rõ về hướng phát triển Package.

P/S: Các thư mục trên không nhất thiết bắt buộc phải có mà nó còn tùy theo Package đó có dùng hay không. 

Thư mục packages/ đặt cùng cấp với thư mục app/

Khai báo composer.json tại packages

Đây là thư mục quan trọng nhất của một Package. Nó giúp khai báo Package với "composer" từ đó khởi tạo đường dẫn dạng link đến thư mục "\vendor".

Cấu trúc file cơ bản được viết như sau:

{
    // Tên của package dùng để khai báo tại composer.json tại root
    "name": "packages/demo", 
    // Đây là phần mô tả tính năng của Package
    "description": "Mô tả", 
    //
    "type": "library",
    "license": "MIT",
    "minimum-stability": "dev",
    // Khai báo tác giả
    "authors": [
        {
            "name": "Tac gia",
            "email": "[email protected]"
        }
    ],
    // Khai báo các packages khác
    "require": {
        //
    },
    // Khai báo namespace psr-4
    "autoload": {
        "psr-4": {
            "Package\\Demo\\": "src/"
        }
    },
    "extra": {
        "laravel": {
            // Khai báo ServiceProvider của Package
            "providers": [
                "Package\\Demo\\Providers\\DemoServiceProvider"
            ],
            "aliases": {}
        }
    }
}

P/S: Mình đã giải thích các khai báo tại ghi chú và các ghi chú này cần xóa đi khi chạy để tránh gây lỗi.

Khởi tạo ServiceProvider của Package

ServiceProvider là điểm kết nối giữa package của bạn và Laravel. Một ServiceProvider chịu trách nhiệm kết nối các thành phần vào trong container của Laravel và thông báo cho Laravel vị trí để load các tài nguyên của package như views, config, helpers,...

Một ServiceProvider kế thừa từ class "Illuminate\Support\ServiceProvider" và chứa hai phương thức chính là register và boot.

Một ServiceProvider cơ bản có cấu trúc như sau:

<?php

    namespace Package\Demo\Providers;
    
    use Illuminate\Support\Facades\File;
    use Illuminate\Support\Facades\Log;
    use Illuminate\Support\ServiceProvider;
    use Illuminate\Support\Facades\Schema;

    class DemoServiceProvider extends ServiceProvider
    {

        /**
        * Register bindings in the container.
        */
        public function register()
        {
            //
        }

        public function boot()
        {
            //
        }

    }

Khai báo package tại composer.json tại thư mục gốc

Chúng ta sẽ khai báo "name" của Package tại "require" và khai báo thư mục chứa Package tại "repositories".

{
    ...
    "require": {
        ...
        "package/demo": "dev-master"
    },
    ...
    "repositories": [
        {
            "type": "path",
            "url": "./packages/*"
        }
    ]
}

Kiểm thử Package

B1: Khởi chạy "composer update" để composer nạp "package/demo" vào vendor (Chỉ cần chạy 1 lần khi khai báo package, sau khi khai báo thì mỗi thay đổi tại package sẽ tự động được update vào thư mục tại vendor)

B2: Cập nhật lại ServiceProvider để kiểm tra xem package đã được update thành công hay chưa:

...
public function boot()
{
    dd('Kiểm tra Package');
}
...

B3: Refresh (F5) lại trang nếu hiện ra đòng chữ "Kiểm tra Package" thì nghĩa là Package của bạn đã được chạy thành công.

Tổng kết

Tổ chức theo dạng Package/Module là một dạng phát triển khá hay giúp chúng ta có thể sử dụng được những Module được dựng sẵn mà mất rất ít công sức, dễ dàng duy trì và phát triển, đặc biệt PHỤ THUỘC ÍT VÀO LARAVEL cũng như dễ dàng CẬP NHẬT ĐƯỢC PHIÊN BẢN nếu như laravel lên bản 8 hay 9.

Download source mẫu

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
3 + 7 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
Profile picture for user admin
Câu nói tâm đắc: “Điều tuyệt với nhất trong cuộc sống là làm được những việc mà người khác tin là không thể!”