Module hóa trong Laravel


Khi làm việc những dự án to bự, chúng ta cần module hóa các chức năng để dễ dàng quản lý, nâng cấp cũng như tái sử dụng chúng.

Module

  • Như các bạn đã biết Laravel xậy dựng MVC với mô hình này bạn sẽ không gặp nhiều vấn đề với các dự án vừa và nhỏ. Nhưng ngày ko đẹp trời nào đó bạn phải maintan dự án to hơn 1 chút lúc đó bạn cảm thấy khó khăn trong việc quản lý code của dự án thì ta phải làm thế nào ?

  • Để giải quyết vấn đề trên mình sẽ giới thiệu cho các bạn mô hình HMVC (Hierarchy - Model - View - Controller). Với mô hình này bạn nhóm code theo chức năng mỗi chức năng sẽ là 1 module. Trong mỗi module là 1 mô hình MVC đầy đủ model, view, controller và cả router. Như vậy việc quản lý code là rất dễ dàng.

Cài đặt & Cấu hình

Ở đây chúng ta hoàn toàn có thể chủ động tạo bằng tay, nhưng rất mất công để tạo các file cũng như folder. Tự động khởi tạo các class và nhiều thứ khác, đồng thời khó quản lý các module.

Mình giới thiệu đến các bạn một thư viện giúp chúng ta thực hiện điều đó, chỉ cần chạy lệnh command.

Composer

composer require nwidart/laravel-modules

Tùy theo phiên bản Laravel mà các bạn cài phiên bản laravel-modules phù hợp

Autoloading

Mặc đinh, các class modules sẽ không tự động load, chúng ta cần khai báo vào file composer.json

{
  "autoload": {
    "psr-4": {
      "App\\": "app/",
      "Modules\\": "Modules/",
  }
}

Sau đó chạy lệnh command:

composer dump-autoload

First Module

Sử dụng script để generate:

php artisan module:make Blog
app/
bootstrap/
vendor/
Modules/
  ├── Blog/
      ├── Assets/
      ├── Config/
      ├── Console/
      ├── Database/
          ├── Migrations/
          ├── Seeders/
      ├── Entities/
      ├── Http/
          ├── Controllers/
          ├── Middleware/
          ├── Requests/
      ├── Providers/
          ├── BlogServiceProvider.php
          ├── RouteServiceProvider.php
      ├── Resources/
          ├── assets/
              ├── js/
                ├── app.js
              ├── sass/
                ├── app.scss
          ├── lang/
          ├── views/
      ├── Routes/
          ├── api.php
          ├── web.php
      ├── Repositories/
      ├── Tests/
      ├── composer.json
      ├── module.json
      ├── package.json
      ├── webpack.mix.js

Sau khi tạo module thành công, file modules_statuses.json tự sinh ra:

{
    "Blog": true
}

File này có chức năng bật tắt các module, set false nếu không muốn sử dụng module Blog

Một module được sinh ra, bạn có thể khai báo và sử dụng nó như 1 ứng dụng laravel thu nhỏ, nó chứa đày đủ tất cả các chứng năng mà 1 laravel project cung cấp.

Vì vậy, bạn cứ thoải mái tung hoành trong thằng module này. Công nghệ nằm trong tay, sức mạnh nằm trong tay.

Chỉ cho các bạn 1 tip: Trong này chúng ta không thể tạo các file (chức năng) bằng lệnh command được. Nhưng không sao, chúng ta vẫn cứ dùng lệnh command để tạo, thì file sau khi được tạo nằng trong folder app, chúng ta cut nó quá module mà các bạn muốn, sau đó đổi namespace từ App -> Modules/... tên của module, và khai báo nó vào trong ServiceProvider của module đó.

Basic usage

Helpers

Laravel-modules cung cấp sẵn cho chúng ta function helper module_path(‘Blog’) trả về đường dẫn đến module Blog
/Users/.../laravel-digging-deeper/Modules/Blog

Ngoài ra các bạn tự tạo cho mình các function helpers khác. Tham khảo thêm ở bài viết trước cách khai báo Ở đây

Compiling Assets

Install && Setup
Khi tạo 1 module mới, đồng thời nó tự sinh nơi chứa các file assets và tệp cấu hình webpack.mix.js, package.json

Để sử dụng, chúng ta cd vào module muốn sử dụng

cd Modules/Blog

và cài đặt các gói cần thiết

npm install

Running Mix
Tạo thư mục này, sau khi code bla bla scss gì gì đó, chúng ta cần build ra file js hoặc css hoặc npm run..

// Run all Mix tasks...
npm run dev

// Run all Mix tasks and minify output...
npm run production

Sau khi tạo tệp được generate, bạn sẽ không biết tên tệp chính xác. Vì vậy, bạn nên sử dụng hàm global mix của Laravel trong view của mình để tải nội dung thích hợp. Hàm mix sẽ tự động xác định tên hiện tại của tệp được tạo:

// Modules/Blog/Resources/views/layouts/master.blade.php

<link rel="stylesheet" href="{{ mix('css/blog.css') }}">

<script src="{{ mix('js/blog.js') }}"></script>

Bạn muốn biết thêm thông tin về Laravel Mix có thể tham khảo: https://laravel.com/docs/mix

Advanced Tools

Artisan commands

module:make
Tạo 1 module mới

php artisan module:make Blog

Có thể tạo nhiều module cùng 1 lúc

php artisan module:make Blog User Admin

Như mình có nói ở trên, các chức năng mà laravel cung cấp như job, event, request, … các bạn có thể dùng lệnh command do laravel cung cấp để generate ra các file đó rồi copy vào module, sau đó đổi namespace. Và cũng có thể dùng command do laravel-modules cung cấp. Thay vì dùng make:event ta dùng module:make-event Blog.
Các hàm make khác cũng tương tự. Các bạn có thể xem các lệnh command bằng cách chạy command

    php artisan list

Chúng ta truyền thêm module vào để nó biết mình tạo cho module nào.

Dùng cách nào cũng được, miễn không có lỗi và chạy thành công nha.

Facade methods

//Get all modules.
Module::all();

// Get all cached modules.

Module::getCached()

// Get ordered modules.
Module::getOrdered();

// Get scanned modules.
Module::scan();

// Find a specific module.
Module::find('name');
// OR
Module::get('name');
// OR
Module::findOrFail('module-name');

// Check the specified module. If it exists, will return true, otherwise false.
Module::has('blog');

// Get all enabled modules.
Module::allEnabled();

// Get count of all modules.
Module::count();

// Get assets path from the specified module.
Module::assetPath('name');

// Get config value from this package.
Module::config('composer.vendor');

// Add a macro to the module repository.
Module::macro('hello', function() {
    echo "I'm a macro";
});

// Call a macro from the module repository.
Module::hello();

// Get all required modules of a module
Module::getRequirements('module name');

Các thành phần khác như ServiceProvider chúng ta khai báo vào đó giống như chúng ta khai báo trong AppServiceProvider.

Kết luận

Thông qua bài viết này mình giới thiệu đến các bạn cách để chúng ta sử dụng module. Thư viện chủ yếu giúp ta tự động generate ra các module 1 cách dễ dàng. Chúng ta hoàn toàn có thể viết ra nó, và không cần phụ thuộc vào thư viện này.

Cái chúng ta quan tâm ở đây là file ModuleServiceProvider trong từng module. Thư viện giúp tự động nạp nhưng file này thông qua file modules_statuses.json thì chúng ta có thể chủ động nạp vào trong file AppServiceProvider hoặc khai báo vào phần providers của config/app.php.

Chỉ cần nắm rõ nguyên lý làm việc của laravel, thì ta có thể làm chủ cái module này.

Nguồn tham khảo:

Rất mong được sự ủng hộ của mọi người để mình có động lực ra những bài viết tiếp theo.
{\__/}
( ~.~ )
/ > ♥️ I LOVE YOU 3000

JUST DO IT!


Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Nguyễn Quang Đạt !
Comments
  TOC