<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های محمد علوی</title><link>https://virgool.ir/feed/@mohammad.alavi</link><description>توسعه دهنده وب فول استک (لاراول, ویو)</description><language>fa</language><pubDate>2026-11-10 22:14:17</pubDate><image><url>https://files.virgool.ir/upload/users/182526/avatar/WhuPSD.png</url><title>محمد علوی</title><link>https://virgool.ir/@mohammad.alavi</link></image><item><title>لود کردن روت های Vue از پوشه های مختلف</title><link>https://virgool.ir/@mohammad.alavi/dynamically-load-vue-routes-from-different-directories-lhva5p2rpuyg</link><description>نکته: من به شدت پیشنهاد میکنم نسخه اصلی مقاله به زبان انگلیسی رو بخونید.مدتی پیش که در تلاش برای پیاده سازی یک ساختار پوشه بندی مقیاس پذیر برای پروژه های Vue بودم مجبور به پیدا کردن راه حلی برای برای لود کردن فایل های route از پوشه های مختلف شدم.معمولا ما همه روت هامون رو در یک فایل به شکل زیر تعریف می کنیم:const routes = [&#xA;  { path: &#39;/foo&#39;, component: Foo },&#xA;  { path: &#39;/bar&#39;, component: Bar },&#xA;  // and so on...&#xA;]const router = new VueRouter({&#xA;  routes // short for `routes: routes`&#xA;})ممکن است این روش برای پروژه های کوچک مناسب باشد ولی وقتی که پروژه شما بزرگتر شد، فایل  روت شما هم به نسبت بزرگ تر و کم کم نگهداری آن هم سخت تر می شود.برای مثال فکر کنیم این ساختار پروژه ما هست:/src&#xA;  /modules&#xA;    /auth&#xA;    /dashboard&#xA;         /components&#xA;               /pages&#xA;               /routes&#xA;                     index.js  &#xA;  /store  &#xA;   /home&#xA;   /profile&#xA;   /...&#xA;حالا نگاهی به محتوای فایل src/modules/dashboard/routes/index.js می اندازیم:export default [&#xA;  {&#xA;    path: &#39;/dashboard&#39;,&#xA;    name: &#39;dashboard&#39;,&#xA;    component: DashboardPage,&#xA;  }&#xA;]در این فایل ما فقط روت های مرتبط با داشبورد (پوشه ای که فایل در آن قرار دارد) را تعریف می کنیم. حالا سوال اینجاست که چگونه میتوانیم این روت ها را رجیستر کنیم به طوری که اَپ ما بتواند آنها را تشخیص بدهد؟متوانیم آنها را به طور داینامیک به صورت زیر با router رجیستر کنیم:import Vue from &#39;vue&#39;&#xA;import VueRouter from &#39;vue-router&#39;&#xA;&#xA;Vue.use(VueRouter)&#xA;&#xA;// Define base routes here&#xA;const baseRoutes = [&#xA;  {&#xA;    path: &#39;/&#39;,&#xA;    name: &#39;index&#39;,&#xA;    redirect: { name: &#39;home&#39; }&#xA;  },&#xA;  {&#xA;    path: &#39;*&#39;,&#xA;    redirect: &#39;/404&#39;&#xA;  }&#xA;]&#xA;&#xA;// Import all of the resource routes files.&#xA;function loadRoutes () {&#xA;  const context = require.context(&#39;@/modules&#39;, true, /routes/index.js$/i)&#xA;  return context.keys()&#xA;    .map(context) // import module&#xA;    .map(m =&gt; m.default) // get `default` export from each resolved module&#xA;}&#xA;&#xA;const resourceRoutes = loadRoutes()&#xA;&#xA;resourceRoutes.forEach((route) =&gt; {&#xA;  for (let i = 0; i &lt; route.length; i++) {&#xA;    baseRoutes.push(route[i])&#xA;  }&#xA;})&#xA;&#xA;const router = new VueRouter({&#xA;  mode: &#39;history&#39;,&#xA;  // base: process.env.BASE_URL,&#xA;  // linkActiveClass: &#39;active&#39;,&#xA;  scrollBehavior () {&#xA;    return { x: 0, y: 0 }&#xA;  },&#xA;  routes: baseRoutes&#xA;})&#xA;&#xA;export default routerبگذارید این قسمت از کد, در فانکشن loadRoutes() را بیشتر بررسی کنیم:require.context(‘@/modules’, true, /routes/index.js$/i)در اینجا require.context() یک ماژول context را برمی گرداند که آن ماژول هم یک فانکشن به نام keys دارد که آرایه ای از تمام روت های مطابق با رج اِکسی که نوشته ایم را برمی گرداند. در آخر آرایه ای که فانکشن loadRoutes() برمی گرداند به شکل زیر است:resourceRoutes = [&#xA;  {&#xA;    0: [&#xA;          {&#xA;            path: &#39;/dashboard&#39;,&#xA;            name: &#39;dashboard&#39;,&#xA;            component: {&#xA;             name: &#39;DashboardPage&#39;,&#xA;             ...&#xA;           }&#xA;        ]&#xA;  },&#xA;  {&#xA;    1: [&#xA;          ...&#xA;        ]&#xA;  },&#xA;{&#xA;    2: [&#xA;          ...&#xA;        ]&#xA;  },&#xA;...&#xA;]سپس ما بر روی تمامی نتایج حقله ای میزنیم و اولین آیتم هر آرایه را برمی گردانیم و آن را به آرایه روت ها اضافه میکنیم.با این روش ما می توانیم اَپلیکیشنی ماژولار و مقیاس پذیر داشته باشیم.مرا در توییتر دنبال کنید Mohammad Alavi</description><category>محمد علوی</category><author>محمد علوی</author><pubDate>Sun, 02 May 2021 19:08:33 +0430</pubDate></item><item><title>توسعه API های مقیاس پذیر و قابل آزمایش با استفاده از Laravel, PHP و Apiato</title><link>https://virgool.ir/@mohammad.alavi/توسعه-api-های-مقیاس-پذیر-و-قابل-آزمایش-با-استفاده-از-laravel-php-و-apiato-yyp0somj0ffh</link><description>همه ما می دانیم که توسعه یک API خوب و قابل اطمینان از ابتدا زمان بر است، بنابراین اگر با من موافقید، ادامه مطلب را بخوانید.نکته: من به شدت پیشنهاد میکنم نسخه اصلی مقاله به زبان انگلیسی رو بخونید.&#xA;هر زمان که می خواهید یک API قابل قبول بسازید حتی اگر از یک فریم ورک خوب مانند Laravel به عنوان نقطه شروع استفاده کنید باید ویژگی های بسیاری مانند موارد زیر را پیاده سازی کنید:یک معماری خوبورژن بندی APIاحراز هویتویژگی های مدیریتی مانند RBAC (کنترل دسترسی مبتنی بر نقش)راه کاری برای تولید مستندات APIمحلی سازیکش کردن داده ها...و بعد از انجام همه این کارها شما تازه به مرحله ای رسیده اید که می توانید اولین خط کد از منطق تجاری API خود را بنویسید. و این چرخه آماده سازی برای توسعه هر پروژه API جدید تکرار می شود و شما خیلی زود از این موضوع خسته می شوید و در نهایت تصمیم می گیرید که پروژه راه انداز (starter) خود را بنویسید یا به دنبال پکیجی از این دسته بگردید.اینجاست که اِپیاتو به داد شما می رسد!اِپیاتو چیست؟اِپیاتو فریم ورکی برای ساخت سیستم های API محور، مقیاس پذیر و قابل آزمایش با PHP است که بر روی فریم ورک Laravel ساخته شده است. اِپیاتو از بهترین معماری ها، ابزارها و قراردادها به روشی کاملاً خلاقانه در جهت ارائه مجموعه ای غنی از ویژگی ها برای توسعه یک سیستم مدرن PHP استفاده می کند.اِپیاتو مستندات (documentation) کامل، با جزییات، اصول، تعاریف و نمونه کد دارد.معماری نرم افزاراِپیاتو با استفاده از الگوی معماری جدید Porto ساخته شده است. Porto یک الگوی معماری مدرن نرم افزاری است که برای کمک به توسعه دهندگان در سازماندهی کد خود به روشی فوق العاده پایدار طراحی شده است. این معماری برای پروژه های بزرگ و طولانی مدت بسیار مفید است، زیرا آنها با گذشت زمان به پیچیدگشان افزوده می شود.ویژگی هادر اینجا برخی از ویژگی های اِپیاتو ارائه شده است:احراز هویت با OAuth2.0 (با استفاده از لاراول پسپورت)کنترل دسترسی مبتنی بر نقش (RBAC)کوئری پارامترهای پیشفرض (جستو جو، مرتب سازی، گروه بندی، فیلتر و...)دارای endpoint های پیشفرض مفید برای مدیریت کاربران، نقش ها/مجوزها، توکن ها و موارد دیگرتولید کننده مستندات API (با استفاده از ApiDocJS)پشتیبانی از CORS (Cross-Origin Resource Sharing) و JSONP (JSON with padding)رمزگذاری/رمزگشایی خودکار ID ها برای جلوگیری از قرار گرفتن ID های واقعی در دسترس عمومقابلیت API Throttling (برای کنترل میزان ترافیک دریافتی و محافظت از سرور شما)پشتیبانی از ریکوئست پارامتر &#34;include&#34; برای بارگذاری روابط تو در توپشتیبانی از کش کردن داده ها (با پاک کردن خودکار در هنگام انجام عملیات های ایجاد، به روز رسانی و حذف)ورژن بندی API در URL یا Headerمدیریت خطاها (اکسپشن) با پاسخهای سفارشی با JSONپشتیبانی از Shallow ETag HTTP Headerمحلی سازی (با استفاده از هدر زبان (language header) به راحتی بین زبانها جابجا شوید)صفحه بندی خودکار داده ها (پیوندهای متا به داده های بعدی و قبلی)ریکویئست/رسپانس مانیتورینگ و کوئری دیباگری دیتابیسپشتیبانی پیشفرض از احراز هویت شبکه های اجتماعی &#34;Google، Facebook، Twitter&#34; (با استفاده از Laravel Socalite)قالب بندی رسپانس های JSON و نتایج صفحه بندی با استفاده از Transformers (با استفاده از Fractal)مدهای کمکی کارآمد برای تست سریعتر و لذت بخش تر (با استفاده از PHPUnit)پشتیبانی از قالب های رسپانس مختلف از جمله JSON API spec v1.0 ، Data Array &amp; Data Cleanتبدیل خودکار تاریخها به قالب ISO در رسپانس هاالگوی معماری نرم افزاری قابل نگهداری و مقیاس پذیر (با استفاده از Porto SAP)دستورات مولد کد، برای تولید عملیات CRUD کامل و سایر دستورات مفید.جداسازی اجزای UI (وب ، API و CLI) (مسیرها، کنترل ها، درخواست ها، تست ها و...)لینک ها:وبسایت Apiatoالگوی معماری نرم افزاری Portoسرور Discordمن را در توییتر دنبال کنید Mohammad Alavi</description><category>محمد علوی</category><author>محمد علوی</author><pubDate>Mon, 26 Apr 2021 12:36:10 +0430</pubDate></item><item><title>رفع مشکل تخصیص حافظه در PHPUnit</title><link>https://virgool.ir/@mohammad.alavi/fix-phpunit-memory-exhaustion-dkyruvwzhwel</link><description>معمولا وقتی پروژه یکمی بزرگ میشه و در جوارش تست ها هم زیاد میشن طبیعتا حافظه ای که برای اجرای اون تست ها هم لازمه زیادتر میشه. اینجاست که مشکل تخصیص حافظه به PHPUnit رخ میده. یه چیزی مثل این:PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 1052672 bytes) in برای رفع این مشکل دو راه پیشنهاد میدم:1. افزایش محدودیت حافظه PHP2. تغییر کانفیگ PHPUnitهر کدوم از این راه ها نقطه قوت و نقطه ضعف خودشون رو دارن.(همه توضیحات بر مبنای ست آپ لوکال خودم، ویندوز 10 و php 7.4.3 هست).افزایش محدودیت حافظه PHP:نقطه قوت: تغییری در سرعت تست ایجاد نمی کنهنقطه ضعف: برای دپلوی بر روی سرور مشکلاتی ایجاد می کنهبرای این کار باید در پوشه نصب PHPتون و در فایل php.ini این رو سرچ کنید:memory_limitنکته: در صورت استفاده از bash میتونید از دستور زیر برای پیدا کردن مسیر نصب PHPتون استفاده کنید:which phpبه صورت پیشفرض حداکثر حافظه ای که یک اسکریپت PHP میتونه استفاده کنه 128M هست که باید اون رو به میزانی که نیاز دارید به صورت زیر افزایش بدید. در اکثر مواقع 2G باید کافی باشه.memory_limit = 2Gاستفاده از این روش مشکل استفاده لوکالمون که زیاد محدودیت حافظه نداریم رو حل می کنه ولی وقتی داریم از سیستم های Continuous Integration مثل TravisCI استفاده می کنیم و همه تست ها در سرور هم اجرا میشن به دلیل اینکه معمولا مقدار حافظه ای که در سرور در دسترسمون هست محدود هست باز هم به همین مشکل بر می خوریم. اینجاست که راه دوم به کمکمون میاد.تغییر کانفیگ PHPUnitنقطه قوت: هم میتونیم در لوکال استفاده کنیم و هم برای دپلوی بر روی سرورنقطه ضعف: کاهش محسوس سرعت اجرای تست هادر فایل phpunit.xml این کانفیگ رو به این شکل اضافه و یا تغییر بدید:processIsolation=&#34;true&#34;این کانفیگ به PHPUnit میگه که هر تست رو به صورت ایزوله انجام بده. اینکار باعث میشه که بعد از اجرا شدن هر تست حافظه مورد استفاده اون آزاد بشه ولی هزینه ای که بابتش پرداخت می کنیم این هست که با فعال کردنش تست ها بسیار کند تر از قبل اجرا میشن. مزیت این روش این هست که میتونیم با خیال راحت تست ها رو دپلوی کنیم بدون اینکه به مشکل کمبود حافظه در سرور بر بخوریم. سرور هم میشینه آروم آروم برای خودش تست ها رو اجرا می کنه ^^ خلاصه اینکه در نوشتن تست فراز و نشیب زیاد هست ولی ارزشش رو داره :) به امید روزی که کد بدون تست نبینیم 3&gt;</description><category>محمد علوی</category><author>محمد علوی</author><pubDate>Wed, 29 Apr 2020 00:12:07 +0430</pubDate></item></channel></rss>