اصول ساخت پکیج‌های لاراول

ترجمه و تالیف : رضا جمال زاده
تاریخ انتشار : 01 مهر 98
خواندن در 5 دقیقه
دسته بندی ها : لاراول

نوشتن پکیج برای لاراول کار ساده‌ای نیست، به خصوص اگر شما بخواهید یک پکیج خوب و کارآمد بنویسید. در این مقاله قصد داریم که مفاهیم اساسی برای ساخت پکیج‌های لاراول را توضیح دهیم همچنین ما می‌خواهیم برخی سوالات متداول در این زمینه را پوشش دهیم. در این مقاله مطالب مستند و غیر مستند و همچنین برخی از تجربیات خودمان در این زمینه را شرح خواهیم داد.

اصول ساخت پکیج‌های لاراول

 چه نیازی به نوشتن پکیج داریم؟ اول از همه ما باید دلایل مفید بودن پکیج‌ها را متوجه شویم. توسعه پکیج‌ها فواید خیلی زیادی دارد اما در این‌جا ما به توضیح دو مورد از آن‌ها می‌پردازیم:

1-نوشتن پکیج به این معناست که شما می‌توانید کدهایی که می‌نویسید را بارها و بارها و در موقعیت‌های مختلف استفاده کنید، همچنین برای نوشتن یک پکیج مناسب شما نیاز به یک طرح ، توسعه ، آزمایش ، رفع اشکالات و سپس طرح دوباره و همچنین توسعه دوباره خواهید داشت. این کار باعث می‌شود که شما دید وسیع‌تری پیدا کنید و با انجام تمرین زیاد و بازنگری کدهای خود، کمک خواهد کرد که شما کدهای واضح‌تر و تمیزتری بنویسید.

2-از سوی دیگر، نوشتن پکیج کمک فراوانی به دنیای اُپن سورس(منبع آزاد) می‌کند. تصور کنید که در هنگام نوشتن پروژه خود با لاراول با کمک این پکیج‌ها چقدر از زمان شما صرفه‌ جویی می‌شود، شاید پکیج شما باعث صرفه جویی در زمان کدنویسی دیگران شود و یا شاید دیگران پکیجی دارند که باعث یادگیری چیزهای زیادی برای شما می‌شود. در هر صورت این یک ارتباط دو طرفه و به طور دقیق‌تر یک معامله دو سر سود است.

آماده کردن مقدمات توسعه پکیج

 در ابتدا بیاید در مورد ساختار پوشه بندی پکیج صحبت کنیم. اکیداً توصیه می‌شود که از نام‌های که لاراول ارائه می‌دهد استفاده کنید، همچنین در این‌جا ما کنترلرها و مدل‌ها را در پوشه src قرار می‌دهیم. 

| resources/
| tests/
| config/
| database/
| src/
| .gitignore
| CHANGELOG.md
| README.md
| phpunit.xml
| composer.json
| LICENSE

مشابه اپلیکیشن لاراول در پوشه‌ی resource  فایل‌های view و فایل‌های js  و css مورد نیاز خود را ذخیره می‌کنیم. ما از پوشه‌ test برای نگهداری واحدها و ویژگی‌های آزمایشی پکیج خود استفاده می‌کنید. در ادامه از پوشه‌ی config برای قرار دادن فایل کانفیگ خود استفاده می‌کنیم. ما migrationها را در پوشه دیتابیس قرار می‌دهیم، در پوشه src هر چیزی را که قرار می‌دهیم، تحت namespace پکیج خود نگهداری می‌کنیم مانند: serviceprovider، مدل‌ها ، کنترلرها ، middlewares ، jobs ، commands و هر چیز دیگری که در پوشه‌ی app اپلیکیشن ما قرار دارد، به عبارتی دیگر در پکیج نویسی به جای استفاده از پوشه‌ی app به عنوان پوشه‌‌ای برای فایل‌های اصلی ما از پوشه‌یsrc  استفاده می‌کنیم.

 در ادامه بیاید به فایل composer.json بپردازیم. در این فایل ما پارامترهای اساسی پکیج خود را تعریف می‌کنیم، لیست کامل این پارامترها را در اینجا می‌توانید مشاهده کنید، اما در این مقاله ما مثالی از یک فایل اساسی ‌JSON را آورده‌ایم:

{
    "name": "thepinecode/package-name",
    "description": "This is the description of the package.",
    "type": "project",
    "license": "MIT",
    "authors": [{...}, {...}],
    "autoload": {
        "psr-4": {
            "Pine\\Package\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Pine\\Package\\Tests\\": "tests/"
        }
    },
    "require": {...},
    "require-dev": {...},
    "extra": {
        "laravel": {
            "providers": [
                "Pine\\Package\\PackageServiceProvider"
            ]
        },
        "branch-alias": {
            "dev-master": "1.0-dev"
        }
    }
}

در بالا، ما موارد خیلی اساسی برای فایل composer.json تنظیم کردیم. در ادامه ما برخی دیگر از مواردی که در هنگام توسعه استفاده می‌کنیم را قرار خواهیم داد. همانطور که دیدید در قسمت extra ما یک شیء لاراول و همچنین یک آرایه providers در درون آن قرار داریم. ما می‌توانید در همین قسمت service provider خود را ارائه دهیم و نیازی به تعریف آن در فایل app.php موجود در پوشه کانفیگ خود نداریم، زیرا با این کار لاراول به صورت اتوماتیک آن را پیدا می‌کند.

تنظیم محیط توسعه 

قبل از هر چیز یک پروژه جدید در لاراول ایجاد می‌کنیم. بهترین روش برای توسعه پکیج، طراحی آن مانند پکیج‌های موجود در لاراول است. ما می‌توانیم این کار را از طریق کامپوزر انجام دهیم(به همین دلیل است که تنظیم کامپوزر پکیج اهمیت فراوانی دارد). بنابراین ما می‌توانیم مخازن(repositories) پکیج خود را در فایل composer.json اپلیکیشن تعریف کنیم و پکیج از پیش آماده را به عنوان یک وابستگی(dependency) قرار دهیم. بخش repositories به کامپوزر اعلام می‌کند که یک پکیج به صورت نصب محلی را  لینک ‌کند. با استفاده از این روش، می‌توانیم بدون نیاز به بروز رسانی Composer در هر زمانی که تغییری ایجاد می‌شود عملیات تست را انجام دهیم و پکیج را به صورت محلی تست کنیم.

...
"require": {
    "php": "^7.1.3",
    "fideloper/proxy": "^4.0",
    "laravel/framework": "5.7.*",
    "laravel/tinker": "^1.0",
    "thepinecode/package-name": "~1.0-dev"
},
...
"repositories": {
    "package-name": {
        "type": "path",
        "url": "packages/thepinecode/package-name",
        "options": {
            "symlink": true
        }
    }
},
...

در اینجا باید به دو نکته توجه کنیم:

 1-ما یک شیء repositories را تعریف کردیم و در داخل آن یک پکیج محلی و جزئیات آن را قرار داده‌ایم، کامپوزر  pathرا می‌خواند سپس می‌تواند آن را به عنوان یک پکیج عادی تشخیص دهد. در قسمت require ما نام پکیج و همچنین در قسمت extra  ورژن پکیج را تعریف می‌کند.

2- در صورتی که همه کارها را به درستی انجام دادیم می‌توانیم composer install در command خود اجرا کنیم. در این صورت تمام نیازمندی‌های پکیج‌ها از جمله نیازمندی‌های پکیج خود را فراخوانی می‌کنیم. از اینجا به بعد همه چیز آماده است و ما می‌توانیم پکیج خود را در محیط لوکال توسعه دهیم و کار توسعه پکیج با استفاده از اپلیکیشن لاراول را انجام دهیم.

پیکربندی (کانفیگ کردن) پکیج

 در اغلب اوقات ما ممکن است فایل پیکربندی را همراه پکیج خود ارائه دهیم و بر اساس ساختار لاراول ما می‌توانیم فایل پیکربندی را در پوشه src/config قرار دهیم. نام این فایل را باید طوری انتخاب کنیم که نشان دهنده نام پکیج باشد(انتخاب نام خود پکیج پیشنهاد می‌شود) این کار باعث آسان‌تر شدن پیکربندی در اپلیکیشن‌های گسترده‌تر می‌شود. برای ادغام پیکربندی به طور اُتوماتیک با پیکربندی اپلیکیشن، ما باید در متد register() در قسمت service provider پکیج کد زیر را اضافه کنید:

$this->mergeConfigFrom(__DIR__.'/../config/package-name.php', 'package-name');

حال سوال اینجاست، اگر کاربران نیاز به تغییر برخی از آپشن‌های پکیج داشته باشند چه کاری باید انجام دهند؟ در ادامه ما باید پیکربندی پکیج(فایل کانفیگ) را در دسترس کاربران قرار دهید. برای فایل‌های blade قالب همین مشکل را داریم که خوشبختانه به سادگی می‌توانید این مشکل را با دادن اجازه به کاربران برای publishکردن -و یا در صورت تمایل کپی کردن- فایل‌های قابل تغییر و بازنگری پکیج در اپلیکیشن لاراول حل کنید.

در متد boot() در قسمت service provider ما می‌توانیم از متد publish() برای تعریف فایل‌هایی که کاربر ممکن است تغییر داده و یا بازنویسی کند استفاده کنید.

$this->publishes([
    // Config
    __DIR__.'/../config/package-name.php' => config_path('package-name.php'),
    
    // Views
    __DIR__.'/../resources/views/view-1.blade.php' => resource_path('views/vendor/package/view-1.blade.php'),
    __DIR__.'/../resources/views/view-2.blade.php' => resource_path('views/vendor/package/view-2.blade.php'),
    
    // Translations
    __DIR__.'/../resources/lang' => resource_path('lang/vendor/package-name'),
    
    // Assets
    __DIR__.'/../resources/js' => public_path('vendor/package-name/js'),
    __DIR__.'/../resources/css' => public_path('vendor/package-name/css'),
], 'package-name');

با اجرای دستور php artisan vendor:publish ––tag=package-name در command  فایل‌های داده شده، در مسیرهای مشخصی از اپلیکیشن کپی می‌شوند. از این‌جا به بعد این فایل‌ها قابل ویرایش هستند و لاراول از نسخه تغییر یافته آن‌ها استفاده خواهد کرد.

Viewهای پکیج

همانطور که در بالا ذکر کردیم ما می‌توانیم views  را در پکیج خود قرار دهیم. استفاده از آن‌ها در پکیج می‌تواند خیلی مفید باشد. پیش از این در مورد publishکردن views ها به وسیله فایل config صحبت کردیم، در ادامه بیاید در مورد چگونگی ارائه فایل‌های view بدون publishکردن آن‌ها صحبت کنیم. در متد boot() از

 service provider ما می‌توانیم کد زیر را قرار دهید:

$this->loadViewsFrom(__DIR__.'/../resources/views', 'package-name');

از این مرحله، ما می‌توانیم از فایل‌های blade به سادگی استفاده کنیم:

@include (‘package-name::view-1’)

 بنابراین همانطور که دیدید ما نام پکیج (package-name) را به عنوان پیشوند قبل از نام فایل قرار می‌دهیم.

روت‌های پکیج

ما می‌توانیم در پکیج خود از روت‌ها استفاده کنیم. تصور کنید، اگر شما پکیجی ساخته‌اید که در آن نیاز به مدیریت ورودی های webhook دارید در این صورت برای مدیریت آن چه در پشت صحنه اتفاق می‌افتد شما نیاز به یک نقطه پایان و یا یک منطق دارید. همچنین ما می‌توانیم کنترلر و middleware ایجاد کنیم و آن‌ها را در پکیج قرار دهیم. این بدین معناست که اگر ما یک روت تعریف کنیم به سادگی می‌توانیم آن را به کنترلر پکیج ارجاع دهید و یا از middleware پکیج خود استفاده کنیم.

اکیداً توصیه می‌شود که از ساختار استاندارد پوشه بندی لاراول در پکیج خود استفاده کنید. بدین معنا که کنترلرهای خود را در پوشه src/Http/Controllers و middlewareهای خود را در پوشه‌ی src/Http/Middleware قرار دهید.

برای اضافه کردن روت‌ها در اپلیکیشن خود ما نیاز داریم که فایل روت پکیج خود را در متد boot() فایل service provider لود کنیم:

$this->loadRoutesFrom(__DIR__.'/../routes/web.php');

 ما می‌توانیم روت‌های خود را تعرف کرده و همچنین از این روت‌ها مشابه اپلیکیشن معمولی لاراول استفاده کنیم.

Migrationهای پکیج

اغلب مواقع ما مدل‌های خودمان را همراه پکیج قرار می‌دهیم. این بدین معناست که ما ماگریشن‌های خود را نیز همراه پکیج می‌آوریم. لود کردن ماگریشن‌ها در اپلیکیشن به سادگی لود کردن روت‌ها است. تنها نیاز داریم که یک خط را در متد boot() خود اضافه کنید پس از آن همه چیز آماده است:

$this->loadMigrationsFrom(__DIR__.'/../database/migrations');

وقتی که شما دستور php artisan migrate در command اجرا می‌کنید لاراول به طور خودکار تمام ماگریشن‌های پکیج را ماگریت می‌کند، بدون نیاز به هیچ‌گونه تلاش و یا کد اضافه‌ای.

ترجمه‌های پکیج

  Localization(بومی سازی) می‌تواند در اپلیکیشن لاراول به صورت مکرر مورد نیاز باشد. مشابه فایل های view ما می‌توانید به سادگی از متد boot() ، فایل‌های مورد نظر را  publishکرده و آن‌ها را لود کنید. ما پیش‌تر در مورد publish صحبت کردیم پس بیاید نگاهی به چگونگی لود translation بیندازیم:

$this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'package-name');

برای استفاده از آن‌ها ما نیاز به پیشوند کلید ترجمه داریم همانطور که در view این کار را انجام داد. @lang (‘package-name::messages.failed’) 

Commands در پکیج

برای تعریف کردن هر command در پکیج خود ما یک متد اختصاصی داریم که می‌توانیم از آن در متد boot() خود استفاده کنیم:

$this->commands([
    Commands/CommandOne::class,
    Commands/CommandTwo::class,
]);

از این مرحله به بعد، ما می‌توانیم از commandهای پکیج خود با استفاده از artisan و نام اختصاصی آن‌ها، که قبلا تعریف کرده‌ایم، استفاده کنیم.

تست کردن پکیج

 در هر موقعیتی تست کردن یک عمل حیاتی است. مخصوصاً وقتی چیزی بنویسید که دیگران بخواهند از آن استفاده کنند. شما نیاز دارید مطمئن شوید از این که کد شما در اپلیکیشن‌های دیگران در حالت‌های مختلف بدون مشکل اجرا می‌شود.

خوشبختانه، ما می‌توانیم به سادگی در کامپوزر پکیج خود orchestral/testbench را صدا بزنیم، همچنین برای اضافه کردن وابستگی‌های توسعه پکیج ما می‌توانیم 

composer require orchestral/testbench -–dev

را در command خود اجرا کنیم.

نتیجه گیری

 در این مقاله ما فقط در مورد اصول اولیه ساخت پکیج صحبت کردیم. توجه کنید که توسعه پکیج یک مبحث گسترده و کمی پیچیده است اما در صورت استفاده از آن می‌توانید به سادگی هر چیزی که می‌خواهید را پیاده سازی کنید.

در بحث ساخت پکیج، شاید شما یک راه حل برای مشکلی پیدا کنید که دیگران در آن مشکل دارند، چرا راه حل خود را با آن‌ها به اشتراک نگذارید؟ توسعه پکیج کمک بزرگی به دنیای منبع آزاد(اپن سورس) است که به وسیله آن می‌توانید به افراد دیگر چیزهای فراوانی بیاموزید.

 در مقاله‌های دیگر سعی خواهیم کرد تا با ذکر یک مثال عینی به آموزش ساخت پکیج‌ها در لاراول بپردازیم. شما می‌توانید  پکیج‌هایی که فکر می‌کنید آموزش ساخت آن‌ها کاربردی است را در قسمت نظرات کامنت کنید.

منبع

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر لازم است ابتدا وارد سایت شوید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید