<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های جواد مسعودیان</title>
        <link>https://virgool.io/feed/@javad.masoudian</link>
        <description>Frontend Developer at Delino</description>
        <language>fa</language>
        <pubDate>2026-06-16 18:01:52</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/33770/avatar/Su0Wwh.jpg?height=120&amp;width=120</url>
            <title>جواد مسعودیان</title>
            <link>https://virgool.io/@javad.masoudian</link>
        </image>

                    <item>
                <title>چطور logic پروژمون رو بین React و React Native باید share کنیم؟</title>
                <link>https://virgool.io/iran-react-community/%DA%86%D8%B7%D9%88%D8%B1-logic-%D9%BE%D8%B1%D9%88%DA%98%D9%85%D9%88%D9%86-%D8%B1%D9%88-%D8%A8%DB%8C%D9%86-react-%D9%88-react-native-%D8%A8%D8%A7%DB%8C%D8%AF-share-%DA%A9%D9%86%DB%8C%D9%85-ahbo66zufc2n</link>
                <description>وقتی React Native کد میزنین انتظار دارین که بعد از تموم شدن پروژه بتونین به راحتی خروجی پلتفرم Android و IOS رو بگیرین.پس حتما انتظار اینم دارین با کمترین زمان، نسخه وب پروژتون رو هم بنویسین و از همه مهم تر اینکه توسعه پروژه وب و موبایلتون در آینده به سادگی تغییر چند خط کد باشهخب اول از همه باید بدونین چه بخش هایی رو میشه بین React و React Native پروژتون share کنینConfigAPIsRedux Custom HooksForm ValidationsHelpersThemesTypescriptsبخش Configدر بخش config پروژتون base API URL، اسم پروژه و هر متغییر ثابتی که بین وب و موبایلتون مشترکه رو میتونین اینجا بنویسینبخش API هادر این بخش برای هر entity در پروژتون فایل مشخص به خودش رو بسازین و API هایی که از بچه های گل بک اند گرفتین رو اینجا تعریف کن، من در این بخش از کتابخونه Axios استفاده کردم، برای مثال یه فایل به نام auth.js ساختم و داخل اون API های لاگین و فراموشی کلمه عبور و ... رو تعریف کردم.بخش Reduxریداکس برای share کردن logic پروژتون بدون وابستگی به کامپوننت‌ها خیلی میتونه کمک کنه، میشه از روش های دیگه ای هم واسه handle کردن state هاتون استفاده کنین، ولی debug کردن state ها با ریداکس مثه آب خوردنهبخش Custom Hooksمن این بخش رو خیلی دوست دارم، بعد از اینکه هوک متولد شد، پروژه های من به طرز عجیبی ساده و خوانا تر شدن (clean code رو میزاره توی جیبش لامصب)هوک‌ها برای نوشتن logic یه کامپوننت میتونن خیلی بهتون کمک کنن، به راحتی میتونین state‌ها وlifecycle  یه کامپوننت رو از توی دل اون بکشید بیرون و در یه فایل مجزا logic اش رو برنامه نویسی کنین. برای مثال میتونین برای بخش لاگین پروژتون یه هوک به اسم useLogin بنویسین و تمام فیلدهای فرم لاگینتون رو در قالب یه state‌ تعریف کنین، همچنین میتونین  و   فرم اتون رو همینجا بنویسین، که خود  میتونه شامل validation فرم و فراخوانی API لاگینتون باشه.بخش Validation های فرمبا توجه به اینکه API هاتون بین وب و موبایل share شده، پس تمام attribute های entity پروژتون بین React و React Native مشترکه و از طرفی تمام فیلدهاتون در فرم مشترک میشه، خب پس میتونین validation های فرم تون رو یه جا بنویسین و اونا رو share کنین (من از کتابخونه Yup برای نوشتن validation هام استفاده میکنم)بخش Helper هادر این بخش میتونین توابع کمکی پروژتون رو بنویسین، برای مثال توابعی که نیازه روی string یا array هاتون فیلتر خاصی اعمال کنین، یه helper خیلی مهم که من توی پروژم باهاش درگیر شدن، هلپری واسه storage بود، این هلپر رو نمیشه بیرون share نوشت واسه اینکه redux و hook هاتون بهش احتیاج دارن، پس با یه کلک مرغابی میتونین همه جا یک جور import هاتون رو بنویسین ولی در صورتی که چیزی که دارین import میکنین، webpack با توجه به پلتفرم مورد نظر فایل خودش رو داره فراخوانی میکنهدر بخشhelpers  یه دایرکتوری به اسم storage بسازین و سه تا فایل زیر رو اونجا قرار بدینIndex.android.jsIndex.ios.jsIndex.jsدرون دو فایل اول که React Native با توجه به پلتفرم اونا رو فراخوانی می‌کنه از کتابخانه @react-native-community/async-storage استفاده کنین و در فایل آخر که برای وب عه از localStorage استفاده کنین.بخش Themeاگر پروژتون شامل چندین theme مختلف عه میتونین پالت رنگ و فونت هاتون رو اینجا تعریف کنینبخش Typescriptاگه از تایپ اسکریپت هم استفاده می‌کنین که type و interface هاتون رو اینجا تعریف و export کنینحالا ممکنه واستون سوال بشه که این بخش هارو کجای پروژه وب و موبایلتون باید قرار بدیناین بخش رو مثل یه ریپو مجزا فرض کنین، برای مثال یه repository به اسم share در گیت لب و یا گیت هاب خودتون بسازین و در root پروژه وب و موبایلتون از اون clone بگیرینچند تا نکته ریز:-	توی پروژه وب و موبایلتون در فایل gitignore دایرکتوری share که در root پروژتون هست رو ignore کنین، چون share خودش یه ریپو مستقله، و اگه تغییری روش دادین به صورت مستقل باید تغییراتش رو commit کنین-	نیازی به package.json واسه پروژه share نیست، چون این repository در root پروژه وب و موبایلتون قرار میگیره و از package.json اون‌ها استفاده میکنه-	پکیج هایی که در بخش‌های share استفاده کردین رو در فایل README لیست کنین تا برنامه‌نویس  وب و موبایلتون پکیج های پروژه share رو روی پروژه خودش نصب کنه</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Fri, 10 Jan 2020 16:45:09 +0330</pubDate>
            </item>
                    <item>
                <title>حذف render اضافی کامپوننت‌های ری‌اکت با batch</title>
                <link>https://virgool.io/iran-react-community/%D8%AD%D8%B0%D9%81-render-%D8%A7%D8%B6%D8%A7%D9%81%DB%8C-%DA%A9%D8%A7%D9%85%D9%BE%D9%88%D9%86%D9%86%D8%AA%D9%87%D8%A7%DB%8C-%D8%B1%DB%8C%D8%A7%DA%A9%D8%AA-%D8%A8%D8%A7-batch-ryiakd75ggoo</link>
                <description>ممکنه به ری رندهای اضافه‌ای که توی کامپوننت‌هاتون هر بار داره رخ میده خیلی دقت نکرده باشین، ولی اینو بدونین که اگه دو تا useState رو پشت سر هم صدا بزنین، اولی اجرا میشه، بعد کامپوننت ری رندر میشه و بعد دومی اجرا میشه و باز کامپوننت رو مجددا ری رندر میکنه، خب راه حل‌های مختلفی واسه افزایش پرفرمنس این موضوع وجود داره.یک سری افراد هنوز دید state کلاس کامپوننت‌ها رو دارن و با hook غریبن و میگن state هاتونو اینطوری تعریف کنین.یک سری افراد هم میگن از useReducer استفاده کنین که احساس میکنم همون داستان بالا میشهمن این مشکل رو قبلا توی dispatch کردن ریداکس داشتم که در انتها راه حل اونم با مثال اوردم، ولی بعد از صحبت با ادی متوجه شدم که این API اول واسه خود react بوده و بعداْ ریداکس ازش استفاده کرده، به این شکل که ReactDOM یه API واسه این کار نوشته که طرز استفادش به شکل زیره که هر چندتا setState ای که می‌خوایی همزمان با هم اجرا کنی و در نهایت یکبار کامپوننتت ری رندر بشه رو توی کال بک این API باید بنویسی.فقط یه نکته اینکه این API الان unstable عه و ممکنه توی نسخه‌های بعدی حذف بشه و به خود react core اضافه بشه، پس بهتره یه جای دیگه مثلا توی helper هامون واسش یه فانکشن تعریف کنیم، تا هر موقع حذف شد و جایگزینش API دیگه ای نوشته شد، تنها اون helper رو آپدیت کنیم.اگه از ریداکس استفاده می‌کنید اونجا هم batch رو داریم، این زیر یه مثال ازش زدم.اون useDispatch و useSelector هم اگه واستون جدیده همینجا توی ویرگول راجبش یه مقاله نوشتم. https://virgool.io/iran-react-community/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-hook-%D9%87%D8%A7-%D8%AF%D8%B1-redux-nhvbbmc8g0rc </description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Fri, 30 Aug 2019 22:48:33 +0430</pubDate>
            </item>
                    <item>
                <title>اکستنشن تبدیل Class کامپوننت به Function کامپوننت (Hook)</title>
                <link>https://virgool.io/iran-react-community/%D8%A7%DA%A9%D8%B3%D8%AA%D9%86%D8%B4%D9%86-%D8%AA%D8%A8%D8%AF%DB%8C%D9%84-class-%DA%A9%D8%A7%D9%85%D9%BE%D9%88%D9%86%D9%86%D8%AA-%D8%A8%D9%87-function-%DA%A9%D8%A7%D9%85%D9%BE%D9%88%D9%86%D9%86%D8%AA-hook-pidpkk5onquk</link>
                <description>نیاز من به چنین اکستنشی از جایی شروع شد که بهم یه پروژه‌ی قدیمی React ای رو دادن و گفتن اون رو توسعه بده، من چند ماهی میشه که دارم از Hook ها استفاده میکنم و دیگه از bind کردن function ها و this.setState کردن خسته شدم، واسه همین تصمیم گرفتم پروژه رو به ساختار Hook ها refactor کنم، از طرفی هم، زمان کافی واسه این refactor کردن ندارم، اول خواستم خودم دست به کار بشم و واسه این کار یه اکستشن بنویسم، ولی گفتم قبلش یه سرچی بزنم توی نت ببینم چیزی پیدا میشه، که بلللله، به قول پسرداییم: همیشه یه نفر پیدا میشه که قبل از تو به اون فکر کرده، اسم این اکستنشن دوست داشتی Glean عه که واسه VSCode نوشته شدهفقط برای اینکه از Hook پشتیبانی کنه باید بعد از نصب این اکستنشن، کانفیگ زیر رو انجام بدینFile &gt; Preferences &gt; Settingsحالا اون بالا کلمه glean رو سرچ کنین، مورد اول که نوشته Glean: Experiments یه خرده پایین ترش نوشته Edit in settings.json ، روش کلیک کنید و خط زیر رو به فایل json اضاف کنین.&quot;glean.experiments&quot;: [&quot;hooksForFunctionalComponents&quot;]بعد از کانفیگ بالا و کانورت کردن، اگه سیستم عاملتون ویندوز باشه به خطا میخورید، که من اینجا یه pull request دادن و منتظر تایید شدنشم. (خب الان تایید شد و یه نسخه ریلیز جدید دادن)حالا یکی از فایل‌های پروژتون که Class کامپوننت نوشتین رو باز کنین و از قسمتی که کلمه Class شروع میشه تا انتهای کاراکتر &quot;{&quot; که کلاس کامپوننت شما تموم میشه رو Select کنید، به کلمه Class اسکرول کنید و میبینید که یه چراغ زرد رنگ ظاهر شده، روش کلیک کنید و Convert Class to Function رو کلیک کنید.Converting Stateful Component to Functional Componentاین اکستنشن یه ابزار جالب دیگه هم داره که میتونید قسمتی از کامپونتت رو جدا کنید و ازش یه کامپوننت جدید بسازید و بعد خودش import اش میکنهExtract to fileاینم آدرس اکستنشن: https://marketplace.visualstudio.com/items?itemName=wix.glean</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Mon, 12 Aug 2019 22:24:54 +0430</pubDate>
            </item>
                    <item>
                <title>سوالات جاوا اسکریپتی برای مصاحبه (قسمت ۱)</title>
                <link>https://virgool.io/JavaScript8/%D8%B3%D9%88%D8%A7%D9%84%D8%A7%D8%AA-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%85%D8%B5%D8%A7%D8%AD%D8%A8%D9%87-%D9%82%D8%B3%D9%85%D8%AA-%DB%B1-hcrzedirdzd8</link>
                <description>لینک زیر که حدود 90 سوال چالشی ایه جاوا اسکریپته رو دوست خوبم حمیدرضا جان برای من ارسال کردن و من تصمیم گرفتم در چند قسمت این سوالات رو برای شما دوستان خوبم ترجمه کنم.https://github.com/lydiahallie/javascript-questionsاگه مصاحبه‌ی یکی از شرکت‌های بزرگ (چه ایرانی و چه غیرایرانی) رو رفته باشین، از همین سوالات js core ای ازتون سوال میپرسنپاسخ سوالات رو در انتهای مقاله نوشتم.توی کامنت‌ها بهم بگین که اگه واستون مفید بوده ادامه سوالات رو ترجمه کنم یا چی؟سوال اول: خروجی کد زیر بنظرتون کدوم گزینه میشه؟ https://gist.github.com/2012mjm/604fa78f29ca082b8a5c7a5da666c9a1 A: Lydia and undefinedB: Lydia and ReferenceErrorC: ReferenceError and 21D: undefined and ReferenceErrorسوال دوم: خروجی این یکی کد کدوم گزینست ؟ https://gist.github.com/2012mjm/75267606418fb8b3a7b025a7a232f40a A: 0 1 2 and 0 1 2B: 0 1 2 and 3 3 3C: 3 3 3 and 0 1 2سوال سوم: بازم خروجی این یکی کد کدوم گزینست ؟ https://gist.github.com/2012mjm/7e238564c99c802f92e1b442fa927ef2 A: 20 and 62.83185307179586B: 20 and NaNC: 20 and 63D: NaN and 63سوال چهارم: خروجی چیه ؟ https://gist.github.com/2012mjm/9e2b758dd5562c9f2512297d490d1ffe A: 1 and falseB: false and NaNC: false and falseسوال پنجم: کدام یک از گزینه‌ها درست است؟ https://gist.github.com/2012mjm/9ddb0aea847098e6f02b7743ebfecb98 A: mouse.bird.size is not validB: mouse[bird.size] is not validC: mouse[bird[&quot;size&quot;]] is not validD: All of them are validسوال ششم: خروجی کد زیر چی میشه؟ https://gist.github.com/2012mjm/32039598fc8e20f577f6395e3bb1890c A: HelloB: Hey!C: undefinedD: ReferenceErrorE: TypeErrorسوال هفتم: خروجی کدومه؟ https://gist.github.com/2012mjm/66b4098ef63452d3f416b25887b0d335 A: true false trueB: false false trueC: true false falseD: false true trueسوال هشتم: خروجی ؟ https://gist.github.com/2012mjm/11c6161eec08b16a89a23682b70167b5 A: orangeB: purpleC: greenD: TypeErrorسوال نهم: خروج؟ https://gist.github.com/2012mjm/3e14389cc0fcd94601dd5ea1738669a9 A: {}B: ReferenceError: greetign is not definedC: undefinedسوال دهم: خ؟ https://gist.github.com/2012mjm/9433b1b10b82e83aa9b7a15f79847d8e A: Nothing, this is totally fine!B: SyntaxError. You cannot add properties to a function this way.C: &quot;Woof&quot; gets logged.D: ReferenceErrorخب حالا میریم سراغ پاسخ سوالاتجواب سوال اول گزینه D میشهدر کنسول لاگ اول، جاوا اسکریپت سعی داره مقدار متغیر name رو لاگ کنه و چون هنوز تعریف نشده، میگرده ببینه جایی تعریفش کردین یا نه، خب میبینه اون پایین یه متغیر از نوع var با نام name ایجاد شده، پس واسه name مقدار undefined رو لاگ میکنه (چون هنوز به خط انتصاب مقدارش نرسیده)، در کنسول لاگ دوم بازم جاوا اسکریپت تلاش میکنه متغیر age رو چاپ کنه، ولی باز میگه مرد حسابی منو مسخره کردی، اینم خو هنوز تعریف نکردی، ولی خب وظیفش اینکه بگرده ببینه جایی پایین تر تعریفش کردی یا نه، خب میبینه این متغیر از اون نوع let تعریف شده، ولی برخلاف متغیرهای var مقدار undefined رو چاپ نمیکنه بلکه ReferenceError میده، چون میگه باید قبلش تعریفش میکردی، یه نکته هم اینکه رفتار const هم شبیه let میمونهجواب سوال دوم گزینه C میشهبه این دلیل که جاوا اسکریپت به صورت event queue کار میکنه، دستورات درون callback function در setTimeout بعد از loop اجرا میشن، در loop اول نوع متغیر i از جنس var تعریف شده، در نتیجه این متغیر به صورت global تعریف میشه، پس در مرحله‌ی آخر loop مقدار 3 رو به خودش میگیره و در نهایت setTimeout سه بار 3 رو نمایش میده، در loop دوم نوع متغیر این بار از جنس let تعریف شده، و این نوع متغیر اصطلاحاً block-scoped عه و در بین همون آکولادهای loop فقط زنده میمونه، و هر سری مقدار هر step رو نمایش میده، const هم شبیه let عمل میکنه.جواب سوال سوم گزینه B میشهبه تابع diameter میگن regular function و به تابع perimeter میگن arrow function، در arrow function ها، کلمه‌ی this به scope خودش اشاره میکنه، نه به shape objectجواب سوال چهارم گزینه A میشهاون علامت + پشت true تلاش میکنه یک عملوند رو به عدد تبدیل کنه، true میشه 1 و false میشه 2رشته‌ی Lydia یک مقدار درست و صحیح محسوب میشه، حالا ما با علامت تعجب پشتش داریم ازش میپرسیم که آیا این مقدار درستی که داری، یک مقدار اشتباست؟ که منطقاً جواب false میده بهمونجواب سوال پنجم گزینه A میشهدر جاوا اسکریپت، تمام کلیدهای object از نوع رشته‌ای هستند (مگر اینکه Symbol باشند). حتی اگر ما کلید‌ها رو به صورت یک رشته تعریف نکنیم باز اونا رو به زیر رشته تبدیل میکنه.گزینه B به این صورت تفسیر میشه که ابتدا مقدار bird.size را بدست میاره که میشه small و سپس مقدار [&quot;mouse[&quot;small که میشه true رو برمیگردونه، گزینه C هم به همین صورتهاما در این صورت مسئله، علامت dot در گزینه A به ما جواب درستی نمیده، چون mouse.bird به ما undefined رو برمیگردونه و بعد میگه undefined.size که یک دستور اشتباست و مفسر خطا میدهجواب سوال ششم گزینه A میشهدر جاوا اسکریپت همه‌ی object ها به وسیله‌ی reference با هم تعامل دارن، در متغیر c ما یک آبجکت رو با reference اون نگه داشتیم، حالا وقتی مقدار c رو توی d میریزید عین این میمونه d هم به همون آبجکت متصل شدهوقتی شما یک object رو تغییر بدید، همه‌ی اون‌ها رو تغییر دادید.جواب سوال هفتم گزینه C میشهنوع new Number یک built-in function constructor عه، در نگاه اول یک عدد به نظر میرسه ولی واقعاً یک عدد نیست، و این یه سری ویژگی‌های اضافی داره و همینطور یک object عه، وقتی از == استفاده می‌کنید فقط دارید مقدارشون رو بررسی میکنید که هر دو 3 هستن ولی وقتی از === استفاده می‌کنید هم مقدارش و هم نوعش رو بررسی میکنید.جواب سوال هشتم گزینه D میشهتابع colorChange یک تابع static عه و نمیتونید از طریق child بهش برسید، بنابراین freddie یک child عه و تابع colorChange در این شرایط در در دسترس نیست.جواب سوال نهم گزینه A میشهبه کد صورت مسئله خوب دقت کردید؟ ... اولی greeting و دومی greetign، ولی جاوا اسکریپت مقدار اون رو به درستی چاپ میکنه و خطایی رخ نمیده، جاوا اسکریپت اون رو به صورت global.greetign یا window.greetign با مقدار یک empty object در نظر میگیره، اگه میخوایید به جاوا اسکریپت اجبار کنید که متغیرهامون حتما type داشته باشن باید از کلمه کلیدی use strict استفاده کنید.جواب سوال دهم گزینه A میشهتعجب نکنید! چنین چیزی در جاوا اسکریپت امکان پذیره، زیرا function ها یک نوع خاصی از object ها هستند. (همه چیز در کنار primitive type ها یک نوع object هستند.)</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Fri, 26 Jul 2019 19:11:10 +0430</pubDate>
            </item>
                    <item>
                <title>سایت React چندزبانه با استفاده از کتابخانه i18next</title>
                <link>https://virgool.io/iran-react-community/%D8%B3%D8%A7%DB%8C%D8%AA-react-%DA%86%D9%86%D8%AF%D8%B2%D8%A8%D8%A7%D9%86%D9%87-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%DA%A9%D8%AA%D8%A7%D8%A8%D8%AE%D8%A7%D9%86%D9%87-i18next-yyornggfc44j</link>
                <description>I18next is an internationalization-framework written in and for JavaScript. But it&#x27;s much more than that. i18next goes beyond just providing the standard i18n features such as (plurals, context, interpolation, format). It provides you with a complete solution to localize your product from web to mobile and desktop.نصبyarn add i18next react-i18nextکانفیگیک فایل برای مثال در root پروژه به نام locale.js برای کانفیگ i18next ایجاد کنید.import i18n from &#039;i18next&#039;;
import { initReactI18next } from &#039;react-i18next&#039;;
import HomeLocale from &#039;../scenes/Home/Home.locale&#039;;

i18n
  .use(initReactI18next) // pass the i18n instance to react-i18next.
  .init({
    resources: {
      ...HomeLocale // merge Home locale to i18n resource
      // add other translation to the array
    },
    lng: &#039;en_US&#039;, // default language
    fallbackLng: &#039;en_US&#039;,
    debug: false,
    interpolation: {
      escapeValue: false // not needed for react as it escapes by default
    }
  });
export default i18n;برای option های بیشتر به آدرس https://www.i18next.com/overview/configuration-options سری بزنید.حالا این کانفیگ رو در فایل Main پروژتون import کنید، برای مثال Main پروژه من App.js اِimport &#039;./locale.js&#039;;ترجمه‌هامن فایل ترجمه هر کامپوننت رو در کنار خود اون با پسوند locale.js قرار دادم، برای مثال کامپوننت Home یک فایل در کنار خودش با نام Home.locale.js داره که به شکل زیر عبارت‌های مورد نیازم رو درون اون ترجمه کردم.export default {
  fa_IR: {
    home: {
      &#039;Welcome to Virgool&#039;: &#039;به ویرگول خوش آمدید&#039;,
      &#039;Your messages: {{message_count}}&#039;: &#039;تعداد پیام‌های شما: {{message_count}}&#039;
    }
  },
  // add other language to the object
};نکته: خود i18next در داکیومنتش گفته که برای هر عبارتی که نیاز به ترجمه داره یک کلید تعریف کنید، به عنوان نمونه بنویسید welcome_virgool ولی اگه به فایل ترجمه‌ی من نگاه کنید من عین عبارت انگلیسی رو تایپ کردم، من این روش رو خیلی وقت پیش از فریم‌ورک پی اچ پی Yii2 یاد گرفتم، این کار دو مزیت داره، یکی اینکه شما دیگه نیاز به تعریف زبان انگلیسی ندارید و i18next در زبان انگلیسی خود کلید رو نمایش میده و مزیت دیگه‌ای که داره اینکه اگه نفر بعدی قصد اضاف کردن زبان جدیدی رو داشته باشه به راحتی با خوندن کلیدها میتونه ترجمش رو انجام بده.فقط دقت داشته باشین که در کانفیگ i18next مقدار lng رو روی en_US تنظیم کنید و در App.js یا فایل main پروژه زبان رو روی زبان پیشفرض تنظیم کنید (بعداً میگم از طریق چه تابعی میتونید زبان رو change کنید) بازم میگم که این روشی که من رفتم از طریق lng نمیتونید زبان پیشفرض رو تنظیم کنید و حتما باید روی en_US تنظیم بشه.طرز استفادهimport { useTranslation } from &#039;react-i18next&#039;;

const Home = () =&gt; {
  const {t, i18n} = useTranslation([&#039;home&#039;]); // &amp;quothome&amp;quot is namespace
  
  // To manually change language
  // i18n.changeLanguage(&#039;fa_IR&#039;);
  
  return (
    &lt;div&gt;
      &lt;h1&gt;{t(&#039;Welcome to Virgool&#039;)}&lt;/h1&gt;
      &lt;p&gt;{t(&#039;Your messages: {{message_count}}&#039;, {message_count: 6})}&lt;/p&gt;
    &lt;/div&gt;
  )
}
export default Home;یه توضیح کوچیک بدم، اگه به خط دوم دقت کنید می‌بینید که use ها به i18next هم رخنه کردن و من ازین بابت بسیار خوشحالم، چون جنس رخنشون خوب بوده، روش HOC هم واسش نوشتن که توی سایت i18next با مثال توضیح داده، به پارامتر useTranslation دقت کنید، این تابع از شما آرایه‌ای از namespace ها رو میگیره، اگه به کد Home.locale.js نگاه کنید می‌بینید که من از کلمه‌ی کلیدی home استفاده کردم و اینجا هم از namespace اش، اولین namespace به عنوان default به i18next برای این کامپوننت تعلق میگیره و ترجمه‌هاشو از نیم اسپیس home میخونه.برای تغییر زبان از تابع changeLanguage میتونید استفاده کنید، این تیکه کد فقط برای یادگیری بیشتره و لازم نیست اینجا زبان رو change کنید، همینطور که پیش‌تر گفتم توی App.js میتونید با این چند خط زبان رو به فارسی که برای مثال زبان default شماست change کنید.detect زبان با استفاده از language detector یه کتابخونه هم واسه detect زبان از طریق مرورگر به نام i18next-browser-languagedetector داره که میتونید به کانفیگ پروژتون اضافش کنید.شما از طرق زیر میتونید زبان رو change کنید.query stringcookielocalStoragenavigatorhtml tagpathsubdomainبرای کانفیگ این مورد به آدرس https://github.com/i18next/i18next-browser-languageDetector یه سر بزنید.</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Thu, 25 Jul 2019 21:12:09 +0430</pubDate>
            </item>
                    <item>
                <title>کانفیگ Redux و Redux-Saga در Next.js</title>
                <link>https://virgool.io/iran-react-community/%DA%A9%D8%A7%D9%86%D9%81%DB%8C%DA%AF-redux-%D9%88-redux-saga-%D8%AF%D8%B1-nextjs-ih1wwrrkfnjs</link>
                <description>در این مقاله قصد دارم نصب و کانفیگ redux و redux-saga رو در فریم‌ورک ری‌اکت Next.js به شما آموزش بدم.نصبyarn add redux react-redux next-redux-wrapper redux-saga next-redux-sagaاگر نیاز به فعال سازی اکستنشن مرورگر redux dev tools را دارید دستور زیر را هم در خط فرمان اجرا کنید.yarn add -D redux-devtools-extensionکانفیگ Storeیک فایل برای مثال در root پروژه خود با نام store.js ایجاد کنید و خطوط زیر رو درون اون بنویسید.import { applyMiddleware, createStore } from &#039;redux&#039;;
import { composeWithDevTools } from &#039;redux-devtools-extension&#039;;
import createSagaMiddleware from &#039;redux-saga&#039;;

import rootReducer from &#039;./reducers&#039;; // combineReducers({..., ...})
import rootSaga from &#039;./sagas&#039;; // yield all([fork(...), ...])

const bindMiddleware = (middleware) =&gt; {
  if (process.env.NODE_ENV !== &#039;production&#039;) {
    return composeWithDevTools(applyMiddleware(...middleware));
  }
  return applyMiddleware(...middleware);
};

const configureStore = (initialState) =&gt; {
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(
    rootReducer,
    initialState,
    bindMiddleware([sagaMiddleware])
  );
  store.sagaTask = sagaMiddleware.run(rootSaga);
  return store;
};
export default configureStore;خب یه توضیح کوتاه راجب کانفیگ بالا بدم.خطوط 1 تا 3 واسه import کتابخانه‌های redux و redux-dev-tools و redux-saga هستندر خط 5 یک فایل با نام reducers رو import کردم که درون این فایل تمامی reducer های من با هم combine شدندر خط 6 یک فایل دیگه برای saga با نام sagas ایمپورت کردم که درون این فایل تمامی saga های پروژه با هم fork شدنمن bindMiddleware رو به صورت یک تابع تعریف کردم، شاید روش دیگه‌ای شما دوست داشته باشین تعریفش کنین، خلاصه ... در صورتی که شما در mode ای غیر از production، برای مثال در حالت development باشید، redux-dev-tools وارد عمل شده و redux شما را تحت شعاع خودش قرار میدهدر ادامه هم که saga middleware رو به middleware های store اضاف و در نهایت create store کردم.اون sagaTask هم که به آبجکت store متصل کردم بعدها بدردمون میخوره.نیم نگاهی به فایل reducers.jsimport { combineReducers } from &#039;redux&#039;;
import userReducer from &#039;../scenes/User/store/User.reducer&#039;;

const rootReducer = combineReducers({
  user: userReducer
  // add other reducers to the array
});
export default rootReducer;و نیم نگاهی به فایل sagas.jsimport { all, fork } from &#039;redux-saga/effects&#039;;
import user from &#039;../scenes/User/store/User.saga&#039;;

/**
  * @description Notice how we now only export the rootSaga,
  *  single entry point to start all Sagas at once.
  * @example rootSaga();
  */
export default function* rootSaga() {
  try {
    yield all([
      fork(user)
      // add other watchers to the array
    ]);
  } catch (e) {}
}کانفیگ Next.jsخب حالا به سراغ کانفیگ Next.js برای Redux می‌ریم، فایل _app.js در دایرکتوری pages رو باز کنید و به شکل زیر اون رو کانفیگ کنید. (اگر این فایل وجود نداره، ایجادش کنید)// /pages/_app.js

import { Provider } from &#039;react-redux&#039;;
import withRedux from &#039;next-redux-wrapper&#039;;
import withReduxSaga from &#039;next-redux-saga&#039;;

import createStore from &#039;../store&#039;;

class MyApp extends App {

  // For Server Side Rendering
  static async getInitialProps({ Component, ctx }) {
    let pageProps = {};
    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps({ context: ctx });
    }
    return { pageProps };
  }
  
  render() {
    const { Component, pageProps, store } = this.props;
    return (
      &lt;Container&gt;
        &lt;Provider store={store}&gt;
          &lt;Component {...pageProps} /&gt;
        &lt;/Provider&gt;
      &lt;/Container&gt;
    );
  }
}
export default withRedux(createStore)(withReduxSaga(MyApp));در مقاله‌های بعدی سعی میکنم تعریف یک action و dispatch کردن اون رو در saga بهتون آموزش بدم و همینطور آموزش dispatch کردن action ها در حالت SSR برای Next.js</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Thu, 25 Jul 2019 19:28:07 +0430</pubDate>
            </item>
                    <item>
                <title>استفاده از Hook ها در Redux</title>
                <link>https://virgool.io/iran-react-community/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-hook-%D9%87%D8%A7-%D8%AF%D8%B1-redux-nhvbbmc8g0rc</link>
                <description>قبل از اینکه react-redux نسخه 7.1.0 اش رو ارائه بده پکیج‌های زیادی واسه کانفیگ hook در ریداکس نوشته شده بود ولی خب با ارئه‌ی نسخه جدید خیلی از این پکیج‌ها از رده خارج شدن، من در این مقاله قصد دارم استفاده از hook ها در redux رو به شما آموزش بدم، اول از همه باید بگم که کانفیگ create store هیچ تغییری نکرده و تنها قابلیت connect در کامپوننت‌‌ها که از مکانیزم HOC یا higher-order component استفاده میکرده رو حذف کرده و گفته که از use های hook استفاده کنید.https://react-redux.js.org/next/api/hooksدو تا فانکشن خیلی کاربردیش useDispatch و useSelector که در ادامه روش استفادش رو واستون توضیح میدم.فانکشن useDispatchاگه قصد دارین از useDispatch استفاده کنید، دور mapDispatchToProps رو خط بکشید، چون دیگه کاربردی واستون نداره.یه مثال سادهimport React from &#039;react&#039;;
import { useDispatch } from &#039;react-redux&#039;;

export const CounterComponent = ({ value }) =&gt; {
  const dispatch = useDispatch();
  return (
    &lt;div&gt;
      &lt;span&gt;{value}&lt;/span&gt;
      &lt;button ={() =&gt; dispatch({ type: &#039;increment-counter&#039; })}&gt;Increment counter&lt;/button&gt;
    &lt;/div&gt;
  )
}فانکشن useSelector همینطور اگه قصد دارین از useSelector استفاده کنید، دور mapStateToProps رو خط بکشید، چون دیگه اینم کاربردی واستون نداره.یه مثال سادهimport React from &#039;react&#039;;
import { useSelector } from &#039;react-redux&#039;;

export const CounterComponent = () =&gt; {
  const counter = useSelector(state =&gt; state.counter);
  return &lt;div&gt;{counter}&lt;/div&gt;
}نکته جالبی که دوستم سعید جان راجب useSelector بهم گفت اینه که این فانکشن قابلیتی مشابه قابلیت memo داره، به این صورت که در شرایطی که value اون counter مثال بالا تغییر کنه، کامپوننت re-render میشه</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Sun, 21 Jul 2019 17:34:22 +0430</pubDate>
            </item>
                    <item>
                <title>ESLint و Prettier برای React</title>
                <link>https://virgool.io/iran-react-community/eslint-%D9%88-prettier-%D8%A8%D8%B1%D8%A7%DB%8C-react-lztrya0tpj6r</link>
                <description>من در ابتدا نصب و کانفیگ ESLint رو به شما آموزش میدم و همچنین بهتون میگم که چطور میتونید قبل از commit کردن روی گیت قوانین ESLint رو به طور خودکار بررسی کنید و بعد از اون به سراغ اکستنشن Prettier میرم و بهتون میگم که چطوری میتونین اون رو با ESLint پروژتون integrate کنید، که با هر بار ذخیره فایل‌های پروژتون تمامی قوانین به طور خودکار اعمال بشهنصب و کانفیگ ESLintESLint is an open source project originally created by Nicholas C. Zakas in June 2013. Its goal is to provide a pluggable linting utility for JavaScript.شما با استفاده از ESLint میتونین دولاپرها رو مقید کنید از یک سری اصول و قوانین در هنگام کد زدن پیروی کنن و از مسیر خارج نشن، به این کار اصطلاحاً Linting می‌گویند.نصبپلاگین‌های ESLint ای مفیدی که من به پروژم اضاف کردم ایناست:eslint-plugin-babeleslint-plugin-css-modules : برای سی‌اس‌اس ماژولeslint-plugin-filenames : برای ساختار و نام فایل‌ها، بهش الگو میدینeslint-plugin-flowtypeeslint-plugin-importeslint-plugin-no-async-without-await : اینم که از اسمش مشخصهeslint-plugin-react : برای خود ری‌اکتeslint-plugin-react-hooks : برای ری‌اکت هوکeslint-plugin-react-redux : برای ریداکسeslint-plugin-redux-saga : برای ریداکس ساگاeslint-plugin-simple-import-sort : برای مرتب سازی ایمپورت‌های خارجی و داخلی پروژتوناگه توی پروژتون از TypeScript استفاده میکنید، دو تا پلاگین زیر بدردتون میخوره@typescript-eslint/eslint-plugin@typescript-eslint/parserبا استفاده از دستور زیر تمامی پلاگین‌ها و پیش‌نیازهای ESLint رو نصب می‌کنیم.yarn add -D eslint babel-eslint eslint-config-react-app eslint-loader eslint-plugin-babel eslint-plugin-react eslint-plugin-css-modules eslint-plugin-filenames eslint-plugin-flowtype eslint-plugin-import eslint-plugin-no-async-without-await eslint-plugin-react-hooks eslint-plugin-react-redux eslint-plugin-redux-saga eslint-plugin-simple-import-sortکانفیگحالا یک فایل با نام .eslintrc در روت پروژتون ایجاد کنید و به شکل زیر ESLint رو کانفیگ کنید.{
  &quot;env&quot;: {
    &quot;browser&quot;: true,
    &quot;es6&quot;: true,
    &quot;node&quot;: true
  },
  &quot;settings&quot;: {
    &quot;react&quot;: {
      &quot;version&quot;: &quot;detect&quot;
    }
  },
  &quot;plugins&quot;: [
    &quot;babel&quot;,
    &quot;react&quot;,
    &quot;react-hooks&quot;,
    &quot;react-redux&quot;,
    &quot;redux-saga&quot;,
    &quot;no-async-without-await&quot;,
    &quot;css-modules&quot;,
    &quot;filenames&quot;,
    &quot;simple-import-sort&quot;
  ],
  &quot;extends&quot;: [
    &quot;react-app&quot;,
    &quot;plugin:react/recommended&quot;,
    &quot;plugin:@typescript-eslint/recommended&quot;,
    &quot;plugin:react-redux/recommended&quot;,
    &quot;plugin:redux-saga/recommended&quot;,
    &quot;plugin:css-modules/recommended&quot;
  ],
  &quot;parser&quot;: &quot;@typescript-eslint/parser&quot;,
  &quot;globals&quot;: {
    &quot;Atomics&quot;: &quot;readonly&quot;,
    &quot;SharedArrayBuffer&quot;: &quot;readonly&quot;
  },
  &quot;parserOptions&quot;: {
    &quot;ecmaFeatures&quot;: {
      &quot;jsx&quot;: true
    },
    &quot;ecmaVersion&quot;: 2018,
    &quot;sourceType&quot;: &quot;module&quot;
  },
  &quot;rules&quot;: {
    &quot;strict&quot;: [&quot;error&quot;, &quot;safe&quot;],
    &quot;no-debugger&quot;: &quot;error&quot;,
    &quot;brace-style&quot;: [ &quot;error&quot;, &quot;1tbs&quot;, { &quot;allowSingleLine&quot;: true  } ],
    &quot;no-trailing-spaces&quot;: &quot;error&quot;,
    &quot;keyword-spacing&quot;: &quot;error&quot;,
    &quot;space-before-function-paren&quot;: [&quot;error&quot;, &quot;never&quot;],
    &quot;spaced-comment&quot;: [&quot;error&quot;, &quot;always&quot;],
    &quot;vars-on-top&quot;: &quot;error&quot;,
    &quot;no-undef&quot;: &quot;error&quot;,
    &quot;no-undefined&quot;: &quot;warn&quot;,
    &quot;comma-dangle&quot;: [&quot;error&quot;, &quot;never&quot;],
    &quot;quotes&quot;: [&quot;error&quot;, &quot;single&quot;],
    &quot;semi&quot;: [&quot;error&quot;, &quot;always&quot;],
    &quot;guard-for-in&quot;: &quot;error&quot;,
    &quot;no-eval&quot;: &quot;error&quot;,
    &quot;no-with&quot;: &quot;error&quot;,
    &quot;valid-typeof&quot;: &quot;error&quot;,
    &quot;no-unused-vars&quot;: &quot;error&quot;,
    &quot;no-continue&quot;: &quot;warn&quot;,
    &quot;no-extra-semi&quot;: &quot;warn&quot;,
    &quot;no-unreachable&quot;: &quot;warn&quot;,
    &quot;no-unused-expressions&quot;: &quot;warn&quot;,
    &quot;max-len&quot;: [&quot;warn&quot;, 80, 4],
    &quot;react/prefer-es6-class&quot;: &quot;warn&quot;,
    &quot;react/jsx-boolean-value&quot;: &quot;warn&quot;,
    &quot;react-hooks/rules-of-hooks&quot;: &quot;error&quot;,
    &quot;react-hooks/exhaustive-deps&quot;: &quot;warn&quot;,
    &quot;@typescript-eslint/indent&quot;: [&quot;error&quot;, 2],
    &quot;@typescript-eslint/no-explicit-any&quot;: &quot;off&quot;,
    &quot;react/prop-types&quot;: &quot;off&quot;,
    &quot;react-redux/mapDispatchToProps-returns-object&quot;: &quot;off&quot;,
    &quot;react-redux/prefer-separate-component-file&quot;: &quot;off&quot;,
    &quot;@typescript-eslint/explicit-function-return-type&quot;: [ &quot;warn&quot;, { &quot;allowExpressions&quot;: true } ],
    &quot;no-async-without-await/no-async-without-await&quot;: &quot;warn&quot;,
    &quot;css-modules/no-undef-class&quot;: &quot;off&quot;,
    &quot;filenames/match-regex&quot;: [
      &quot;error&quot;,
      &quot;^[a-zA-Z]+\\.*\\b(typescript|module|locale|validate|test|action|api|reducer|saga)?\\b$&quot;,
      true
    ],
    &quot;filenames/match-exported&quot;: &quot;off&quot;,
    &quot;filenames/no-index&quot;: &quot;error&quot;,
    &quot;simple-import-sort/sort&quot;: &quot;error&quot;
  }
}اجازه بدین قبل از اینکه بریم سراغ مرحله بعد یه توضیح کوتاهی راجب کانفیگ بالا بدم.قسمت plugins که مشخصه، همون لیستی ایه که اون بالا معرفی کردم، شما از طریق extends میتونید یکسری rule هایی که خود پلاگین‌ها به صورت پیشنهادی نوشتن رو به rule های پروژتون extend کنید.قسمت parserOptions برای اینکه بهش بگین من از ecmaVersion 2018 استفاده میکنم و قسمت مهم داستان هم rule هاست که از طریق سه نوع type با نام‌های error، warn و off می‌تونید سطح اجباری بودن و نبودن و rule هارو تعیین کنید.یکی از rule هایی که شاید فقط مختص پروژه خودم باشه و خودمم خیلی دوسش دارم رو اجازه بدین واستون یه توضیح کوتاهی راجبش بدم، رول filenames/match-regex که با استفاده از یک الگوی مشخص بهش میگین که نام فایل‌های پروژم از این ساختار خارج نشه، برای مثال نام چندتا از فایل‌های من به این شکله:Login.tsxLogin.module.scssLogin.locale.tsxLogin.reducer.tsx...کانفیگ اسکریپت ESLint در package.json{
  &quot;scripts&quot;: {
    &quot;lint&quot;: &quot;./node_modules/.bin/eslint src --ext .js,.jsx,.ts,.tsx&quot;,
    &quot;lint:fix&quot;: &quot;./node_modules/.bin/eslint src --ext .js,.jsx,.ts,.tsx --fix&quot;
  }
}طرز استفاده از اسکریپت بالا در خط فرمان به این شکلهyarn lint
yarn lint:fix
// OR
npm run lint
npm run lint:fixکانفیگ ESLint برای pre-commitشما با استفاده از pre-commit میتونید به صورت خودکار قوانین ESLint رو قبل از اینکه دولاپری بخواد کامیتش رو انجام بده بررسی کنید و اگه error ای در قوانین باشه جلوی کامیتش رو بگیرید.&quot;scripts&quot;: {
  &quot;precommit-msg&quot;: &quot;echo &#039;Pre-commit checks...&#039; &amp;&amp; exit 0&quot;
},
&quot;pre-commit&quot;: [
  &quot;precommit-msg&quot;,
  &quot;lint&quot;
]نصب و کانفیگ PrettierPrettier is an opinionated code formatter. It enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary.اکستنشن Prettier برای VSCodehttps://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscodeخط فرمان Prettieryarn add -D prettier-eslint-cli کانفیگ اسکریپت Prettier در package.json{
  &quot;scripts&quot;: {
    &quot;prettier&quot;: &quot;./node_modules/.bin/prettier-eslint \&quot;src/**/*.tsx\&quot;&quot;,
    &quot;prettier:fix&quot;: &quot;./node_modules/.bin/prettier-eslint --write \&quot;src/**/*.tsx\&quot; \&quot;src/**/*.ts\&quot;&quot;,
  }
}طرز استفاده از اسکریپت بالا در خط فرمان به این شکلهyarn prettier
yarn prettier:fix
// OR
npm run prettier
npm run prettier:fixکانفیگ VSCode برای ESLint و Prettierفایل زیر رو در روت پروژه ایجاد و خطوط زیر رو در اون اضاف کنید..vscode/settings.json{
  &quot;prettier.eslintIntegration&quot;: true,
  &quot;editor.formatOnSave&quot;: true
}خط اول برای integration اکستنشن Prettier با ESLint و خط دوم برای اینکه بعد از هر بار فشردن کلیدهای Ctrl + S اکستنشن Prettier به طور خودکار اجرا بشه.اگه سوالی راجب rule های ESLint من داشتین، میتونید در قسمت کامنت‌ها ازم بپرسین</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Sun, 21 Jul 2019 11:42:06 +0430</pubDate>
            </item>
                    <item>
                <title>چانک کردن Sass فایل‌ها در Next.js</title>
                <link>https://virgool.io/iran-react-community/%DA%86%D8%A7%D9%86%DA%A9-%DA%A9%D8%B1%D8%AF%D9%86-sass-%D9%81%D8%A7%DB%8C%D9%84%D9%87%D8%A7-%D8%AF%D8%B1-nextjs-nltrflldidyn</link>
                <description>در پروژه جدید خودم و سعید تصمیم گرفتیم که از فریم‌ورک ری‌اکت Next.js استفاده کنیم، مهمترین قابلیت این فریم‌ورک کانفیگ SSR اشه ولی خب به همین راحتی هم نمیتونین از یه پروژه‌ای که با CRA استارت زدین به Next.js مهاجرت کنین به این خاطر من و سعید توی این جابه‌جایی چالش‌های زیادی داشتیم، که البته سعی داریم این تجربه رو کم کم در ویرگول با شما به اشتراک بگذاریم.چانک (Chunk) یکی از شاخه‌های وب‌پک به نام Code Splitting محسوب میشه و خیلی ساده بخوام تعریفش رو بگم شکستن و تکه تکه کردن فایل‌های تولید شده برای هر کامپوننت اِ که دیگه شما یک فایل 2، 3 مگی واسه کل پروژتون ندارید و اون‌ها رو به فایل‌های چند کیلوبایتی میشکونید.خب هدف من از نوشتن این مقاله معرفی و توسعه‌ی یکی از پلاگین‌های Next.js به نام zeit/next-sass که یکسری محدودیت‌ها از جمله استفاده‌ی همزمان از sass module و sass غیر ماژولی و مهمتر از اون چانک کردن فایل‌های sass ایه که در نهایت من این پلاگین رو کوبیدم و از نو ساختم.برای شروع پکیج مورد نظر رو نصب کنید.npm install --save @2012mjm/next-sassیا از روش زیر، که من خودم yarn رو بیشتر دوس دارم.yarn add @2012mjm/next-sassدر فایل next.config.js پروژه Next.js یتون پلاگین مورد نظر رو import و به روشی که نوشتم اون رو به فریم‌ورکتون متصل کنید.const withSass = require(&#039;@2012mjm/next-sass&#039;)

module.exports = withSass({
    /* config options here */
})حالا کنار کامپوننت موردنظرتون یک فایل برای مثال با نام styles.module.scss ایجاد کنید، و چند خط sass ای توی اون تایپ کنید.$font-size: 50px;
.example {
    font-size: $font-size;
}و بعد به شکل زیر در کامپوننتون import اش کنینimport styles from &quot;../styles.module.scss&quot;
export default () =&gt; &lt;div className={styles.example}&gt;Hello World!&lt;/div&gt;به همین راحتی ...البته تا این جای کار رو خود پلاگین zeit/next-sass واستون انجام میده، اولین مشکلی که ما بهش برخوردیم، استفاده از sass بوت‌استرپ بود که وقتی پلاگین رو روی ماژول بیس تنظیم می‌کردیم تمام sass فایل‌های ماژولی بیلد و تمامی سلکتورهای css بوت‌استرپ داغون میشدن، برای حل این مشکل فایل‌هایی که با پسوند module.scss یا module.sass باشن رو ماژولی کامپایل و فایل هایی که تنها پسوند scss یا sass داشته باشن رو غیر ماژولی کامپایل کردیم.مشکل دوم که به عنوان تاپیک این مقاله انتخاب کردم این بود که فایل sass تمامی کامپوننت‌ها در قالب یک فایل کامپایل میشد و حجم فایل استایل پروژه خیلی خیلی بالا میرفت، مخصوصا در پروژه‌هایی که scale بالا داشتن، برای حل این مشکل مجبور شدم یه خرده با webpack دست و پنجه نرم کنم که در نهایت موفق شدم با استفاده از پلاگین وب‌پک extract-css-chunks-webpack-plugin این مشکل رو هم رفع کنم.فقط نکته‌ی مهمی که وجود داره اینکه باید صفحات رو به صورت dynamic ایمپورت کنید تا فایل css هر page با لود شدن همزمان اون فراخوانی بشه، به این صورت:// pages/index.js

import dynamic from &#039;next/dynamic&#039;;
const Home = dynamic(() =&gt;
    import(/* webpackChunkName: &quot;home.js&quot; */ &#039;../src/scenes/Home/Home&#039;)
);
export default Home;اون /* webpackChunkName: &quot;home.js&quot; */ واسه جاوااسکریپت کامنت محسوب میشه ولی واسه وب‌پک یه رشته‌ی معنی داره و اگه اونو ننویسین باعث میشه به یک خطای مرگبار در هنگام بیلد پروداکشن بخورین، دلیلشم اینکه وب‌پک به جای home.js اسم چانک‌ها رو یک و دو و سه میزاره.نکته آخر هم اینکه اگه خواستین پلاگین مورد نظر رو به صورت سفارشی کانفیگ کنید، به روشی که من واسه پروژمون کانفیگ کردم می‌تونین انجامش بدین. module.exports = withSass({
  cssLoaderOptions: {
    importLoaders: 1,
    localIdentName: &#039;[local]_[hash:base64:5]&#039;
  },
  cssExtractOutput: {
    filename: {
      dev: &#039;static/css/[name].css&#039;,
      prod: &#039;static/css/[contenthash:8].css&#039;
    },
    chunkFilename: {
      dev: &#039;static/css/[name].chunk.css&#039;,
      prod: &#039;static/css/[contenthash:16].css&#039;
    }
  })
)مستندات کامل این پکیج هم در آدرس زیر قابل دسترسهhttps://www.npmjs.com/package/@2012mjm/next-sass</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Sat, 20 Jul 2019 16:45:44 +0430</pubDate>
            </item>
                    <item>
                <title>چطوری یه پروژه React ای رو Code Review کنیم؟</title>
                <link>https://virgool.io/iran-react-community/%DA%86%D8%B7%D9%88%D8%B1%DB%8C-%DB%8C%D9%87-%D9%BE%D8%B1%D9%88%DA%98%D9%87-react-%D8%A7%DB%8C-%D8%B1%D9%88-code-review-%DA%A9%D9%86%DB%8C%D9%85-lu4rc9pf7y5o</link>
                <description>اولین code review خودم رو برای آزمون استخدامی در یک پوزیشن React ای واسه یک شرکت نرم افزاری اروپایی انجام دادم، مصاحبه‌های اون ور آبی با این ور آبی خیلی فرق داره، اینجا ازت میپرسن خب نمونه کارات چیه، چند سال کار کردی، چی بلدی و ... ولی اون ور آبی اکثرا ازت تست میگیرن، اونم نه یک سوال در مورد زبون برنامه نویسی موردنظرشون، بلکه بهتون یه مسئله میدن و میگن برو ببینیم چند مرده حلاجی، میخوان ببینن الکی جو خارج و کارخارجی گرفتت یا نه بابا این واقعا بلده!! تستی که از من گرفتن به این صورت بود که بهم گفتن که دسترسی به سورس یکی از پروژه هامون رو بهت میدیم، البته به همین راحتی هم دسترسی ندادن، واسم یک NDA (توافقنامه عدم افشاء) ایمیل کردن تا پاش یه امضای دیجیتال بزنم، بعد هم یه فرم توی google docs باهام share کردن که ساختار code review بود.از اونجایی که من تا حالا توی عمرم یه code review حرفه ای انجام نداده بودم، و مهم تر از همه اینکه ما توی ایران زیاد به چنین کاری اعتقادی نداریم، به همین دلیل کلی توی منابع انگلیسی سرچ کردم تا در نهایت تونستن از چند تا مقاله یه چیزی دستگیرم بشه، من code review خودم رو بخش‌های زیر دسته بندی کردم. GeneralClean CodePerformanceخب با یاد و نام خدا میریم سراغ code review پروژه‌ی ... (شرمنده نمیتونم اسمش رو بیارم، یکم secrete)1. General1.1. Structure easily understand1.1.1. The directory name must represent the files within itسعی کنید نام دایرکتوری رو متناظر با فایل‌هایی که درون اون هستن انتخاب کنید.1.1.2. Insert each item with its style in a separate directoryاستایل هر کامپوننت رو کنار خود فایل تعریف کنید، البته بستگی به scale پروژه داره+ components/Card/Avatar
     - Avatar.js
     - Avatar.style.js1.2. Keep components smallبهتره کامپوننت‌هاتون رو کوچولو تعریف کنید. برای مثال یه فایل به اسم Button.js ساخته بودن و درون اون سه تا کامپوننت از انواع button ها تعریف کرده بودن، خب این چه کاریه آخه !2. Clean Code2.1. Add comment2.1.1. Comment rulesسعی کنید قوانین زیر رو در بحث کامنت گذاری دقت کنید تا کد یکدستی داشته باشینOnly comment on things that have business logic complexity.Don&#x27;t leave commented out code in project codebase.Don&#x27;t have journal comments, use version control for old code in project historyAvoid positional markers, they usually just add noise. Let the functions and variable names along with the proper indentation and formatting give the visual structure to project code.2.1.2. Comment on PropTypesCallToAction.propTypes = {
    // This is the button label
    label: PropTypes.string,
    // If true, i don&#039;t know what it is doing :)
    alternative: PropTypes.bool
};2.2. Using code formatter extensionsاکستنشن Code formatter بهتون کمک میکنه تا با استفاده از یک سری قوانین که واسش تعیین می‌کنید ساختار کدهاتون رو منظم کنه 2.3. ESlint2.3.1. ESLint Git pre-commit hookشما می‌تونید با استفاده از قابلیت pre-commit در GIT جلوی کامیت‌هایی که قوانین ESLint رو زیر پا گذاشتن رو بگیرید، تا developer شما بعد از رعایت قوانین تعیین شده کدش رو commit کنه2.4. Import the desired Action instead of starنام اکشن‌هاتون رو قشنگ ذکر کنید، این باعث خوانایی بیشتر میشه، کد زیر بود کهimport * as actions from &#039;../../actions&#039;;تبدیل شد بهimport { saveUser, updateUser } from &#039;../../actions&#039;;2.5. Remove duplicate Actionsاکشن‌هایی که یه type و یه payload یکسان دارن رو میتونید به یک فایل common منتقل کنید و از تکرار اونا جلوگیری کنید.2.6. Rename the single file in the directory to index.jsفایل‌های تک و تنهایی که در یک دایرکتوری مشخص هستن رو میتونید به index.js تغییر بدید، این کار کمک میکنه import هاتون ساده تر بشن، البته موقعی که فایل رو در editor باز می‌کنید یکم تعدد فایل‌های index اون بالا بین تب‌ها زیاد میشه !// src/utils/storage/index.js
import Storage from &#039;../storage&#039;;2.7. Add propTypes and defaultProps for all components2.8. Separate the style from the component in the style.js fileسعی کنید استایل هاتون رو ته فایل component تعریف نکنید، بهتره اونا رو به یه فایل دیگه منتقل کنید و بعد import اش کنید.2.9. No useless import fileایمپورت‌های بدون استفاده رو حذف کنید، این قوانین رو در eslint می‌تونید تعریف کنید.2.10. No useless constructorاگه کامپوننتون class بیس و نیاز به constructor اون کامپوننت ندارید، بهتره پاکش کنید.2.11. Using the React Hooksاستفاده از Hook های جدید و دوست داشتنی React3. Performance3.1. Making async calls for component initialization in the componentDidMountتوابع async ای که نیاز دارین واسه بار اول اجرا بشه رو بهتره توی componentDidMount بجای constructor بنویسید، برای مثال توابعی که نیاز داره یه request به سرور بزنه3.2. Analyzing and optimizing Webpack bundle bloatکتابخونه webpack-bundle-analyzer بهتون کمک میکنه تا باندل پروژتون رو آنالیز کنید و اگه از کتابخونه سنگینی دارید استفاده می‌کنید مطلع بشید.3.3. Code-Splitting3.3.1. Lodash module, one-by-one or ‘modules’ importکتابخونه lodash یکی از سنگین‌ترین کتابخونه‌هاست که باید خیلی حواستون رو بهش بدین، و بهتره تابعی که نیاز دارید رو به طور مستقیم صدا بزنید، مثال زیر رو ببینید.import omitBy from &#039;lodash/omitBy&#039;;
import isUndefined from &#039;lodash/isUndefined&#039;;3.3.2. React.lazy and Suspense3.4. Speed up image loading time3.4.1. Reduce Image size, convert images to WebP format3.4.2. Cache the images locally3.5. Remove all console before deploying the production versionکنسول‌ها جا نمونن، از کتابخونه babel-plugin-transform-remove-console میتونید استفاده کنید، خودش ترتیب حذف کنسول‌هاتون رو میده.3.6. Using PureComponent3.7. Using React.memoامیدوارم واسه code review های اون ور آبی و یا شایدم این ور آبی بدردتون بخوره.</description>
                <category>جواد مسعودیان</category>
                <author>جواد مسعودیان</author>
                <pubDate>Tue, 16 Jul 2019 18:46:51 +0430</pubDate>
            </item>
            </channel>
</rss>