<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های حسام جعفرزاده</title><link>https://virgool.ir/feed/@jafarzadeh.hesam.wm</link><description>به دنبال یادگیری بیشتر - اطلاعات بیشتر در مورد من در: hesij.ir</description><language>fa</language><pubDate>2026-11-10 15:00:54</pubDate><image><url>https://files.virgool.ir/upload/users/53980/avatar/E5nymt.jpeg</url><title>حسام جعفرزاده</title><link>https://virgool.ir/@jafarzadeh.hesam.wm</link></image><item><title>خطای mixed content در لاراول و برطرف کردن آن</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/خطای-mixed-content-در-لاراول-و-برطرف-کردن-آن-h6kxnbbffgbz</link><description>رفع خطای Mixed content در لاراولاگر پروژه‌ی لاراولی را روی حالت production اجرا کرده باشید احتمالا با خطای mixed content مواجه شده اید و زمانی که به این خطا بخورید، فایل‌های  assets پروژه به درستی اجرا نخواهند شد.علت ظاهر شدن این خطا این است که شما از یک منبع امن یا secure (به طور مثال https) تقاضای دريافت یک محتوای نامطمئن یا insecure (مثلا یک درخواست http) را دارید. در این حالت درخواست شما به درستی اجرا نمی‌شود و با این خطا روبه‌رو می‌شوید.همانطور که گفتیم زمانی که این خطا وجود داشته باشد فایل‌های asset به درستی load نمی‌شوند.برای مشاهده‌ ی آموزش رفع این خطا، پیشنهاد می‌کنم مطلب رفع خطای Mixed content در لاراول ۱۰  از وب‌سایت  بنده‌ را مطالعه کنید.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Sat, 28 Oct 2023 22:11:52 +0330</pubDate></item><item><title>هر آنچه که در مورد v-model باید بدانید</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/هر-آنچه-که-در-مورد-v-model-باید-بدانید-lozuqwoisgao</link><description>هر آنچه که در مورد v-model باید بدانیدمقدمهبا دانستن این موضوع شروع می‌کنیم که، v-model یک directive ویو‌جی‌اس هست که ارتباطی ۲ طرفه یا همان two way data binding را، بین template و داده‌ها(Data) ایجاد می‌کند. استفاده‌ی رایج از v-model هنگام کار با فرم‌ها می‌باشد،‌ یعنی زمانی که inputهای یک فرم به داده‌ها(Data) متصل می‌شوند و مقدار آن‌ها را تعیین می‌کنند.‌برای مثال به قطعه کد زیر که از v-model روی یک text input استفاده کرده‌ایم توجه کنید.&lt;template&gt;&#xA;  &lt;div&gt;&#xA;    &lt;input type=&#34;text&#34; v-model=&#34;value&#34; /&gt;&#xA;    &lt;p&gt;Value: {{ value }}&lt;/p&gt;&#xA;  &lt;/div&gt;&#xA;&lt;/template&gt;&#xA;&#xA;&lt;script setup&gt;&#xA;import { ref } from &#39;vue&#39;&#xA;&#xA;const value = ref(&#39;&#39;)&#xA;با اجرای کد فوق متوجه خواهید شد که با اعمال هر تغییر در input مقدار  متغیر value که توسط دایرکتیو v-model به آن متصل(bind) شده است نیز تغییر  می‌کند. این رویداد اشاره به همان مفهوم two way data binding دارد که با  تغییر در input، مقدار متغیر bind شده به آن نیز عوض می‌گردد و بلعکس با  تغییر مقدار value، مقدار نوشته شده درون input نیز تغییر خواهد کرد.تفاوت بین v-model و v-bindگاهی اوقات پیش می‌آید که تازه‌کارها، دایرکتیو v-bind را به جای  v-model استفاده می‌کنند اما در حقیقت این دو با یکدیگر تفاوت دارند و  مهم‌ترین تفاوت بین این دو directive این است که v-bind بر خلاف v-model  ارتباطی ۲ طرفه را ایجاد نمی‌کند. در مثال بالا مفهوم two  way data binding را مشاهده کردید اما اگر در مثال بالا به جای استفاده از  v-model بر روی input، از v-bind استفاده کرده بودیم، در بار نخست، مقدار  value درون input قرار می‌گرفت اما با تغییر مقدار input، مقدار متغیر  value تغییری نمی‌کرد. چون v-bind ارتباطی یک طرفه را  ایجاد می‌کند(بر خلاف v-model). در نگاه نخست ممکن است تفاوت قابل  ملاحظه‌ای نباشد اما باید هنگام انتخاب و استفاده از این دو directive  محتاط عمل کنیم و ببینیم که به کدام نوع ارتباط(یک طرفه یا دو طرفه) نیاز  داریم.اصلاح‌کننده‌های v-modelویو‌جی‌اس  به صورت پیش‌فرض، چند اصلاح‌ کننده (modifiers) را برای کار  با v-model معرفی کرده است که عملکرد v-model را تغییر می‌دهند. اصلاح کننده‌ی layz.به طور پیش‌فرض رفتار v-model به این شکل است که اگر داده‌ای توسط  v-model به یک input متصل کنیم،‌ هر تغییری که در مقدار input بدهیم آن  تغییر بلافاصله بر مقداری که input به آن متصل(bind) است، اعمال می‌شود به  عبارت دیگر می‌توان گفت که v-model مقدار بین داده و input را sync نگه می‌دارد. اما اگر از modifier یا اصلاح کننده‌ی lazy. استفاده کنیم، متغیر متصل شده به input و مقدار درون input زمانی هماهنگ  می‌شوند که تغییر درون input کامل شود و یا به عبارت focus از روی input  برداشته شود.&lt;input type=&#34;text&#34; v-model.lazy=&#34;value&#34; /&gt;در حالت معمولی با نوشتن هر کارکتر درون یک input مقدار متصل شده به آن از طریق v-model، نیز به روزرسانی می‌شود اما هنگامی که از lazy. استفاده می‌کنیم، هر تغییری که درون text input بدهیم زمانی با داده‌ی  متصل شده به آن هماهنگ می‌شود که focus از روی input برداشته شود. این  ویژگی باعث می‌شود تا تعداد دفعاتی که v-model سعی می‌کند داده‌ی متصل به  input را بروز رسانی کند کاهش یابد و این ویژگی در مواردی باعث افزایش و  بهبود عملکرد نیز خواهد شد.ادامه‌ی مطلب را از اینجا مطالعه فرمایید.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Tue, 11 Apr 2023 16:31:59 +0330</pubDate></item><item><title>معرفی فریم‌ورک Vue js</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/معرفی-فریم-ورک-vue-js-kcx2lyezgykb</link><description>لوگوی فریم‌ورک vue jsمعرفی Vue jsویو جی اس (Vue js) یک فریم‌ورکِ متن بازِ زبان برنامه  نویسی جاوا اسکریپت است که به صورت عمده در طراحی وب سایت و در بخش  Front-end  پروژه‌ها مورد استفاده قرار می‌گیرد. این فریم‌ورک‌، یکی از  گزینه‌های محبوب برای توسعه‌ی وب‌سایت می‌باشد و نخستین بار در سال ۲۰۱۴ و   توسط آقای Evan You منتشر شد. تا زمان نوشتن این مطلب، این فریم‌ورک موفق  به کسب ۳۵.۶k ستاره در گیت‌هاب شده است.پروژه‌های vue js براساس CSS, HTML و Javascript ساخته می‌شوند و به  لطف مدل ساختاری این فریم‌ورک، که component based است، پیاده‌سازی پروژه،  بسیار تمیزتر، منسجم‌تر و ساده‌تر می‌گردد.کاربردهای متفاوت Vue jsفریم ورک Vue js بیشترِ نیازهای سمت فرانت‌اند یک پروژه را برطرف می‌سازد، البته باید به  این نکته توجه داشته باشید که امروزه پروژه‌هایی که در بستر وب قرار  می‌گیرند، از لحاظ عملکرد و مقیاس بسیار با یکدیگر متفاوت هستند، از این رو  vue سعی کرده است که یک فریم‌ورک منعطف و سازگار با شرایط باشد، به طوری  که می‌تواند بر اساس نیاز شما، قابلیت‌های متفاوتی از خود نشان دهد.ممکن است که در یک پروژه‌ی HTML معمولی، به صورت مختصر و صرفا جهت اجرای یک منطق جاوا اسکریپتی به شما کمک کند.و یا ممکن است در طراحی یک وب‌سایت تک‌صفحه‌ای یا همان SPA (Single Page Application) نقش ایفا کند.گاهی اوقات سئو وب سایت، برای شما از اهمیت بالایی  برخوردار خواهد بود، پس می‌توانید از قابلیت SSR و یا همان Server Side  Rendering کمک بگیرید و خروجی را به سمت مرورگر ارسال کنید تا از امتیاز  سئوی بهتری برخوردار باشید.خلاصه همانطور که پیش‌تر گفتیم ویو جی اس سعی کرده است تا کاملا منعطف و  سازگار و متناسب با نیاز شما عمل کند، البته علاوه بر آنچه که ذکر کردیم  شما حتی می‌توانید برای توسعه‌ی برنامه‌های Desktop، Mobile و یا حتی خط  فرمان(Command Line) نیز از Vue js استفاده کنید.ادامه‌ی مطلب را در این لینک بخوانید.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Tue, 04 Apr 2023 21:16:40 +0330</pubDate></item><item><title>معرفی مفهوم Top Level Await در ES2020</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/معرفی-مفهوم-top-level-await-در-es2020-crtpevy54bfe</link><description>معرفی مفهوم Top Level Await در ES2020معرفی top level awaitزمانی که برای بار نخست async/await معرفی  شد، استفاده از await خارج از یک async function باعث ایجاد خطا می‌شد. از  این رو زمانی که برنامه‌نویس‌ها نیاز داشتند که از دستور await استفاده  کنند اما این دستور درون یک async function نبود، از الگوی immediately-invoked async function expressions یا IIAFE استفاده می‌کردند.  در ES2020 ویژگی جدید به اسم top level await معرفی  شد که به شما اجازه می‌دهد از دستور await خارج از یک async function  استفاده کنید. در این حالت ماژول همانند یک async function عمل می‌کند. فرض  کنید دو ماژول A , B داریم، که از ویژگی top level await در ماژول A  استفاده کرده‌ایم و در ماژول B، ماژول A را import می‌کنیم. در این حالت  ماژول B منتظر می‌ماند تا ماژول  A به طور کامل load شود سپس به ادامه‌ی  تفسیر کدهای خودش می‌پردازد.  این ویژگی در بسیاری از جهات کد را تمیزتر و  خواناتر می‌کند. بهتر است که کاربرد این ویژگی را با ذکر یک مثال و هنگام  کار با ماژول‌ها بررسی کنیم.ذکر مسئله برای درک کاربرد ویژگی top level awaitبیان مسئلهما در این مطلب با استفاده از یک مثال  کاربرد و مزیت top level await را شرح می‌دهیم. برای ادامه‌ی کار فرض کنید  که قصد داریم اطلاعات کاربران را از یک API دریافت کنیم و آنها را در یک  لیست در صفحه‌ی HTML نشان دهیم. برای این کار ۳ فایل به نام‌های   index.html, app.mjs و user.mjs را ایجاد می‌کنیم. کار هر کدام از این  فایل‌های به شرح زیر می‌باشند:فایل index.html که یک فایل HTML است و از  آن برای نوشتن کد‌های HTML مربوط به نمایش اطلاعات کاربران استفاده می‌کنیم  و در قسمت script این فایل، فایل app.mjs را فراخوانی می‌کنیم.فایل user.mjs که اطلاعات کاربران را از یک API دریافت می‌کند.و فایل app.mjs که ماژول user.mjs را import می‌کند و اطلاعات کاربران را توسط جاوا اسکریپت در فایل index.html وارد می‌کند.ادامه‌ی این مطلب را می‌توانید در پست معرفی مفهوم Top Level Await در ES2020 مطالعه فرمایید.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Fri, 31 Mar 2023 12:44:45 +0330</pubDate></item><item><title>آموزش postgres - بررسی self-join</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/آموزش-postgres-بررسی-self-join-nrzwuujaah7q</link><description>در این مطلب در مورد این یاد می‌گیریم که چجوری با استفاده از self-join یک جدول رو با خودش مقایسه کنیم.قبل از هر چیز توصیه میکنیم که اگر با joinها آشنایی ندارید، نخست آموزش انواع join رو مطالعه بفرمایید.در واقع self-join یک join معمولی است که یک جدول را با خودش join می‌کند. بیشتر اوقات از این join برای اجرای کوئری‌هایی استفاده می‌کنیم که نتایج حالت خوشه‌ای و یا ارث‌بری دارند و یا حتی زمان‌هایی که میخواهیم اطلاعات یک سطر از یک جدول رو با بقیه‌ی سطر‌های همون جدول مقایسه کنیم.در self-join تمام ارجاعات ما به یک جدول است اما برای ایجاد تفاوت باید هر بار برای جدول اسمی جدید در نظر بگیریم (table aliases)، به نحوه‌ی نوشتن توجه کنید:SELECT select_list &#xA;FROM table_name t1 &#xA;INNER JOIN table_name t2&#xA;ON join_predicate;در دستور بالا جدول table_name را، که موقتا آنرا t1 نام گذاری کردیم، به همان جدول table_name که این‌بار موقتا آنرا t2 نام گذاری کردیم inner join زدیم. توجه کنید که ما می‌توانیم دستور بالا را به کمک left join و right join هم بنویسیم.SELECT select_list &#xA;FROM table_name t1&#xA; LEFT JOIN table_name t2&#xA; ON join_predicate;اجازه بدید که آموزش رو با مثال پیش ببریم، قصد داریم تا یک ساختار خوشه‌ای رو با استفاده از self-join پیاده سازی کنیم. فرض کنید که ساختار زیر رو برای یک سازمان داریم:self-joinبرای پیاده سازی این دستور ابتدا یک جدول employee می‌سازیم و داده‌های بالا را در آن ذخیره می‌کنیم.CREATE TABLE employee (&#xA;&#x9;employee_id INT PRIMARY KEY,&#xA;&#x9;first_name VARCHAR (255) NOT NULL,&#xA;&#x9;last_name VARCHAR (255) NOT NULL,&#xA;&#x9;manager_id INT,&#xA;&#x9;FOREIGN KEY (manager_id) &#xA;&#x9;REFERENCES employee (employee_id) &#xA;&#x9;ON DELETE CASCADE&#xA;);&#xA;INSERT INTO employee (&#xA;&#x9;employee_id,&#xA;&#x9;first_name,&#xA;&#x9;last_name,&#xA;&#x9;manager_id&#xA;)&#xA;VALUES&#xA;&#x9;(1, &#39;Windy&#39;, &#39;Hays&#39;, NULL),&#xA;&#x9;(2, &#39;Ava&#39;, &#39;Christensen&#39;, 1),&#xA;&#x9;(3, &#39;Hassan&#39;, &#39;Conner&#39;, 1),&#xA;&#x9;(4, &#39;Anna&#39;, &#39;Reeves&#39;, 2),&#xA;&#x9;(5, &#39;Sau&#39;, &#39;Norman&#39;, 2),&#xA;&#x9;(6, &#39;Kelsie&#39;, &#39;Hays&#39;, 3),&#xA;&#x9;(7, &#39;Tory&#39;, &#39;Goff&#39;, 3),&#xA;&#x9;(8, &#39;Salley&#39;, &#39;Lester&#39;, 3);توجه کنید که در جدول بالا ستون manager_id در واقع اشاره می‌کنید به ستون employee_id از همین جدول و به عبارت ساده بیان کننده این است که، مدیرِ شخصِ Salley، کارمندِ شماره‌ی ۳ است که Hassan نام دارد. زمانی که ستون manager_id خالی باشد به این معنا است که این شخص به خودش مقام بالا است و کسی manager او نیست.حال قصد داریم با یک query مشخص کنیم که در داده‌های این جدول چه کسی مدیر فرد دیگری است:SELECT&#xA;    e.first_name || &#39; &#39; || e.last_name employee,&#xA;    m.first_name || &#39; &#39; || m.last_name manager&#xA;FROM&#xA;    employee e&#xA;INNER JOIN employee m ON m.employee_id = e.manager_id&#xA;ORDER BY manager;در دستور بالا دو بار به جدول employee ارجاع دادیم که با استفاده از table aliases (تعیین نام موقت برای جدول) یک بار آنرا جدول e و یک بار دیگر آنرا جدول m نام گذاری کردیم. در دستور select هم از تعیین نام موقت یا column aliases استفاده کردیم. (برای کسب اطلاعات بیشتر در این خصوص،‌ آموزش نام گذاری موقت در دیتابیس رو ببینید).در join بالا تعیین کردیم که داده‌های ستون employee_id از جدول m رو با داده‌های ستون manager_id از جدول e مقایسه شوند و در صورتی که برابر باشند در نتایج ما قرار گیرند.به خروجی دستور توجه کنید:self joinاگر توجه کنید متوجه می‌شوید که top manager یا افرادی که manager_id آنها null هست در این لیست وجود ندارند.برای حل این مسئله نیز می‌تونیم کوئری رو با استفاده از LEFT JOIN به شکل زیر تغییر بدیم.SELECT&#xA;    e.first_name || &#39; &#39; || e.last_name employee,&#xA;    m .first_name || &#39; &#39; || m .last_name manager&#xA;FROM&#xA;    employee e&#xA;LEFT JOIN employee m ON m .employee_id = e.manager_id&#xA;ORDER BY manager;خروجی دستور بالا به این شکل خواهد بود:self joinبپردازیم به یک مثال دیگر که در آن قصد داریم سطر‌های یک جدول رو با سطر‌های دیگر از همون جدول مقایسه کنیم:جدول زیر رو در نظر بگیرید که برای نگهداری اطلاعات فیلم‌ها ازش استفاده می‌کنیم.film tableدر جدول بالا یک ستون به اسم length داریم که مدت زمان فیلم رو توی خودش نگه میداره و ما قصد داریم فیلم‌هایی که مدت زمان یکسانی رو دارند رو لیست کنیم. برای این کار از دستور زیر کمک می‌گیریم:SELECT&#xA;    f1.title,&#xA;    f2.title,&#xA;    f1.length&#xA;FROM&#xA;    film f1&#xA;INNER JOIN film f2 &#xA;    ON f1.film_id &lt;&gt; f2.film_id AND &#xA;       f1.length = f2.length;در دستور بالا جدول film رو با خودش inner join زدیم و شرط گذاشتیم که فیلم‌هایی که طول یکسانی دارند لیست شوند در با f1.film_id &lt;&gt; f2.film_id مطمئن شدیم که یک فیلم با خودش مقایسه نشود.خروجی دستور بالا به شکل زیر خواهد بود:self joinامیدوارم مطالب براتون مفید واقع شده باشه و لایک و کامنت رو فراموش نکنید.پایان/</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Sun, 13 Mar 2022 22:49:34 +0330</pubDate></item><item><title>آموزش postgres - دستور join</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/آموزش-postgres-دستور-join-lnc7fsk2spvl</link><description>بررسی انواع دستور join در postgresدر این آموزش قصد داریم به بررسی inner join, left join, right join و full join در postgres بپردازیم.به طور ساده و خلاصه، زمانی از از دستور join  استفاده می‌کنیم که می‌خواهیم داده‌های‌ِ ستون‌های یک جدول (self join) یا چند جدول رو با هم ترکیب کنیم و یک ساختار جدید بدست آوریم که عموما در این ترکیب‌ِ ستون های مشترک، یک ستون در یک جدول نقش ستون نگهدارنده کلید اصلی و در جدول دیگر نقشِ ستونِ کلید خارجی را دارد.در postgres انواع joinها به شکل زیر است:inner joinleft joinright joinfull outer joincross joinnatural joinself joinخب، اجازه بدید که با مثال پیش بریم، به دو جدول به اسم‌های basket_a و basket_b نیاز داریم، ابتدا آنها را ایجاد می‌کنیم و چند داده‌ در هر کدام از آنها ذخیره می‌کنیم:CREATE TABLE basket_a (&#xA;    a INT PRIMARY KEY,&#xA;    fruit_a VARCHAR (100) NOT NULL&#xA;);&#xA;&#xA;CREATE TABLE basket_b (&#xA;    b INT PRIMARY KEY,&#xA;    fruit_b VARCHAR (100) NOT NULL&#xA;);&#xA;&#xA;INSERT INTO basket_a (a, fruit_a) &#xA;VALUES&#xA;    (1, &#39;Apple&#39;),&#xA;    (2, &#39;Orange&#39;),&#xA;    (3, &#39;Banana&#39;),&#xA;    (4, &#39;Cucumber&#39;);&#xA;&#xA;INSERT INTO basket_b (b, fruit_b) &#xA;VALUES&#xA;    (1, &#39;Orange&#39;),&#xA;    (2, &#39;Apple&#39;), &#xA;    (3, &#39;Watermelon&#39;),&#xA;    (4, &#39;Pear&#39;);اگر از جدول های بالا لیست بگیریم خروجی مشابه با زیر خواهد بود:لیست داده‌های جدول basket_aلیست داده‌های جدول basket_bبررسی inner joinقصد داریم که میوه‌های مشترک بین جدول basket_a و basket_b رو لیست کنیم، به این شکل عمل می‌کنیم:SELECT&#xA;    a,    fruit_a,     b,    fruit_b &#xA;FROM&#xA;    basket_a&#xA; INNER JOIN basket_b&#xA;   ON fruit_a = fruit_b;در دستور بالا، دستور inner join تمام مقادیر ستون fruit_a از جدول basket_a رو با مقادیر ستون fruit_b از جدول basket_b مقایسه میکنه و جاهایی که مقادیر ستون fruit_a با ستون fruit_b برابر باشد را برمیگرداند.به خروجی دستور توجه کنید:inner joinدر واقع اگر بخواهیم رفتار inner join را روی نمودار venn نشان بدهیم به این شکل خواهد بود:venn - inner joinبررسی left joinزمانیکه که دو جدول رو با یکدیگر left join می‌کنیم به جدول نخست جدول left و به جدول دوم، جدول right می‌گوییم. دو جدولی که در ابتدای آموزش ساختیم را در نظر بگیرید. قصد داریم تا کوئری زیر را روی آنها اجرا کنیم:SELECT&#xA;    a,    fruit_a,     b,     fruit_b&#xA; FROM    basket_a &#xA;LEFT JOIN basket_b&#xA;    ON fruit_a = fruit_b;در left join ابتدا تمام داده‌های ستون fruit_a  از جدول basket_a (چونکه جدول left هست) با داده‌های ستون fruit_b از جدول basket_b مقایسه می‌شوند. اگر بین آنها اشتراکی وجود داشته باشد، left join سطرهای جدیدی می‌سازد که شامل این داده ‌های مشترک است و اگر چیزی از مقادیر fruit_a با داده‌های ستون fruit_b مشترک نباشد، left join با ستون‌های ذکر شده در select سطر‌های جدیدی میسازد اما اینبار ستون‌های جدول basket_b مقدار null را دارند.به خروجی توجه کنید:left joinاگر بخواهیم این نوع از join رو روی نمودار نشون بدیم به شکل زیر خواهد بود:venn - left joinاگر شما نیاز داشته باشید که داده‌های را لیست کنید که در جدول left وجود داشته باشند اما در جدول right نباشند می‌توانید کوئری زیر رو اجرا کنید:SELECT&#xA;    a,    fruit_a,    b,     fruit_b&#xA;FROM&#xA;    basket_a&#xA;LEFT JOIN basket_b&#xA;   ON fruit_a = fruit_b&#xA; WHERE b IS NULL;به خروجی این کوئری توجه کنید:اجرای left join و لیست داده‌هایی که فقط در جدول left هستندو نمودار venn برای این دستور به این شکل خواهد بود:نمودار venn برای left join همراه با شرط محدود کنندهبررسی right joinاین نوع از join برعکس left join عمل می‌کند. یعنی در واقع بررسی داده‌ها از جدول right شروع می‌شود و با یک ستون از جدول left مقایسه می‌شوند.یعنی برای right join از جدول های بالا می‌توان گفت که، تمام مقادیر ستون fruit_b از جدول basket_b با مقادیر ستون fruit_a از جدول basket_a مقایسه می‌شوند و هر مقایسه در نتیجه اش یک سطر ایجاد می‌شود از ستون‌های تعیین شده‌ در دستور SELECT که اگر این مقایسه اشتراکی داشته باشد، مقادیر مشترک در سطر جای میگیرند و اگر مقادیری از ستون fruit_b باشد که هیچ اشتراکی با fruit_a نداشته باشد، برای مقادیر جدول left که همان basket_a است، در سطر جدید، مقدار null قرار می‌گیرد.SELECT&#xA;    a,    fruit_a,    b,    fruit_b&#xA; FROM    basket_a&#xA; RIGHT JOIN basket_b&#xA; ON fruit_a = fruit_b;که خروجی دستور بالا به شکل زیر خواهد بود:اجرای right joinو نمایش دستور right join روی نمودار venn که به شکل زیر خواهد بود:venn - right joinبه طور مشابه با left join شما می‌توانید با اعمال یک شرط تعیین کنید که تنها داده‌هایی لیست شوند که در جدول right قرار دارند و در جدول left وجود ندارند.SELECT&#xA;    a,    fruit_a,    b,    fruit_b &#xA;FROM&#xA;    basket_a&#xA; RIGHT JOIN basket_b&#xA;    ON fruit_a = fruit_b&#xA; WHERE a IS NULL;که خروجی آن به این شکل خواهد بود:و نمایش این حالت از ‌right join روی نمودار venn به این شکل خواهد بود:نمودار venn برای right join همراه با شرط محدود کنندهبررسی full joinدر این نوع از join داده‌های مشترک از بین هر دو جدول (right - left ) دریافت می‌شوند و داده‌هایی که بین جدول‌ها مشترک نباشد برای آنها مقدار null درنظر گرفته می‌شود.SELECT&#xA;    a,    fruit_a,    b,    fruit_b&#xA; FROM    basket_a&#xA; FULL OUTER JOIN basket_b&#xA;     ON fruit_a = fruit_b;خروجی دستور بالا به شکل زیر خواهد بود:full joinو نمودار venn برای این join به شکل زیر خواهد بود:venn - full joinگاهی اوقات ممکن است نیاز داشته باشید که داده‌هایی را از جدول‌های دریافت کنید که هیچ اشتراکی با یکدیگر نداشته باشند، برای این کار تنها کافیست که دستور زیر را اجرا کنید:SELECT    a,    fruit_a,    b,    fruit_b&#xA; FROM    basket_a&#xA; FULL JOIN basket_b&#xA;    ON fruit_a = fruit_b&#xA; WHERE a IS NULL OR b IS NULL;خروجی این دستور به شکل زیر خواهد بود :دستور full join همراه با شرط محدود کنندهو نمودار venn برای این دستور:نمودار venn برای full join همراه با شرط محدود کنندهدر آموزش‌های بعدی، به انواع دیگر از join خواهیم پرداخت اما تا اینجای کار امیدوارم که این آموزش براتون مفید واقع شده باشه و در ضمن خوشحال میشم که نظرات شما رو در خصوص این آموزش بدونم.پایان/</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Sat, 12 Mar 2022 00:19:59 +0330</pubDate></item><item><title>آموزش postgres - بررسی Column Alias</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/آموزش-postgres-بررسی-column-alias-qga5lnqhtksh</link><description>همونطور که توی آموزش دستور Select قول داده بودم امروز قصد دارم به آموزش تعیین نام مستعار برای یک ستون و یا همون column aliases بپردازم.نام مستعار یا column alias به ما این امکان رو میده که در دستور SELECT نامی جدید رو به یک ستون و یا حتی یک expression اختصاص بدیم و این اسم موقت در طول اجرای کوئری وجود خواهد داشت.SELECT column_name AS alias_name‌ FROM table_name; در دستور بالا، نامِ مستعارِ alias_name را برای ستونِ column_name قراردادیم. توجه داشته باشید که کلمه‌ی AS اختیاری است و می‌توانید آنرا حذف کنید. یعنی به شکل زیر بنویسید:SELECT column_name alias_name FROM table_name;در دستور زیر نحوه‌ی قرار دادن یک نام مستعار برای یک expression رو نشون دادیم که خیلی شبیه به حالت تعیین نام برای ستون است:SELECT expression AS alias_name FROM table_name; و اما بریم سراغ مثال:فرض کنید جدول زیر رو، به عنوان جدول customer داریم:جدول customerاین کوئری رو در نظر بگیرید:SELECT first_name,  last_name&#xA;FROM customer;که خروجی اون به شکل زیر خواهد بود:خروجی Queryاما اگر قصد داشته باشیم که نام ستون last_name را به surname تغییر دهیم، به شکل زیر عمل می‌کنیم:SELECT first_name, last_name AS surname&#xA;FROM customer;که خروجی زیر را خواهد‌ داشت:‌خروجی Queryکوئری بالا را به شکل زیر هم می‌شه نوشت:‌(حذف AS از query)SELECT  first_name,  last_name surname&#xA;FROM customer;و اما مثال از تعیینِ نامِ مستعار برای یک expressionتوی آموزش دستور Select یک query نوشتیم که با یک توی کوئری از concatenating operator استفاده کردیم) حاصل ستون‌های first_name و last_name رو با هم ترکیب میکرد و در خروجی به عنوان یک ستون به ما نشون میداد اما اسمِ ستونِ نهایی ?column? بود.SELECT   first_name || &#39; &#39; || last_name  FROM customer;خروجی کوئری -- به اسم ستون توجه کنید.اما با اجرای دستور زیر، به ستون حاصل از ترکیب ستون‌های first_name و last_name، یک اسم مستعار اختصاص می‌دهیم:SELECT first_name || &#39; &#39; || last_name AS full_name FROM‌ customer;خروجی دستور بالا به شکل زیر خواهد شد:خروجی کوئری - به نام ستون توجه کنید.توجه کنید که اگر بخواهید اسمی که به عنوان نام مستعار انتخاب می‌کنید شامل کاراکتر space باشد باید آنرا درون کوتیشین دوتایی (double quotes) قرار بدهید. به طور مثال:SELECT first_name || &#39; &#39; || last_name &#34;full name&#34; &#xA;FROM customer;خروجی query به این شکل خواهد بود:پایان/خوشحال میشم نظرات شما رو هم بدونمدر ضمن،‌ منتظر آموزش‌های بعدی باشید...</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Sun, 06 Mar 2022 15:09:40 +0330</pubDate></item><item><title>آموزش postgres - دستور select</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/آموزش-postgres-دستور-select-qzjc8ggybeyk</link><description>آموزش دستور Select در Postgresتوی این آموزش یاد میگیریم که چجوری از دستور select برای دریافت اطلاعات از جدول‌ها استفاده کنیم...یکی از پرکاربردترین دستورات هنگام کار با دیتابیس، دستور select است که با اون میتونیم اطلاعاتی رو با  توجه به شرایط تعیین شده از جدول(ها) دریافت کنیم.این دستور یکسری بند (که از این پس caluse می‌نامیم ) داره که ابتدا اونها رو یک بررسی مختصر میکنیم:بند DISTINCT که ردیف‌های متمایز را از یک جدول دریافت می‌کند و موارد تکراری فقط یک بار آورده می‌شوند.استفاده از ORDER BY که وظیفه‌ی sort کردن رو بر عهده داره.فیلتر کردن row ها بر اساس WHEREدریافت یک مجموعه‌ی محدود شده از نتایج با استفاده از LIMIT و FETCH گروه‌بندی کردن rowها با کمک GROUP BYاعمال شرط و فیلتر روی گروه‌ها با استفاده از HAVINGمتصل کردن جدول‌ها با یکدیگر با استفاده از شکل‌های متفاوت join مثل INNER JOIN - LEFT JOIN - CROSS JOIN و یا FULL OUTER JOINابتدا با شکل ساده‌ی SELECT شروع می‌کنیمSELECT select_list FROM table_name;در دستور بالا مقدار select_list می‌تواند نام ستون‌ یا ستون‌هایی باشد که قصد دارید داده‌‌های آنها دریافت شود و اگر بخواهید که نام چند ستون را بنویسید باید آنها را با , از هم جدا کنید. البته گاهی اوقات شما نیاز دارید تا داده‌های تمام ستون‌ها را دریافت کنید، در این صورت به جای نوشتن نام تک تک ستون‌ها، از علامت * استفاده می‌کنیم که به معنای تمامی ستون‌ها می‌باشد.مقدار table_name هم باید نام جدولی باشد که قصد دارید query روی آن اجرا شود.نکته: توجه داشته باشید که مقدار FROM قبل از دستور SELECT بررسی می‌شود.نکته: دستورات SQL به کوچک یا بزرگ بودن حروف حساس نیستند، یعنی اگر شما به جای SELECT از select و یا Select استفاده کنید تفاوتی ایجاد نمی‌شود اما به طور قرارداد، برای اینکه دستورات راحت‌تر خوانده شوند آنها را با حروف بزرگ می‌نویسیم.نکته: توجه کنید که دستور FROM به عنوان بخش الزامی و اجباری از دستور SELECT نیست و میتوان آنرا حذف کرد و دستور SELECT تنها یک expression را محاسبه کند. (در طول آموزش و قسمت‌های بعدی نمونه‌هایی خواهیم دید)خب، بهتر است که چند مثال از این دستور را ببینیم. فرض کنید یک جدول با نام customer  به شکل زیر داریم:جدول customerبا استفاده از کد زیر تنها مقادیر ستون first_name را دریافت می‌کنیم:SELECT first_name FROM customer;خروجی دستور به این شکل می‌شود:دریافت مقادیر ستون first_name از جدول customerاگر در دستور بالا به جای first_name از علامت * استفاده می‌کردیم، مقادیر تمامی ستون‌ها از جدول customer برایمان لیست میشد. توجه داشته باشید که استفاده از * در تمامی حالات مناسب نیست زیرا:ممکنه که جدول شما دارای ستون‌های زیادی باشه که تنها به چندتا از آنها نیاز داشته باشید، پس اگر در اینجا از * استفاده کنیم می‌تونه به جای اینکه مفید باشه کارایی دیتابیس رو کاهش بده.دوم اینکه گاهی اوقات دریافت اطلاعات زیادی و بدون فایده از دیتابیس میتونه باعث ایجاد ترافیک زیاد بین برنامه‌ی شما و سرور بشه که درنتیجه منجر به کندی برنامه شما خواهد شد.نکته:‌ علامت ; که در انتهای query نوشتیم جزیی از دستور SQL نیست و تنها با استفاده از آن به SQL میفهمانیم که دستور ما در اینجا به پایان رسید و البته برای جدا کردن چند دستور SQL هم به کار می‌رود.گاهی اوقات ممکن است که نیاز داشته باشید که در دستور select  از یک expression هم استفاده کنید.به طور مثال فرض کنید که قصد دارید از جدول customer، مقدار ستون email و مقدار ترکیب شده‌ی ستون‌های first_name و last_name رو دریافت کنید، در این حالت به این شکل عمل می‌کنیم:SELECT &#xA;   first_name || &#39; &#39; || last_name,&#xA;   email&#xA;FROM &#xA;   customer;که خروجی دستور بالا به این شکل خواهد بود:استفاده concatenation operator در دستور selectدر مثال بالا از  concatenation operator استفاده کردیم تا بتوانیم مقادیر ستون‌ first_name و last_name رو با هم ترکیب کنیم اما اگر به خروجی توجه کنید می‌بینید که اسم ستون حاصل از این ترکیب به صورت ?column? در آمده که در آموزش‌ تعیین نام مستعار برای یک ستون توضیح دادم که چجوری این مشکل رو برطرف کنید.استفاده از دستور SELECT بدون FROM:SELECT 5 * 3;که خروجی آن به صورت زیر خواهد بود:استفاده از دستور ‌SELECT بدون FROMهنوز کلی با دستور SELECT کار داریم، پس فعلا اینها رو تمرین کنید تا بریم سراغ آموزش بعدی...</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Fri, 04 Mar 2022 17:44:41 +0330</pubDate></item><item><title>خلاصه ای بر داکرفایل های چند سطحی</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/خلاصه-ای-بر-داکرفایل-های-چند-سطحی-qbigtwuydtaa</link><description>مفهوم  multi-stage در داکرپایین نگه داشتن حجم داکر imageها یکی از چالش‌های مهم در داکر است و زمانی که حجم image بالا می‌رود نگه داری و استفاده از آن نیز مشکل تر خواهد بو و از طرفی نوشتن چند داکرفایل برای یک پروژه هم میتونه پیچیدگی رو بیشتر کنه.میدونید که هر دستوری که در داکرفایل اجرا می‌شود یک لایه به image اضافه می‌کند و از این رو باید جوری دستو‌رها را بنویسیم که image نهایی بهینه باشد. یکی از کارهایی که به بهینه کردن image کمک میکنه استفاده از داکرفایل‌های چندسطحی (multi-stage) است.تا ورژن‌های قبلی داکر که قابلیت داکرهای چندسطحی (multi stage) رو نداشت مجبور میشدیم از builder pattern استفاده کنیم، یا به زبون ساده بخواهیم بگیم یعنی اینکه برای حالت Develop و Production داکر فایل‌های جداگانه بنویسیم و هر کدام را جدا اجرا کنیم.اما...مولتی استیج چیست؟مولتی استیج یعنی اینکه در یک داکرفایل چندین بار دستور FROM را داشته باشیم. هر FROM از یک Base image استفاده می‌کند و یک stage جدید را می‌سازد. در multi stage این قابلیت را داریم که از یک استیج محتوایی را به استیج دیگر کپی کنیم و این بدان معنا است که می‌توانیم از آنچه که نیاز نداریم صرف‌نظر کنیمFROM golang:1.7.3&#xA;&#xA;WORKDIR /go/src/github.com/alexellis/href-counter/&#xA;&#xA;RUN go get -d -v golang.org/x/net/html&#xA;&#xA;COPY app.go .&#xA;&#xA;RUN CGO ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .&#xA;&#xA;&#xA;FROM alpine:latest&#xA;&#xA;RUN apk - -no-ache  add  ca-certificates&#xA;&#xA;WORKDIR /root/&#xA;&#xA;COPY - -from=0  /g/src/github.com/alexellis/href-counter/app .&#xA;&#xA;CMD [&#34;./app&#34;]در داکر فایل بالا می‌بینید که دو دستور FROM داریم و از Base image های golang و alpine استفاده کردیم با این اوصاف ما فقط یک داکر فایل داریم و با یک دستور آنرا اجرا میکنیم docker  build -t example/example .این داکر فایل به چه صورت اجرا میشود؟ در این داکر فایل دستور FROM دوم یک نسخه از آخرین ورژن alpine را به عنوان Base image قرار می‌دهد و دستور COPY --from=0 محتویات آدرس داده شده را از درون مسیر /g/src/github.com/alexellis/href-counter/appاز stage نخست به آدرس / در stage دوم کپی میکند.احتمالا این سوال برایتان پیش آمده که from=0-- به چه معناست!‌ stage ها به طور پیش فرض هیچ اسمی ندارند و برای اینکه به یک stage اشاره کنیم، از عدد شمارنده‌ی هر کدام از آنها استفاده می‌کنیم. این عدد به طور پیش فرض به هر stage داده می‌شود و توجه کنید که این‌ شمارنده از صفر شروع می‌شود و برای هر استیج یک واحد افزایش پیدا می‌کند.اما اگر بخواهیم به یک stage نام بدهیم با استفاده از عبارت AS اینکار را انجام می‌دهیم.بعد از اینکار برای اشاره به یک stage دیگر نیازی به استفاده از عدد نیست و می‌توان از طریق نام داده شده به آن دسترسی داشت.به طور مثال:FROM golang:1.7.3 AS golang_builder&#xA;&#xA;WORKDIR /go/src/github.com/alexellis/href-counter/&#xA;&#xA;RUN go get -d -v golang.org/x/net/html &#xA;&#xA;COPY app.go .&#xA;&#xA;RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . &#xA;&#xA;&#xA;FROM alpine:latest&#xA;&#xA;RUN apk --no-cache add ca-certificates&#xA;&#xA;WORKDIR /root/ &#xA;&#xA;COPY --from=golang_builder /go/src/github.com/alexellis/href-counter/app .&#xA;&#xA;CMD [&#34;./app&#34;]میتوانیم فقط یک stage را اجرا کنیم؟حتما، ممکنه که یک داکر فایل چند stage داشته باشه و ما نخواهیم که همه‌ی آنها را اجرا کنیم در این شرایط میتونیم در دستور build مشخص کنیم که قصد اجرای کدام بخش از داکر فایل را داریم.docker build --target golang_builder example/example .یعنی در دستور build با استفاده از آپشن target ، نام stage‌ی که قصد اجرای آن را داریم، ذکر می‌کنیم.گاهی اوقات برای دیباگ یک بخش از داکر فایل ممکنه که بخواهید فقط یک استیج رو اجرا کنید، با این روش به آسونی این کار ممکن میشه.نکات:- همیشه برای کپی کردن از یک stage نیاز نیست که اون stage از قبل در داکر فایل ما موجود باشه!‌ شما میتونید نامی که به عنوان ورودی به from-- میدید خودش یک Image به صورت لوکال و یا روی داکرهاب باشه.مثلا می‌تونید بنویسید:COPY --from=nginx:latest  /etc/nginx.conf  /nginx.confدستور بالا ابتدا چک میکند که اگر ایمیج nginx:lates موجود بود، کانفیگ‌های موجود در آدرس /etc/nginx.conf را به آدرس nginx.conf/ کپی میکند‌ و اگر موجود نبود ابتدا nginx:latest رو دریافت می‌کنه و سپس عمل کپی را انجام می‌دهد.- استفاده از multi-stage در جهت بهینه‌تر شدن imageها خیلی مفیده اما این موضوع رو هم فراموش نکنید که استفاده از این شیوه وحی مُنزل نیست و ممکنه بعضی از همکارانتون با این سبک نوشتن آشنایی نداشته باشند و یا جاهایی باعث پیچیده تر شدن قضيه بشه. پس قبل از استفاده شرایط رو بررسی کنید.در ضمن، یک مثال از داکر فایلهای چند سطحی رو می‌تونید تو این پست مشاهده کنید.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Tue, 01 Mar 2022 00:43:28 +0330</pubDate></item><item><title>استفاده از دستور ADD یا COPY ؟ مسئله این است !</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/استفاده-از-دستور-add-یا-copy-مسئله-این-است-wwlbe1c4ut6p</link><description>دستور add و copy در داکرفایلبه احتمال خیلی قوی، اگر که با Dockerfile کار کرده باشید، دستور‌های ADD و COPY به چشمتان خورده‌اند...اما،‌ تفاوت این دو دستور، در چیست ؟  و از کدام یک باید استفاده کنیم؟اجازه دهید که با یک توضیح بسیار کلی شروع کنیم. هر دو دستور، کار یکسان کپی کردن فایل‌ها از یک آدرس به یک کانتینر را دارند.دستور COPY یک آدرس را به عنوان مبدا (src) و یک آدرس را به عنوان مقصد(dest) دریافت می‌کند و محتویات مبدا را درون مقصد ( که آدرسی درون image هست ) کپی می‌کند.توجه کنید که در دستور COPY  آدرس مبدا، باید محلی در هاست یا کامپیوتر شما باشد و نمی‌تواند یک آدرس روی فضای اینترنت باشد.COPY &lt;src&gt;  &lt;dest&gt;دستور ADD هم به همین شکل عمل می‌کند اما ۲ تفاوت با دستور COPY  دارد:اولین تفاوت اینکه،‌ در این دستور شما اجازه دارید آدرس مبدا را جایی به جز سیستم خودتان تعیین کنید. (مثلا آدرس یک فایل روی یک سرور)و دومین تفاوت اینکه، این دستور به طور پیش فرض فایل‌های فشرده‌ را در محل مقصد extract می‌کند.و اما نکات بسیار مهمی که نباید آنها را نادیده بگیریم:یک:‌ زمان استفاده از  دستور ADD برای extract فایل‌های فشرده شده، این فایل‌ها (tar)  باید  به صورت لوکالی  باشند و نمی‌توانند روی یک remote آدرس باشند.دو:  اگر قرار است که یکی از دستورات Dockerfile مان،وظیفه‌ی کپی کردن یکسری فایل از سیستم به image را برعهده داشته باشد و در داخل این فایل‌ها، فایلی قرار داشته باشد که باعث تغییراتی عمده و کلیدی در ساخت image می‌شود بهتر است که آنرا به صورت جداگانه کپی کنیم، به طور مثال اگر قرار است فایل‌های یک پروژه‌ی نود‌جی‌اس را درون image کپی کنیم، بهتر است فایل package.json را که لیست پکیج‌ها و کانفیگ‌های مورد نیاز پروژه را در خود دارد، به صورت جداگانه کپی کنیم و بعد از اینکه دستور npm install را اجرا کردیم ما بقی فایل‌های پروژه را کپی کنیم.اما چرا؟  زیرا ‌در اجرای هر دستور از Dockerfile، یک لایه و کش برای آن در نظر گرفته می‌شود و این کار باعث می‌شود که اگر فایل package.json را تغییر دادیم، تنها لایه‌های مرتبط با این تغییر،  مجدد اجرا شوند و در نتیجه کش‌های کمتری که وابسته به این لایه‌ها هستند به روزرسانی شوند (نسبت به حالتی که ابتدا تمام فایل‌ها کپی شوند) و مابقی فایل‌ها که بعد دستور install، کپی کردیم بدون تغییر بمانند.پس، این حالت شاید اجرا شود، اما کاملا درست و منطقی نیست:FROM node:alpine-lts&#xA;COPY . .&#xA;RUN npm install&#xA;.... و شیوه‌ی صحیح نوشتن:FROM node:alpine-lts&#xA;COPY package.json&#xA;RUN npm install&#xA;COPY . .&#xA;...در شرایط یکسان کدام را استفاده کنیم ؟‌طبق داکیومنت داکر،‌ در شرایطی که استفاده از این دستور‌ها تفاوتی ندارد بهتر است که از COPY استفاده کنید و تنها در صورت نیاز به توانایی‌های دستور ADD،‌ آنرا به کار ببریم.بسیار خوشحال میشم که نظرات شما رو هم بدونم.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Sat, 26 Feb 2022 21:52:57 +0330</pubDate></item><item><title>چجوری پروژه‌‌های Vue رو Dockerize کنیم‌؟</title><link>https://virgool.ir/Solidity/چجوری-پروژه-های-vue-رو-dockerize-کنیم-dsugtpgyprcw</link><description>Vue + Dockerممکنه که به این فکر افتاده باشید که چجوری میشه یه پروژه Vue js رو داکرایز کرد.با من پیش بیایید تا این کار رو انجام بدیم:با ساختن یک فایل به اسم Dockerfile (بدون هیچ پسوندی) در مسیر ریشه‌ی پروژه شروع میکنیم. ( توجه کنید که اگه بخواهید میتونید اسم و محل فایل رو عوض کنید اما بزارید فعلا خیلی پیچیدش نکنیم :)  )این دستورات رو توی این فایل می‌نویسیم:FROM node:lts-alpine&#xA;&#xA;# install simple http server for serving static content&#xA;RUN npm install -g http-server&#xA;&#xA;# make the &#39;app&#39; folder the current working directory&#xA;WORKDIR /app&#xA;&#xA;# copy both &#39;package.json&#39; and &#39;package-lock.json&#39; (if available)&#xA;COPY package*.json ./&#xA;&#xA;# install project dependencies&#xA;RUN npm install&#xA;&#xA;# copy project files and folders to the current working directory (i.e. &#39;app&#39; folder)&#xA;COPY . .&#xA;&#xA;# build app for production with minification&#xA;RUN npm run build&#xA;&#xA;EXPOSE 8080&#xA;&#xA;CMD [ &#34;http-server&#34;, &#34;dist&#34; ]خب، یه نگاهی بندازیم به این داکرفایل با دستور FROM، نوع و ورژن image پایه‌ی این  Dockerfile  را مشخص می‌کنیم. سپس پکیجی که برای اجرای فایل‌های پروژه به آن نیاز داریم رو به صورت گلوبال نصب کردیم (پکیج http-server) این پکیج نقش سرور را برایمان بازی می‌کند. سپس یک دایرکتوری به اسم app ساختیم و اونرو محل اجرای دستورات بعدی تعیین کردیم.فایل ‌های package.json و package.lock.json رو توی پوشه app کپی کردیم بعد  npm install و نصب پکیج‌های پروژه‌ی خودمونبا دستور COPY تمام فایل‌های پروژه مون رو توی پوشه‌ی app کپی کردیماز پروژه build گرفتیم و در نهایت پوشه dist رو با http-server اجرا کردیم.قبل از اجرای این داکر فایل، یک فایل به اسم dockerignore. رو توی مسیر ریشه از پروژه می‌سازیم و دستورات زیر رو داخلش قرار میدیم: **/node_modules&#xA;**/distاین فایل مشابه با فایل gitignore. عمل میکنه و باعث میشه که محتویات این فایل از چشم دستورات داکرفایل نادیده گرفته بشن،‌ مثلا با اجرای دستور COPY از فایل‌های پروژه، این دستور دایرکتوری‌ها و فایل‌های داخل dockerignore. رو نادیده میگیره.حالا یک image از این داکرفایل می سازیم:docker build -t vuejs/dockerize .توی دستور بالا،‌ با آپشن t- مشخص کردیم که اسم image ی که قرار هست ساخته بشه vuejs/dockerize باشه و علامت نقطه مشخص میکنه که این image باید از روی همین داکرفایلی که در محل اجرای این دستور هست ساخته شود.در نهایت یک کانتینر از روی این Image اجرا میکنیم:docker run -d -p 8080:8080 --rm --name dockerize-vuejs-app vuejs/dockerizeبا دستور بالا یک کانتینر می‌سازیم که پورت ۸۰۸۰ از هاست شما را به پورت ۸۰۸۰ از کانتینر متصل میکنداگر این کانتینر از قبل موجود باشد، آپشن rm-- به صورت اتوماتیک آنرا حذف می‌کند.با آپشن name--  اسم کانتینر رو مشخص کردیم و در انتها هم گفتیم که این کانتینر از روی image به اسم  vuejs/dockerize ساخته بشه.آپشن -d باعث میشه که این کانتینر در بک گراند اجرا بشه (detached mode)اگر که تمام مراحل بالا بدون مشکل انجام داده باشید، شما می‌تونید این پروژه vue رو از طریق مرورگرتون با رفتن به آدرس localhost:8080 اجرا کنید.خب...طبق چیزی که توی داکیومنت vue گفته شده، درسته که شما تونستید به این شکل پروژه‌ی vue رو داکرایز کنید اما این شیوه برای حالت production خیلی امن و مطمئن نیست و بهتر هست که از یک وب سرور مثل apache و یا nginx استفاده کنید.It is powerful enough for production usage, but it’s simple and hackable enough to be used for testing, local development, and learning.https://v2.vuejs.org/v2/cookbook/dockerize-vuejs-app.htmlواسه‌ی این که پروژه رو با nginx اجرا کنیم باید یک تغییراتی توی داکرفایلمون بدیم:# build stage&#xA;FROM node:lts-alpine as build-stage&#xA;&#xA;WORKDIR /app&#xA;&#xA;COPY package*.json ./&#xA;&#xA;RUN npm install --production&#xA;&#xA;COPY . .&#xA;&#xA;RUN npm run build&#xA;&#xA;# production stage&#xA;FROM nginx:stable-alpine as production-stage&#xA;&#xA;COPY --from=build-stage /app/dist /usr/share/nginx/html&#xA;&#xA;EXPOSE 80&#xA;&#xA;CMD [&#34;nginx&#34;, &#34;-g&#34;, &#34;daemon off;&#34;]به این شکل از داکرفایل ها که چند دستور FROM دارند، multi stage گفته می‌شه.برای اطلاعات بیشتر می‌تونید این لینک رو ببینید.خب ببینیم توی این داکر فایل چی داریم:توی stage اول که اونو build-stage نام گذاری کردیم تقریبا همه چیز مشابه به با داکرفایل قبلی است با این تفاوت که دیگه http-server رو نصب نکردیم و ازش استفاده ای هم نکردیم.و اما در stage دوم از nginx استفاده کردیم و اسم این stage رو  production-stage گذاشتیم.محتویات پوشه‌ی /app/dist از build-stage رو به داخل دایرکتوری /user/share/nginx/html از production-stage ریختیمپورت ۸۰ کانتینر رو expose کردیمو در پایان هم با استفاده از nginx سرور رو راه‌اندازی کردیم.حالا اگر از روی این داکر فایل یک image بسازید و بعد یک کانتینر از روش اجرا کنید، باز خروجی مشابهی در آدرس localhost:8080 خواهید گرفت.توجه کنید که این بار توی ساخت Container پورت ۸۰۸۰ از هاست رو به پورت ۸۰ کانتینر متصل می‌کنیم.docker run -d -p 8080:80 --rm --name dockerize-vuejs-app vuejs/dockerizeتوجه:‌ حالت خاص‌ِ History Mode در Vue Routerاگه که توی Router پروژه‌تون mode رو به history تغییر داده‌اید ممکنه که زمانی که پروژه رو اجرا می‌کنید، اگه یک آدرسی از پروژه‌‌تون رو به جز آدرس ریشه، توی مرورگر بزنید با خطای ۴۰۴ رو به رو شید.برای حل این مشکل کافیه که یک تغییر توی تنظیمات nginx بدیم:برای این کار، فایل nginx.conf رو توی مسیر ریشه پروژه ایجاد کنید و تنظیمات زیر رو داخلش قرار بدید:user  nginx;&#xA;worker_processes  1;&#xA;error_log  /var/log/nginx/error.log warn;&#xA;pid        /var/run/nginx.pid;&#xA;events {&#xA;  worker_connections  1024;&#xA;}&#xA;http {&#xA;  include       /etc/nginx/mime.types;&#xA;  default_type  application/octet-stream;&#xA;  log_format  main  &#39;$remote_addr - $remote_user [$time_local] &#34;$request&#34; &#39;&#xA;                    &#39;$status $body_bytes_sent &#34;$http_referer&#34; &#39;&#xA;                    &#39;&#34;$http_user_agent&#34; &#34;$http_x_forwarded_for&#34;&#39;;&#xA;  access_log  /var/log/nginx/access.log  main;&#xA;  sendfile        on;&#xA;  keepalive_timeout  65;&#xA;  server {&#xA;    listen       80;&#xA;    server_name  localhost;&#xA;    location / {&#xA;      root   /app;&#xA;      index  index.html;&#xA;      try_files $uri $uri/ /index.html;&#xA;    }&#xA;    error_page   500 502 503 504  /50x.html;&#xA;    location = /50x.html {&#xA;      root   /usr/share/nginx/html;&#xA;    }&#xA;  }&#xA;}سپس نیاز داریم که مجدد داکرفایلمون رو تغییراتی بدیم و این فایل nginx.conf رو به عنوان تنظیمات جدید Nginx قرار بدیم:FROM node:latest as build-stage&#xA;&#xA;WORKDIR /app&#xA;&#xA;COPY package*.json ./&#xA;&#xA;RUN npm install&#xA;&#xA;COPY ./ .&#xA;&#xA;RUN npm run build&#xA;&#xA;&#xA;FROM nginx as production-stage&#xA;&#xA;RUN mkdir /app&#xA;&#xA;COPY --from=build-stage /app/dist /app&#xA;&#xA;COPY nginx.conf /etc/nginx/nginx.confحالا کافیه که باز روال ایجاد image و container رو یک بار دیگه انجام بدیم و یک کانتینر جدید اجرا کنیم.اگه مراحل رو با موفقیت پشت سر گذاشته باشید،‌می‌تونید خروجی رو توی آدرس localhost:8080 مرورگرتون ببینید.تمام :) در ضمن، اگه سوالی داشته باشید، خوشحال میشم تا جایی که بلد باشم کمکتون کنم.موفق باشید.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Fri, 25 Feb 2022 21:42:32 +0330</pubDate></item><item><title>سرباز، برنامه نویس</title><link>https://virgool.ir/@jafarzadeh.hesam.wm/سرباز-برنامه-نویس-sxumbtv6zoya</link><description>سرباز سپاه هستند ایشونهمه جوره اش رو تست کردیم، فقط همین مونده بود!!! کار با کارفرما های متفاوت (خوش قلق یا بد قلق، با تخصص یا بی تخصص و... ) ، انجام پروژه های متفاوت(سخت، آسون، با دد لاین کوتاه و یا هرچی دیگه)  و در کل شرایط متفاوت، خودش به تنهایی میتونست همه چی رو پیچیده کنه، چه برسه به اینکه حالا دیگه، خدمت سربازی هم بهش اضافه شه... واقعا مدیریت زمان سخت میشه و اگر بتونید هم با چنگ و دندون وقت رو اسیر خودتون کنید احتمالا اینقد خسته هستید که حداکثر بعد از 30 دقیقه از باز کردن vs code دارید خواب خرگوشی میبینید??البته شنیدیم و دیدیم بعضی ها رو که خداییش خیلی خدمت فشاری بهشون وارد نمیکنه... (بند پ) واسم جالبه که بدونم شما موقع خدمت، چه اوضاعی داشتید! واستون سخت بود یا اسون؟ کامنت کنید?</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Tue, 23 Mar 2021 22:48:18 +0430</pubDate></item><item><title>دستور grep در لینوکس</title><link>https://virgool.ir/CodeLovers/دستور-grep-در-لینوکس-hhi6gkic84xi</link><description>:) grepاگر با ترمینال لینوکس کار کرده باشید احتمالا به دستور grep برخورد کردید، حالا قصد داریم تا کمی بیشتر با این دستور آشنا شیم.این دستور مخفف کلمات Global Regular Expression Print است که کارش جستجوی یک عبارت و یا الگو بین فایل یا فایل‌هایی (یا رشته‌ها) می‌باشد.این دستور به طور کلی از ۳ بخش تشکیل شده است:بخش اول : دستور grepبخش دوم: عبارت یا الگویی که قصد جستجوی آن را داریمو بخش سوم نام فایل یا فایل‌هایی که می‌خواهیم در آن‌ها به جستجو بپردازیم.grep linxu sample.txtاین دستور به دنبال کلمه‌ی linxu در فایل sample.txt می‌گردد و در صورتی که موجود باشد تمام خطی که شامل این کلمه بوده است را برمیگرداند.برای این که همین کلمه را بین چند فایل جستجو کنیم کافی است که نام فایل ها را با space از هم جدا کنیم :grep linux sample1.txt sample2.txt sample3.txtو مجدد اگر این کلمه در هرکدام از این فایل ها که باشد این بار علاوه بر این که خطی که شامل این کلمه بوده چاپ می‌شود نام فایل هم در ابتدا چاپ می‌شودگاهی اوقات نیاز داریم که بین تمام فایل‌های موجود در یک دایرکتوری جستجو کنیم برای این کار به جای نام فایل از * استفاده می‌کنیم:grep linux *در ضمن می‌توانیم تعیین کنیم که این جستجو به صورت تو در تو انجام شود، برای این‌کار از آپشن r استفاده می‌کنیمgrep -r linux *اگر بخواهیم که جستجوی خود را محدود به کلمه کنیم از آپشن w استفاده می‌کنیم که در اینصورت خطوطی چاپ خواهند شد که دقیقا همین عبارت در آن‌ها باشد (بدون این آپشن اگر عبارت بخشی از یک رشته هم باشد چاپ خواهد شد)grep -w linux *به طور پیش‌فرض دستور grep به کوچک یا بزرگ بودن حروف حساس است اما اگر بخواهیم این حساسیت کنار گذاشته شود می‌توانیم از آپشن i استفاده کنیمgrep -i linux *که در اینصورت اگر خطی شامل LINUX هم باشد در خروجی چاپ خواهد شد.برای نمایش نام فایل‌هایی که الگوی مورد نظر در آن‌ها منطبق شده است از آپشن l استفاده می‌کنیمgrep -l linux *برای شمارش تعداد موارد منطبق شده در هر فایل از آپشن c استفاده می‌شودgrep -c linux *اگر بخواهیم شماره ی خطی که الگوی مورد نظر در آن پیدا شده در خروجی چاپ شود از دستور n استفاده می‌کنیم.grep -n linux sample.txtمی‌توانیم با استفاده از آپشن A تعداد خطوط بعد از انطباق و با استفاده از آپشن B تعداد خطوط قبل از انطباق و با استفاده از C تعداد خطوط قبل و بعد انطباق را هم در خروجی چاپ کنیم:grep -n -C 3 linux sample.txtبا اجرای دستور بالا ۳ خط از قبل و ۳ خط از بعد انطباق‌ها چاپ خواهد شد.شما دیگه چه آپشن‌هایی میشناسید؟ اونها رو کامنت کنید تا ما هم بدونیم...</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Thu, 28 Jan 2021 10:11:51 +0330</pubDate></item><item><title>میانجی (Middleware) در Express JS</title><link>https://virgool.ir/nodejs/میانجی-middleware-در-express-js-i8dxylkzst1f</link><description>قبل از هر چیز ، Middleware چیست ؟به طور ساده به عنوان یک راه ورودی در نظر بگیرید که Request ها اول از همه باید از اینجا عبور کنند و سپس به Handler برسند.در Express برای اینکه بتوانیم یک middleware بنویسیم از متد زیر استفاده میکنیم :app.use(path,callbak)این متد یک پارامتر اختیاری (path) و یک پارامتر اجباری (callback) میگیرد.فرض کنید قصد داریم تا Date و Method و آدرس درخواست داده شده به سرور رو در جایی ثبت کنیم، برای این کار یک middleware قبل از تمام Route ها تعریف میکنیم : //instantiate the Express.js appapp.use(function(req, res, next) {&#xA;    console.log(&#39;%s %s — %s&#39;, (new Date).toString(), req.method, req.url);&#xA;    return next();&#xA;});&#xA; //implement server routesاز طرف دیگر فرض کنید میخواهیم که این اتفاق فقط برای مسیرهایی که با الگوی admin/ شروع میشوند بیافتد، در این حالت از پارامتر اختیاری path استفاده میکنیم : //instantiate the Express.js appapp.use(&#39;/admin&#39;, function(req, res, next) {    console.log(&#39;%s %s — %s&#39;, (new Date).toString(), req.method, req.url);&#xA;    return next();&#xA; });&#xA;....&#xA;app.get(&#39;admin/login&#39;, (req,res) =&gt; {&#xA;    // TODO&#xA;});حال هر درخواستی که از مسیر /admin گذر کند اول این لاگ چاپ میشود.میدلویر ها کاربردهای زیادی دارند به طور مثال میتوان از آنها برای محدود کردن سطوح دسترسی استفاده کرد.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Wed, 26 Jun 2019 20:35:46 +0430</pubDate></item><item><title>پیکربندی (Configuration) در Express JS</title><link>https://virgool.ir/JavaScript8/پیکربندی-configuration-در-express-js-dihiazwfkeef</link><description>configuration in express jsمتد های ()app.set و ()app.getمتد (app.set(name,value دو ورودی دریافت میکند : نام و مقدار و همانطور که از نامش پیداست value را برای name تعیین میکند. به طور مثال میخواهیم پورتی که قرار است اپلیکیشن ما روی آن اجرا شود را مشخص کنیم : app.set(&#39;port&#39;,3000);&#xA;// or&#xA;app.set(&#39;port&#39;, process.env.PORT || 3000);در رابطه با process.env بعدا صحبت خواهیم کرد.مجبور نیستیم نامی که به این متد میدهیم حتما در تنظیمات Express js موجود باشد، این نام میتواند کاملا دلخواه هم باشد.برای دریافت value که قبلا برای یک نام تنظیم کرده ایم میتوانیم به شیوه های زیر عمل کنیم :app.set(name);  // with a single parameter&#xA;// or&#xA;app.get(name);توجه داشته باشید در صورتی که بخواهید از ()app.set برای دریافت مقدار استفاده کنید تنها باید پارامتر نام را ارسال کنید.متد های ()app.enable و ()app.disableهمانطور که گفته شد میتوانیم با متد ()app.set هر مقداری را برای یک name ذخیره کنیم ، به طور مثال : app.set( &#39;foo&#39; , true);&#xA;// or&#xA; app.set( &#39;foo&#39; , false);در این مواقع که میخواهیم Value ای برای یک name ذخیره کنیم که از جنس Boolean است (True یا False )‌ میتوانیم به این شکل عمل کنیم که :// Set TRUE&#xA;app.enable( &#39;foo&#39; );&#xA;&#xA;// Set False&#xA;app.disable( &#39;foo&#39; );متدهای ()app.enabled و ()app.disabledبرای اینکه چک کنیم مقدار foo ( که در مثال بالا ذکر شد ) TRUE یا FALSE است میتوانیم از متد های زیر استفاده کنیم :‌app.disabled(&#39;foo&#39;)&#xA;app.enabled(&#39;foo&#39;)اگر foo مقدار false را داشته باشد (&#39;app.disabled(&#39;foo مقدار true برمیگرداند.در ضمن خوشحال میشوم دیدگاه شما را راجع به این پست بدونم.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Tue, 25 Jun 2019 20:52:14 +0430</pubDate></item><item><title>اولین برنامه با Express</title><link>https://virgool.ir/JavaScript8/اولین-برنامه-با-express-psz8zfld9ocg</link><description>Hello World in Express JSدر این قسمت یاد میگیریم که چگونه عبارت Hello world را با Express js چاپ کنیم.یک فایل ‌hello.js درست میکنیم که قرار است برای ما نقش سرور را بازی کند.کتابخانه ی اکسپرس را Load میکنیم.var express = require(&#39;express&#39;);&#xA;var app = express();برنامه ای که نوشتیم باید روی یک port اجرا شود. از پورت 3000 استفاده میکنیم. (در پست های بعدی به شما آموزش میدهم که چگونه یک فایل ENV درست کنیم و Config های Application را آنجا ذخیره کنیم.)var port = 3000;حال یک Route با WildCard  * تعریف میکنیم : app.get( &#39;*&#39;, function(req, res){&#xA;    res.end(&#39;Hello World&#39;); &#xA;});تابع app.get به عنوان پارامتر اول، یک Regular عبارات منظم) می پذیرد ( یک الگو را به عنوان ورودی می پذیرد و این الگو را با پارامتر اول Route های تعریف شده چک میکند تا به اولین انطباق برسد، در رابطه با ‌Route ها بیشتر صحبت خواهیم کرد ) ما در اینجا از Asterisk (*) استفاده کردیم که به معنای تمام الگوهای ممکن است.پارامتر دوم این تابع یک Request Handler است که با آن میتوانیم Request و Response ها را مدیریت کنیم.( مشابه با Callback که در Nodejs برای متد http.createServer مینویسیم!!! )بیشتر :‌ Request Handler یک تابع است که هنگامی سرور یک درخواست دریافت میکند اجرا میشود.در اکسپرس هر Request Handler حداقل دو پارامتر ورودی دریافت میکند: یک Request و یک Responseدر ادامه بیشتر در مورد ‌Request Handler صحبت خواهیم کرد.حال از پورت تعریف شده استفاده میکنیم و برنامه را اجرا میکنیم.app.listen(port, function(){ &#xA;    console.log(&#39;The server is running, &#39; + &#39; please, open your browser at http://localhost:%s&#39;,&#xA;    port);&#xA;});حال برای اجرای اسکریپ، ترمینال را در همان فولدری که اسکریپت را نوشته ایم باز میکنیم و دستور زیر را مینویسم :node hello.jsمرورگر را باز کرده و به آدرس Localhost:3000 بروید، Hello World شما آماده است.کد :var express = require(&#39;express&#39;); &#xA;var port = 3000;&#xA;var app = express(); &#xA;app.get( &#39;*&#39;, function(req, res){&#xA;    res.end(&#39;Hello World&#39;);&#xA;});&#xA;app.listen(port, function(){&#xA;     console.log(&#39;The server is running, &#39; + &#39; please, open your browser at http://localhost:%s&#39;,     port);منتظر پست های بعدی باشید.</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Sun, 23 Jun 2019 21:42:16 +0430</pubDate></item><item><title>مقدمه ای بر اکسپرس جی اس</title><link>https://virgool.ir/nodejs/مقدمه-ای-بر-اکسپرس-جی-اس-f389tbbyz8w0</link><description>Express JSاکسپرس جی اس چیست ؟ یک وب فریم ورک است که برپایه ی Node_js# ساخته شده است و از آنجا که ساختن دوچرخه از ابتدا کار عاقلانه ای نیست و بهتر است که همان دوچرخه ی ساخته شده را بهتر کنیم برای توسعه وب سایت با استفاده از تکنولوژی #node_js از این فریم ورک استفاده میکنیم.در اکپرس شما در انتخاب پکیج هایی که به آنها نیاز دارید مختار هستید و این انعطاف پذیری این فریم ورک را ارتقا میدهد. به طور مثال برای انتخاب یک template engine دست شما کاملا باز است.هنگامی که یک برنامه‌ی Express اجرا میشود، express به درخواست های شما گوش میدهد و وضعیت انطباق هر در خواست شما را  با Route و middleware ها به ترتیب خطوط نوشته شده از بالا به پایین بررسی میکند.بررسی از بالا به پایین یکی از جنبه های مفید express است که به شما اجازه میدهد تا کنترل بیشتری بر روی جریان داده ها داشته باشید.به طور مثال‌:parse کردن کوکی هاparse کردن پارامتر های Routeدریافت اطلاعات احراز هویت از دیتابیس.ایجاد برنامه‌ی Hello World در پست های بعدی.#express#js#node</description><category>حسام جعفرزاده</category><author>حسام جعفرزاده</author><pubDate>Sat, 22 Jun 2019 23:40:48 +0430</pubDate></item></channel></rss>