ساختارمند کردن پروژه‌های بزرگ
چگونه با React یک برنامه بزرگ را  مدیریت و سازماند‌هی کنیم؟
React از سوی فیسبوک به عنوان راه‌کاری برای حل مشکل برنامه‌های گسترش‌پذیری که ترافیک سنگینی دارند ابداع شد. توسعه‌دهندگان وب از این چهارچوب متن باز جاوااسکریپتی برای ساخت رابط‌های کاربری استفاده می‌کنند. انعطاف‌پذیری و قابلیت‌های متنوعی که ری‌اکت ارائه می‌کند باعث شده تا این چهارچوب به شکل گسترده‌ای توسط توسعه‌دهندگان و شرکت‌های بزرگی نظیر فیسبوک و اینستاگرام استفاده ‌شود. در ایران نیز ری‌اکت با استقبال خوبی از سوی توسعه‌دهندگان روبرو شده است، بنابراین مهم است با تکنیک‌های مهمی که در زمینه ساخت و ساختاربندی برنامه‌های بزرگ ری‌اکت در دسترس‌مان قرار دارد آشنا باشیم.

ساخت ابزار 

بسیاری از توسعه‌دهندگان وب علاقه شدیدی دارند که ازwebpack  برای ساخت پروژه‌های خود استفاده کنند. اگر چه استفاده از این ابزار می‌تواند پیچیده باشد، اما گروه توسعه با زحمات زیادی که برای‌ نسخه 5‌ آن متحمل شده‌اند و امکانات متنوع و مستندات جامعی که ارائه کرده‌اند این فرآیند را ساده‌تر از قبل کرده‌اند. توسعه‌دهندگان برای کامپایل کدهای خود می‌توانند از Babel که شامل مبدل‌های ویژه ری‌اکت نظیر JSX است استفاده کنند، در حالی که برای میزبانی محلی از سایت webpack-dev-server که شامل قابلیت نوسازی خودکار صفحه است در دسترس آن‌ها قرار دارد. علاوه بر این، برای مدیریت هرچه دقیق‌تر وابستگی‌های ورودی و خروجی امکان به‌کارگیری ماژول‌های ES وجود دارد که اولین بار در ES2015 ارائه شدند. webpack می‌تواند از CommonJS پشتیبانی کند و با استفاده از ماژول‌های ES2015 کدهای بلااستفاده را از مجموعه حذف کند. آمارها نشان می‌دهند که بخش عمده‌ای از اکوسیستم وب به سمت ماژول‌های ES متمایل شده‌اند، بنابراین ایده بدی نیست که سنگ‌بنای پروژه‌های جدید را بر مبنای این تغییرات پایه‌گذاری کنید. البته اگر تمایلی به استفاده از webpack ندارید، جایگزین‌های دیگری نیز در دسترس است که Rollup یکی از آن‌ها است. 

ساختار پوشه‌

هیچ ساختار پوشه مشخصی برای برنامه‌های ری‌اکت وجود ندارد. اما راهکاری که در ادامه با آن آشنا می‌شوید، در ارتباط با تمامی پروژه‌ها قابل استفاده است. برای مرتب کردن کارها، ما تمام کدهای اپلیکیشن را داخل پوشه‌ای به‌نام src قرار می‌دهیم. این مورد فقط شامل کدی است که در بسته نرم‌افزاری نهایی شما قرار می‌گیرد و نه چیز بیشتر. انجام این‌کار مزایای زیادی دارد، زیرا می‌توانید به Babel (یا هر ابزار دیگری که بر اساس کد اپلیکیشن عمل می‌کند) بگویید فقط در یک فهرست جست‌وجو کند و اطمینان حاصل کنید هیچ کد غیر‌ضروری پردازش نخواهد شد. در این حالت قادر هستید سایر کدها مثل فایل‌های پیکربندی webpack را در پوشه‌ای با نام مناسب نگه‌داری کنید. ساختار پوشه‌ اصلی می‌تواند همانند ترکیب نحوی زیر باشد:

- src => app code here

- webpack => webpack configs

- scripts => any build scripts

- tests => any test specific code (API mocks, etc.)

  • رویکرد فوق به شما این امکان را می‌دهد تا فایل‌هایی که در بالاترین سطح قرار دارند index.html، package.json و فایل‌هایی که با نقطه شروع می‌شوند (مثل .babelrc) را در پوشه مذکور قرار دهید. برخی ترجیح می‌دهند پیکربندی Babel را در package.json قرار دهند، اما در پروژه‌های بزرگ‌تر این فایل‌ها می‌توانند خیلی بزرگ شوند، بنابراین بهتر است از .eslintrc،  .babelrc و نمونه‌های مشابه استفاده کنید. 

مولفه‌های ری‌اکت 

بعد از این که پوشه src را آماده کردید، نوبت به تصمیم‌گیری در مورد ساختار مولفه‌های پروژه می‌رسد. یکی از شیوه‌های متداول قرار دادن تمام مولفه‌ها در یک پوشه بزرگ مثل src/components است، اما چنین انتخابی در پروژه‌های بزرگ به سرعت باعث سردرگمی‌ می‌شود. بهتر است مولفه‌ها را بر اساس محل استفاده آن‌ها در اپلیکیشن به همراه یک پوشه اصلی برای مولفه‌های مشترکی که در کل برنامه استفاده می‌شوند (مثل دکمه‌ها، سرتیترها، فوترها و مولفه‌هایی که پرکاربرد هستند) گروه‌بندی کنید. برای نمونه، ما پوشه‌ای به‌نام cart داریم که شامل تمام مولفه‌های مرتبط با نمایش سبد خرید است و پوشه دیگری به‌نام listings که شامل کدهایی است که فهرست اقلامی‌ که کاربران می‌توانند در یک صفحه خرید کنند را شامل می‌شود. علاوه بر این، دسته‌بندی پوشه‌ها به این معنا است که شما دیگر نیاز نیست برای قرار دادن کدهای بخش‌های زیرمجموعه اپلیکیشن از پیشوند برای نام‌گذاری استفاده کنید. به‌طور مثال، اگر بخشی از کدها را در اختیار داریم که جمع مبلغ سبد خرید کاربر را محاسبه می‌کند، به جای این‌که نام آن‌را CartTotal بگذاریم، می‌توانید آن‌را Total نامگذاری کنید، زیرا آن‌را قبلا از یک پوشه به‌نام cart وارد کرده‌اید:

import Total from ‘../cart/total’

// vs

import CartTotal from ‘../cart/cart-total’

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

استفاده از پسوند jsx به جای حروف بزرگ

بسیاری از افراد برای تفکیک مولفه‌های ری‌اکت از فایل‌های معمولی جاوااسکریپت، آن‌ها را با حروف بزرگ نام‌گذاری می‌کنند. بنابراین، طبق مثال بالا نام فایل‌ها به صورت CartTotal.js و Total.js خواهد بود، اما برخی دیگر از توسعه‌دهندگان ترجيح می‌دهند اسامی‌ با حروف کوچک به همراه کاراکتر جداکننده خط تیره (-) انتخاب کنند و برای جداسازی مولفه‌های ری‌اکت از پسوند .jsx برای فایل‌ها استفاده کنند. بنابراین بهتر است نام فایل را cart-total.jsx انتخاب کنید. راهکار فوق مزیت بزرگی دارد که اجازه می‌دهد برای پیدا کردن فایل‌های ری‌اکت با جست‌وجوی .jsx دامنه جست‌وجو را محدود کنید و حتا می‌توانید در صورت نیاز پلاگین‌های webpack مشخصی را به این فایل‌ها اعمال کنید. از هر روشی برای نام‌گذاری استفاده می‌کنید، مهم این است که به آن پایبند باشید. زمانی‌که پروژه‌ها بزرگ می‌شوند، عدم پیروی از همین اصول ساده باعث می‌شود در زمان پیدا کردن فایل‌ها سردرگم‌ شوید. 

یک مولفه ری‌اکت به ازای هر فایل 

طبق قانون قبلی، ما به یک فایل مولفه ری‌اکت پایبند هستیم و این مولفه همیشه باید خروجی پیش فرض باشد. به‌طور معمول فایل‌های ری‌اکت به صورت زیر هستند:

import React from ‘react’

export default function Total(props) {

  …

}

در مواردی که برای اتصال یک مولفه به یک ذخیره‌ساز Redux باید آن‌را به کد متصل کنیم، این فرآیند را می‌توان به صورت زیر مدیریت کرد: 

import React, { Component, PropTypes } from ‘react’

import { connect } from ‘react-redux’

export default function Total(props) {

  …

}

export default connect(() => {…})(Total)

همان‌گونه که مشاهده می‌کنید ما همچنان از مولفه اصلی خروجی خواهیم گرفت. این‌کار برای آزمایش کد و زمانی که نیاز به تنظیم Redux در واحد آزمايش نداریم (Unit Test) کاملا مفید است. 

اجتناب از متدهای render بزرگ 

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

همیشه از prop-type استفاده کنید 

ری‌اکت با استفاده از بسته prop-types به شما اجازه می‌دهد اسامی‌ و نوع خصوصیاتی که انتظار دارید یک مولفه ارائه کند را مستندسازی کنید. با مشخص کردن اسامی‌ و نوع خصوصیات مورد انتظار، به همراه این‌که آیا آن‌ها اختیاری هستند یا خیر، می‌توانید اطمینان بیشتری حاصل کنید که آیا مولفه‌هایی که با آن‌ها کار می‌کنید خصوصیات مناسب را در اختیار شما می‌گذارند و اگر نام یک خصوصیت را فراموش کردید، می‌توانید زمان کمتری را صرف دیباگ کردن کدهای خود کنید یا خیر. شما می‌توانید با استفاده از eslint-plugin-react PropTypes rule این‌کار را الزامی‌ کنید. اگر چه وقت گذاشتن برای انجام چنین کاری در ظاهر ممکن است بی‌فایده به نظر برسد، اما وقتی به سراغ استفاده مجدد از یک مولفه می‌روید که شش ماه پیش آن‌را نوشته بودید از انجام این کار خرسند خواهید شد.

Redux

خیلی از توسعه‌دهندگان برای مدیریت داده‌ها در اپلیکیشن‌های خود از Redux استفاده می‌کنند، بنابراین چگونگی سازمان‌دهی برنامه‌های Redux اهمیت زیادی دارد، زیرا توسعه‌دهندگان روش‌ها و گزینه‌های مختلفی برای این منظور پیشنهاد می‌کنند.  Ducks یک گزینه مناسب در این زمینه است که تمام امکانات مورد نیاز بخش‌های مختلف اپلیکیشن شما را در یک فایل ارائه می‌کند. به جای در اختیار داشتن reducers.js و actions.js که هر کدام شامل کدهای مرتبط به هم هستند، سیستم Ducks به این مسئله اذعان دارد که گروه‌بندی کدهای مرتبط با هم درون یک فایل واحد منطقی‌تر است. فرض کنید شما یک ذخیره‌ساز Redux با دو کلید user و posts در اختیار دارید، ساختار پوشه شما چیزی شبیه به حالت زیر است:

ducks

  •  index.js
  •  user.js
  •  posts.js

فایل index.js حاوی کدی است که گیرنده اصلی را (احتمالا با استفاده از combineReducers  از Redux) ایجاد می‌کند. اکنون در user.js و posts.js باید کدهایی شبیه به قطعه کدهای زیر را قرار ‌دهید:

// user.js

const LOG_IN = ‘LOG_IN’

export const logIn = name => ({ type: LOG_IN, name })

export default function reducer(state = {}, action) {

  …

}

ماژول‌های مستقل جاوا اسکریپت 

اگر چه تمرکز این مقاله روی مولفه‌های React است، اما در زمان ساخت یک اپلیکیشن ری‌اکت مجبور به نوشتن کدهای زیادی هستید که کاملا از ری‌اکت مجزا هستند. مجزا بودن بسیاری از کدها از مولفه‌های برنامه‌نویس یکی از مزایای اصلی چهارچوب ری‌اکت است. شما می‌توانید پوشه‌ای به‌نام lib یا services را برای قرار دادن محتوای مجزا از مولفه‌های ری‌اکت در نظر بگیرید. این سرویس‌ها گاهی اوقات گروهی از توابع و گاهی یک شی مرتبط با توابع را ارائه می‌کنند. برای مثال ما services/local-storage.js

را داریم که بخشی از window.localStorage API را شامل می‌شود:

// services/local-storage.js

const LocalStorage = {

  get() {},

  set() {},

  …

}

export default LocalStorage

  • با استفاده از این شیوه این توانایی را به‌دست می‌آورید تا بدون نیاز به رندر مولفه‌های ری‌اکت این کد را به صورت مجزا آزمايش کنید. 

 

 

ماهنامه شبکه را از کجا تهیه کنیم؟
ماهنامه شبکه را می‌توانید از کتابخانه‌های عمومی سراسر کشور و نیز از دکه‌های روزنامه‌فروشی تهیه نمائید.

ثبت اشتراک نسخه کاغذی ماهنامه شبکه     
ثبت اشتراک نسخه آنلاین

 

کتاب الکترونیک +Network راهنمای شبکه‌ها

  • برای دانلود تنها کتاب کامل ترجمه فارسی +Network  اینجا  کلیک کنید.

کتاب الکترونیک دوره مقدماتی آموزش پایتون

  • اگر قصد یادگیری برنامه‌نویسی را دارید ولی هیچ پیش‌زمینه‌ای ندارید اینجا کلیک کنید.
برچسب: 

ایسوس

نظر شما چیست؟