Next.js چیست و چه کاربردی دارد؟ + پروژه عملی

?What is Next.js

what-is-nextjs-by-roxo

در این مقاله می خواهیم با فریم ورکی برای React  به نام Next.js آشنا شویم! احتمالا خواندن این جمله برایتان عجیب باشد چرا که react خودش یک کتابخانه است بنابراین چطور می توانیم یک فریم ورک را برایش داشته باشیم!؟ در این مقاله به طور مفصل به این سوال پاسخ و دلایل استفاده از Next.js را نیز توضیح می دهیم.اگر به وب سایت Next.js بروید می بینید که جمله بزرگی در آن نوشته شده است:

The React Framework for Production

این جمله به معنی این است که next یک فریم ورک react برای مرحله بهره برداری (production) است. می توان این جمله را به صورت fullstack frarmework for react نیز نوشت، یعنی یک فریم ورک fullstack (شامل backend و frontend) برای کتابخانه react!

اگر از این جملات فنی دور بشویم، می توانیم next.js را به زبان ساده تعریف کنیم: فریم ورکی که از react استفاده می کند و تمام برنامه شما (سمت سرور و سمت کلاینت) را برایتان می سازد. این فریم ورک قابلیت های بسیار بیشتری را نسبت به react به شما می دهد و در واقع react را توسعه می دهد. توجه داشته باشید که در next.js هنوز هم کد react می نویسیم اما همانطور که گفتم قابلیت های آن بسیار زیاد و قوی شده است و برای هر مسئله کوچکی نیاز به استفاده از کتابخانه های خارجی ندارید.

Next.js چیست و چرا از آن استفاده می کنیم؟

اگر در زمینه توسعه وب کار می کنید، به احتمال زیاد نام Next.js را شنیده اید یا در مورد آن کنجکاو هستید. Next.js چیزی است که اغلب به عنوان «فریمورک متا» شناخته می شود، زیرا فریم ورکی است که بر اساس یک یا چند فریمورک دیگر ساخته شده است. Next.js بر اساس React ساخته شده است. به‌طور ساده، Next.js یک فریم ورک React برای توسعه برنامه‌های جاوا اسکریپت تک صفحه‌ای است. مزایای این فریم ورک، هم برای برنامه های کاربردی client و هم برای تیم توسعه بسیار زیاد است.سایت ها و برنامه هایی که سریع نیستند انتظارات ما را برآورده نمی کنند و آن ها را نمی پسندیم. یکی از مهم ترین مزایای Next.js  سرعت و عملکرد فوق العاده آن است.

Next.js یک فریم ورک جاوا اسکریپت است که به شما امکان می دهد وب سایت های ایستا بسیار سریع و بسیار کاربر پسند و هم چنین برنامه های کاربردی وب را با استفاده از React بسازید. این ویژگی به Next.js اجازه می‌دهد تا برنامه‌های ترکیبی بسازد که هم صفحه های رندر شده توسط سرور و هم صفحات تولید شده به صورت ایستا را شامل می‌شود.

Next.js به طور گسترده توسط بزرگترین و محبوب ترین شرکت ها در سراسر جهان مانند Netflix، Uber ،Starbucks یا Twitch استفاده می شود. همچنین به‌عنوان یکی از سریع‌ترین فریمورک‌های React در نظر گرفته می‌شود که برای کار با سایت‌های استاتیک مناسب است که اخیرا جذاب ترین موضوع در دنیای توسعه وب است. بخش بزرگی از دلیلی که توسعه دهندگان و شرکت ها Next.js را برای توسعه برنامه های کاربردی وب خود انتخاب می کنند این است که این یک فریم ورک fullstack است. بیایید نگاهی کوتاه به نحوه تکامل Next.js و به ویژه نحوه تکامل متدهای render در Next.js بیندازیم.

تکامل Next.js

امروزه، Next.js اغلب با متدولوژی Jamstack برای توسعه برنامه های کاربردی وب مرتبط است. با این حال، زمانی که در اوایل سال 2016 راه اندازی شد، فقط برای برنامه های سمت سرور استفاده می شد. در آن زمان، چیزی که Next.js را منحصربه‌فرد می‌کرد این بود که هم frontend و هم backend برنامه شما را مدیریت می‌کرد و هر دو با استفاده از جاوا اسکریپت و React ساخته می شدند. این به توسعه دهندگان اجازه می دهد تا با استفاده از تنها یک زبان و مجموعه ابزار، برنامه های fullstack بسازند و در عین حال تجربه کاربری بهبود یافته ای را ارائه دهند که معمولا منجر به رندر اولیه سریعتر صفحه می شود. Next.js هم چنین به دلیل ساده سازی ساخت برنامه های فول استک با استفاده از React محبوبیت پیدا کرد.

ویژگی های مهم Next.js

ویژگی های مهم Next.js

ما می خواهیم در این بخش به ویژگی ها و کاربردهای Next.js بپردازیم. این کار باعث می شود دقیقا درک کنید که بخش ابتدایی مقاله در مورد چه بود و اینکه Next دقیقا چه کاری را انجام می دهد.

۱. Server-side Rendering (صفحه سازی در سمت سرور)

Server-side Rendering به معنی رندر کردن صفحات (ساخت و نمایش آن ها) در سمت سرور است. اگر با react کار کرده باشید می دانید که ما در react داده ها را از سرور گرفته و در سمت کلاینت (در مرورگر کاربر) از آن داده ها برای ساخت و نمایش صفحه (render کردن آن) استفاده می کنیم. در این حالت صفحه را در سمت کلاینت ساخته و نمایش داده ایم اما server-side rendering مانند زمانی است که از PHP برای تولید صفحات HTML استفاده می کنید! یعنی صفحات شما در سمت سرور ساخته شده و سپس به صورت آماده به سمت کاربر ارسال می شوند بنابراین کاربر نیازی به انجام پردازش ندارد.

شما می توانید برای درک این موضوع به وب سایتی بروید که با react نوشته شده است. اگر سورس کد این وب سایت را از مرورگر خود باز کنید متوجه خواهید شد که وب سایت خالی است! چرا؟ به دلیل اینکه در وب سایت های SPA یا Single Page Application صفحات واقعی را نداریم بلکه آن ها با جاوا اسکریپت و به صورت پویا ایجاد شده اند.

چنین برنامه هایی مشکل جدی ایجاد نمی کنند (البته بسته به اینکه چه برنامه ای را می سازید) اما یکی از معایب آن این است که کاربر در اولین بازدید خود از سایت شما باید مدت نسبتا زیادی را منتظر بماند. چرا؟ به دلیل اینکه ابتدا سرور فایل های جاوا اسکریپت را برای کاربر می فرستد، سپس مرورگر کاربر این فایل ها را اجرا می کند و تازه در این مرحله دریافت داده های صفحه از سمت پایگاه داده و سرور شرع می شود. به همین خاطر است که در بسیاری از برنامه های SPA یک علامت loading یا spinner را مشاهده می کنید که به کاربر می گوید منتظر باشد. زمانی که می گویم «مدت نسبتا زیاد» منظورم بر اساس معیار های سایبری سریع امروزی است. در بسیاری از اوقات این وقفه هیچ مشکلی ندارد اما شاید شما بخواهید صفحات سریعا برای کاربر باز شوند.

یکی دیگر از مشکلات SPA ها، مشکلات مربوط به بهینه سازی موتورهای جست و جو (سئو یا SEO) است. اگر برنامه شما خصوصی باشد (مثلا صفحه ادمین در یک وب سایت) این صفحه هیچ گاه توسط موتورهای جست و جو خوانده نخواهد شد بنابراین مسئله سئو به هیچ عنوان در آن اهمیت ندارد اما اگر هدف اصلی وب سایت شما بالا آمدن در گوگل و فروش محصول یا خدمات خاصی است، باید فکری به حال سئو بکنید. چرا؟ به دلیل اینکه موتورهای جست و جو در ابتدا فقط یک صفحه خالی را می بینند که جاوا اسکریپت دارد اما بعد از چند لحظه محتوای صفحه را دریافت می کنند. این وقفه می تواند باعث ضربه خوردن سئوی شما شود. همچنین در برخی موارد معدود نیز موتورهای جست و جو اصلا نمی توانند محتوای یک صفحه SPA را مشاهده کنند که از نظر سئو بسیار بد است.

اینجاست که server-side rendering به ما کمک می کند. اگر صفحات ما در سمت سرور ساخته شده باشند و سپس ما آن صفحه آماده را به سمت کاربر ارسال کنیم دیگر از نظر سئو هیچ مشکلی نداریم. همچنین دیگر آن وقفه اولیه وجود ندارد و صفحات به صورت لحظه ای برای کاربر نمایش داده می شود. لازم به ذکر است که React به صورت پیش فرض دارای قابلیت هایی است که به شما اجازه می دهد server-side rendering را در خود react انجام بدهید اما پیکربندی و راه اندازی آن کمی سخت است و از نظر قابلیت نیز به پای Next نمی رسد.

سوال: آیا این مسئله به معنی تبدیل شدن سایت ما به سایت های قدیمی HTML ای است؟ با این حساب چرا از react استفاده کنیم؟

پاسخ: اولا باید در نظر داشت که Next.js برای طرفداران react ساخته شده است و ده ها راه دیگر برای server-side rendering وجود دارد. شما هیچ الزامی به استفاده از Next ندارید. دوما Next.js فقط صفحه اول را برای کاربر در سمت سرور می سازد اما از آنجا به بعد یک برنامه React عادی دارید و حرکت کاربر بین صفحات مختلف شما به صورت SPA و با react خواهد بود.

این ویژگی، مهم ترین ویژگی Next.js محسوب می شود.

۲. File-based Routing (ناوبری فایل محور)

ویژگی دوم و بسیار محبوب Next.js ناوبری فایل محور یا File-based Routing است. در کتابخانه react به صورت پیش فرض هیچ router ای وجود ندارد که مسیر حرکت کاربر و تغییر URL مرورگر را تحت نظر بلکه از پکیج هایی مانند react-router استفاده می کنیم. کار چنین پکیج هایی این است که با تغییر URL در مرورگر کاربر، جلوی رفتار پیش فرض مرورگر (ارسال درخواست HTTP) گرفته شود و سپس نمایش محتوای متفاوت در همان صفحه است بنابراین به نوعی کاربر را گول می زنیم تا تصور کند برنامه ما صفحات مختلفی را دارد.

یکی از معایب این پکیج ها این است که در آن ها کدنویسی اضافه داریم و باید آن ها را با React ترکیب کنیم. همچنین هیچ ارتباطی بین کامپوننت های React ما و route های برنامه وجود ندارد، به غیر از چیزی که به صورت صریح و با کد مشخص کرده باشیم. Next.js این مسئله را با معرفی سیستم ناوبری یا routing خاص خودش حل می کند! در Next.js برای تعریف یک مسیر (route) جدید از فایل ها و پوشه ها استفاده می کنیم! در واقع در پروژه های Next.js یک پوشه به نام pages را داریم که عینا باید با همین نام باشد. حالا درون این پوشه، پوشه ها و فایل های دیگری را خواهید داشت و ساختار این پوشه ها و فایل ها دقیقا سیستم routing وب سایت شما خواهد بود!

چنین سیستمی برای ساخت route چندین مزیت مهم دارد. اولا برای تولید route ها هیچ نیازی به نوشتن کد نداریم بلکه Next.js خودش این کار را برایمان انجام می دهد. دوما به دلیل نوشتن کد کمتر، خوانایی کدهایمان بالا رفته و از شلوغ شدن پروژه جلوگیری می کنیم. سوما درک سیستم routing در این حالت بسیار ساده تر است چرا که با نگاه انداختن به پوشه pages به راحتی می توانیم مسیر های سایت خودمان را ببینیم. طبیعتا این سیستم routing تمام امکانات سیستم های مدرن ناوبری را دارد: مثلا به nested routes دسترسی دارید، به dynamic routes دسترسی دارید، به dynamic parameters دسترسی دارید و الی آخر.

۳. Fullstack Capabilities (توانایی فول استک)

ما می دانیم که react برای سمت کلاینت (مرورگر کاربر) ساخته شده است اما سمت سرور چطور؟ باید توجه داشت که Next.js به صورت جادویی کدهای سمت سرور را برای شما نمی نویسد چرا که چنین کاری اصلا ممکن نیست. کاری که Next.js برای ما انجام می دهد ساده کردن ترکیب کد react با کد سمت سرور (منطق کاری سایت ما) است. اگر از Next.js استفاده کنید، ساخت یک API در سمت سرور برای کار با برنامه React بسیار آسان خواهد بود. با این حساب فرآیند هایی که به سرور و API نیاز دارند به راحتی در دسترس شما خواهند بود. مثلا فرآیند احراز هویت کاربران، دریافت داده، ذخیره سازی داده و امثال آن همگی به راحتی انجام می شوند.

شاید بپرسید مگر با react عادی نمی توانیم این کار را انجام بدهیم؟ حرفتان صحیح است. ما می توانیم بدون Next.js یک پروژه react داشته باشیم و API را جداگانه بنویسیم. در هر دو حالت نیز باید API را خودمان بنویسیم اما در پروژه های Next.js علاوه بر مزیت های قبلی این مزیت را نیز داریم که کد سمت سرور (مثلا Node.js) و کد سمت کلاینت‌ (React) در یک پروژه و یکجا قرار دارند بنابراین مدیریت آن بسیار ساده تر خواهد بود.

روش های رندر کردن در Next.js

همانطور که اشاره کردیم، Next.js صرفا به عنوان یک چارچوب برای رندر در سمت سرور SSR آغاز به کار کرد، ولی همان طور که قابلیت های آن گسترش پیدا کرد، حتی معنای SSR در Next.js نیز تغییر کرده است.

رندر در سمت سرور SSR

در SSR، محتوا بر روی سرور (که Node.js است) برای هر درخواست تولید می شود و سپس به مرورگر ارسال می شود. با انتشار Next.js 8، هر صفحه رندر شده توسط سرور به یک تابع بدون سرور تبدیل شد (همچنین به عنوان لامبدا شناخته می شود). به عنوان مثال، هنگامی که اگر /about را در مرورگر باز کنیم، Next.js یک تابع بدون سرور را فراخوانی می‌کند که در نتیجه آن داده‌های مورد نیاز از backend برای render صفحه About واکشی می شوند. واکشی داده ها در متد getServerSideProps() در Next.js کپسوله شده است.

پیش رندر

با پیش رندر - که «رندر استاتیک یا SSG» نیز نامیده می شود، صفحه در طول ساختی که پیش از استقرار برنامه اتفاق می افتد، معمولا به عنوان بخشی از فرآیند ساخت CI/CD رندر می شود. این در ابتدا به عنوان یک گزینه در Next.js 3 اضافه شد، اما این فرآیند بسیار ساده بود. از Next.js 6، مسیرها برای صفحات SSR و SSG خودکار شدند (اگرچه مسیرهای پویا همچنان باید مسیرها را به صورت برنامه‌نویسی از طریق متد ()getStaticPaths رندر کنند). Next.js 9 قابلیتی به نام «بهینه سازی استاتیک خودکار» را معرفی کرد که به طور خودکار تعیین می کند که آیا یک صفحه می تواند به صورت ثابت ارائه شود یا خیر. توانایی ترکیب صفحات/مسیرهای رندر شده سمت سرور و صفحات/مسیرها از پیش رندر شده برای Next.js منحصربه‌فرد بود و از آن زمان توسط سایر فریم ورک ها مانند Gatsby و Nuxt استفاده شده است.

رندر معلق ISR

در Next.js، رندر معلق با نام «بازسازی استاتیک افزایشی یا ISR» شناخته می‌شود که در ابتدا در نسخه 9.4 معرفی شد. هدف ISR حذف زمان ساخت بسیار طولانی است که سایت‌های بزرگ اغلب با آن مواجه می‌شوند و به توسعه‌دهنده اجازه می‌دهد ساخت صفحات با ترافیک کمتر را به تعویق بیندازد. هم چنین این قابلیت را دارد که به صورت انتخابی برای رندر صفحات بر اساس محتوای تولید شده توسط کاربر استفاده شود. البته، مانند هر فریم ورک فرانت‌اند، Next.js نیز روش‌هایی برای کمک به رندر در سمت کلاینت دارد.

مزایا و معایب Next.js

مثل هر ابزار دیگری در دنیای برنامه نویسی، Next.js نیز مزایا و معایب خودش را دارد.

مزایای Nextjs

یکی از مهمترین مزایای یادگیری Next.js، آگاهی شما از میزان انعطاف پذیری و توانمندی در ساخت برنامه های مختلف است.سرعت بارگذاری صفحه (در میلی ثانیه!) و تجربه کاربر از استفاده از وب سایت ها یا فروشگاه های وب در طراحی های وب امروزی نقش بسیار مهمی دارند. Nextjs به شما امکان می دهد تا برنامه های ساده و پیچیده را بسیار سریع تر و آسان تر بسازید و به لطف بسیاری از فریم ورک هایی که برای آن رشد کرده اند، می توانید وب سایت های فوق العاده سریعی برای دستیابی به تجربه کاربری و SEO بهتر ایجاد کنید.

رندر شدن در سمت سرور (Server Side Rendering یا  SSR)

کامپوننت های React  در ابتدا در سمت سرور render می شوند. این به این معنی است که در هنگام نمایش HTML، هیچ اتفاق دیگری لازم نیست تا کاربر بتواند محتوای صفحه را ببینید. این باعث می شود زمان بارگذاری صفحه برای کاربر بسیار سریع تر به نظر برسد. SSR  هم چنین مزایای یک وب‌سایت out-of-the-box، فهرست‌بندی و خزیدن را دارد که برای بهینه‌سازی موتورهای جستجو (SEO) ضروری است زیرا جاوا اسکریپت سمت client برای دیدن محتوای صفحه نیازی به اجرا شدن ندارد. رندر کردن همان کامپوننت ‌ها در سمت سرور مانند سمت کلاینت به این معنی است که زمان توسعه کاهش می‌یابد زیرا ما می‌توانیم کامپوننت های React  خود را تنها یک بار بسازیم و Next JS همه کارهای مربوط به رندر دوباره آن کامپوننت ها را در سمت کاربر انجام می‌دهد.

تقسیم خودکار کد

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

جایگزینی ماژول داغ (Hot Module Replacement  یا HMR)

HMR بیش تر برای توسعه دهندگان اهمیت دارد تا کاربران معمولی.به توسعه‌دهندگان اجازه می‌دهد تا تغییراتی را که در طول توسعه ایجاد کرده‌اند، به‌محض ایجاد آن‌ها در برنامه ی در حال اجرا ببینند. با این حال، برخلاف روش‌های سنتی، فقط ماژول‌هایی را بارگذاری می‌کنند که واقعا تغییر کرده‌اند، وضعیتی را که برنامه در آن قرار داشته است را حفظ می‌کنند و زمان مورد نیاز برای مشاهده تغییرات در عمل را به میزان قابل توجهی کاهش می‌دهند. در نهایت، تاثیر مثبت برای مشتریان ما این است که زمان کمتری برای توسعه از ما می‌گیرد.

به طور خلاصه، مزایای اصلی Next.js عبارتند از:

  • بهبود فرآیند توسعه = هزینه و سود زمانی برای مشتریان ما
  • عملکرد بهبود یافته = برنامه های کاربردی سریعتر
  • سئوی بهبودیافته = فهرست‌پذیری بیشتر و برنامه‌های کاربردی سئو دوستانه
  • تجربه کاربری غنی (آسانتر و سریعتر)
  • عملکرد عالی (همچنین ساده تر و سریعتر)
  • توسعه سریع ویژگی
  • UX یا تجربه کاربری بسیار بهتری خواهید داشت چرا که وقفه اولیه در بارگذاری صفحات را نداریم و سرعت بارگذاری بسیار بهتر خواهد بود.
  • سرعت وب سایت شما بالاتر می رود، مخصوصا زمانی که از caching در سرور خود استفاده کنید تا لازم نباشد صفحات همیشه در سمت سرور ساخته شوند. در caching صفحات را که تغییر نمی کنند ذخیره کرده و در درخواست های بعدی بدون نیاز به ساخت دوباره، آن ها را مستقیما به سمت کاربر ارسال می کنیم که فرآیندی بسیار سریع است.
  • توسعه منظم و بسیار سریع به دلیل یکپارچگی پروژه در سمت کلاینت و سرور.

مزایای Next.js برای توسعه دهندگان

صرف نظر مزایای تجاری یا فنی، Next.js فایده هایی دارد که به راحتی نمی توانید از آن بگذرید:

  • صرفه جویی در زمان - اگر می خواهید یک برنامه پیچیده بسازید، ماهیت js اجازه می دهد تا در زمان صرفه جویی کنید.
  • بدون پیکربندی - به شما امکان می دهد به جای منطق برنامه، روی منطق تجاری برنامه خود تمرکز کنید. و برای کمک به شما، کامپایل و بسته‌بندی خودکار را فراهم می‌کند. به عبارت دیگر، Next از همان ابتدا برای production بهینه شده است.
  • تولید ایستا افزایشی – به شما این امکان را می‌دهد تا صفحات موجود را با رندر کردن دوباره آن‌ها در پس‌زمینه، به‌روزرسانی کنید. بنابراین محتوای استاتیک می‌تواند پویا شود.
  • ترکیبی از SSR و SSG - صفحات در زمان ساخت یا زمان درخواست رندر می شوند.
  • پشتیبانی از TypeScript - پیکربندی و کامپایل خودکار TypeScript
  • بازخوانی سریع - تجربه ویرایش زنده و سریع.
  • پشتیبانی داخلی از CSS - امکان وارد کردن فایل های CSS از یک فایل جاوا اسکریپت.

معایب استفاده از Next.js

تعداد مزایای Next بسیار زیاد است و به وضوح بیشتر از معایب آن است. با این حال، بیایید آنها را بنویسیم تا تا حد امکان عینی باشند.

  • توسعه و مدیریت - انعطاف پذیری ارائه شده توسط Next هزینه های خود را دارد. برای ایجاد همه تغییرات مورد نظر، به یک فرد متخصص با دانش مناسب نیاز داریم. خبر خوب این است که این شخص نباید توسعه دهنده باشد.
  • هزینه مداوم – از آن جایی که Next.js صفحات داخلی زیادی را render نمی کند، باید قسمت frontend خود را باید ایجاد کنید، که هر از گاهی به تغییرات نیاز دارد. این به این معنی است که برای انجام کار باید به یک توسعه دهنده پول پرداخت کنید.
  • پلاگین کم - شما نمی توانید از پلاگین های زیادی استفاده کنید.
  • عدم انعطاف پذیری سیستم routing - با اینکه سیستم routing مورد علاقه ما است اما قابل تغییر نیست. اگر شما دوست نداشته باشید از این سیستم استفاده کنید، هیچ راهی برای تغییر آن وجود ندارد.
  • محدودیت زبان سمت سرور - فریم ورک Next.js تکنولوژی سمت سرور خود را Node انتخاب کرده است و تغییر آن ممکن نیست. مثلا اگر بخواهید به جای Node از زبان PHP استفاده کنید ممکن نیست. حتی اگر بخواهید به جای Node از تکنولوژی بسیار مشابهی مانند Deno استفاده کنید باز هم ممکن نیست.
  • فقدان state-manager - با اینکه Next.js یک فریم ورک کامل است اما state manager ای ندارد بنابراین باید خودتان این موضوع را حل کنید. این مشکل در سمت کلاینت با پکیج هایی مانند Redux حل می شود.

چه چیزی می توانید با NEXT.JS بسازید؟

با Next.js می توانید موارد زیر را بسازید:

  • MVP
  • وب سایت های Jamstack
  • پورتال های وب
  • Single web pages
  • وب سایت های استاتیک
  • محصول های SaaS
  • وب سایت های تجارت الکترونیک و عمده فروشی
  • داشبوردها
  • برنامه های کاربردی تحت وب
  • رابط های کاربری تعاملی

وب سایت های ساخته شده با Nextjs

وب سایت هایی را که با Nextjs ساخته شده اند، می توانید در زیر ببینید:

https://nike.com
https://nike.com
https://m.twitch.tv
https://ferrari.com
https://ferrari.com

یک پروژه کوچک با Next.js

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

تصویر کامل پروژه
تصویر کامل پروژه

نوشتن پروژه

پیش از نوشتن پروژه مطمئن شوید node را در سیستم خود نصب کرده اید. برای نصب آن می توانید به سایت آن مراجعه کنید. ابتدا یک پوشه خالی با نام pokedex ایجاد می کنیم. سپس آن را با vscode باز می کنیم. در vscode ترمینال را باز کرده و دستور زیر را برای ایجاد یک پروژه جدید Next.js می نویسیم.

نصب Next.js
نصب Next.js

نقطه پس از دستور npx create-next-app به معنی این است که پروژه را در همین پوشه ایجاد کن.پس از تمام شدن نصب پروژه باید تصویر زیر را ببینیم:

ساختار پروژه
ساختار پروژه

برای دیدن پروژه باید دستور npm run dev را ترمینال بنویسیم و سپس Enter را بزنیم. پس از این کار می توانیم برنامه خود را در آدرس  http://localhost:3000/ ببینیم:

قالب کلی Next.js
قالب کلی Next.js

تصویر بالا یک قالب کلی برای Next.js است.فایل اصلی این برنامه index.js است که در پوشه pages قرار دارد.این فایل به کمی تمیزکاری نیاز دارد.

این فایل را باز کنید و سپس کد زیر را در آن قرار دهید:

import Head from 'next/head'

export default function Home() {
  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1 style={{color:"purple",textAlign:"center", direction: "rtl"}}>
        ساخت pokedex با Roxo
        </h1>
      </main>
    </div>
  )
}

پس از نوشتن کد بالا صفحه زیر را خواهیم دید:

 

صفحه پس از تمیزکاری
صفحه پس از تمیزکاری

برای استایل دهی این پروژه از tailwindcss استفاده می کنیم. برای این کار دستور زیر را در ترمینال می نویسیم. ابتدا باید ترمینال را متوقف کنیم سپس دستور را بنویسیم:

نصب tailwincss
نصب tailwincss

سپس برای پیکربندی tailwindcss دستور زیر را در ترمینال می نویسیم. اگر پیکربندی با موفقیت انجام شود باید پیام Created Tailwind CSS config file: tailwind.config.js را ببینید مانند زیر:

پیکربندی tailwindcss
پیکربندی tailwindcss

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

فایل tailwind.config.js
فایل tailwind.config.js

فایل را باز کنید و کدهای زیر را در آن قرار دهید:

module.exports = {
  purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {},
  },
  variants: {  
    extend: {},
  },   
  plugins: [],
}

در ادامه کار یک فایل جدید در root خود به نام postcss.config.js ایجاد می کنیم و کد زیر را به آن اضافه می کنیم:

postcss.config.js
postcss.config.js
module.exports = {
    plugins: ['tailwindcss', 'postcss-preset-env'],
};


اکنون باید سراغ پوشه styles برویم. در این پوشه فایل Home.module.css را پاک می کنیم. پس از آن همه کدهای فایل globals.css را پاک می کنیم و کدهای زیر را در آن می نویسیم:

@tailwind base;

@tailwind components;

@tailwind utilities;

برای دیدن نتیجه استفاده از tailwindcss دوباره برنامه را با npm run dev اجرا می کنیم. پس از اجرا باید نوشته کوچک تر به نظر برسد مانند زیر:

برای داشتن یک کامپوننت که اجزای دیگر را دربر بگیرد کامپوننت Layout.js را در یک پوشه جدید به نام components ایجاد می کنیم. کد زیر را در این کامپوننت می نویسیم:

import React from 'react'
import Head from 'next/head'

export default function Layout({title,children}) {
    return (
        <div className='bg-gray-300'>
            <Head>
                <title>{title}</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>
            <main className='container mx-auto max-w-xl pt-8 min-h-screen'>
                {children}
            </main>
        </div>
       
    )
}

تگ main در بالا با tailwindcss استایل دهی شده است. برای آشنایی بیش تر با tailwindcss می توانید به نشانی سر بزنید. حال باید کامپوننت Layout.js را وارد index.js کنیم تا بتوانیم از آن استفاده کنیم. کد زیر را جایگزین کدهای پیشین index.js می کنیم:

import Head from 'next/head'
import Layout from "../components/Layout"

export default function Home() {
  return (
    <Layout title="Nextjs Pokedex">
        <h1 className="text-4xl mb-8 text-center">
            Nextjs Pokedex
        </h1>
    </Layout>
  )
}

پس از باز کردن صفحه باید تصویر زیر را ببینیم:

از pokeapi برای نمایش داده های خود استفاده می کنیم. با استفاده از تابع getStaticProps داده خود را از این api واکشی می کنیم. getStaticProps یک تابع همگام است که باید آن را در داخل کامپوننت page خود export کنیم که در این جا index.js است. در این تابع می توانیم هر کدی (بک اند) که روی سرور بک اند اجرا می شود را بنویسیم. یک مزیت دیگر این است که، کدی که در داخل این تابع می نویسیم برای client قابل مشاهده نیست. اگر نیاز به ارتباط با دیتابیس داشته باشیم، این کار را در داخل این تابع انجام می دهیم و به این ترتیب پایگاه داده ما برای client قابل دستیابی نیست. تابع getStaticProps را در index.js تعریف می کنیم. کد آن در زیر آمده است:

export async function getStaticProps(context) {
  try {
      const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=150');
      const { results } = await res.json();
      const pokemon = results.map((pokemon, index) => {
          const paddedId = ('00' + (index + 1)).slice(-3);

          const image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
          return { ...pokemon, image };
      });
      return {
          props: { pokemon },
      };
  } catch (err) {
      console.error(err);
  }
}

در این تابع از trycatch برای نوشتن کد خود استفاده کرده ایم تا به این ترتیب خطاهای احتمالی را مدیریت کنیم. سپس با استفاده از fetch داده های خود را ازhttps://pokeapi.co/api/v2/pokemon?limit=150 واکشی می کنیم. از این api صد و پنجاه pokemon وارد برنامه خود می کنیم. این داده های واکشی شده تصویر ندارند. برای این که برای کدام از آن ها یک تصویر مناسب نمایش دهیم از https://assets.pokemon.com/assets/cms2/img/pokedex/full/001.png استفاده می کنیم. اگر این url را باز کنیم تصویر زیر را می بینیم:

تصویر pokemon
تصویر pokemon

در این url، 001.png شماره اولین pokemon است.با تغییر این شماره می توان pokemon متفاوتی به دست آورد. در داده هایی که fetch به دست آورده است map می کنیم و id هر pokemon را به دست آورده و در متغیر paddledId قرار می دهیم. برای تعریف تصویر از متغیر image استفاده می کنیم و از id موجود در paddledId  برای به دست آوردن یک pokemon خاص استفاده می کنیم. paddledId به جای شماره عکس می گذاریم. این نکته را فراموش نکنید که حتما پس از شماره عکس پسوند .png را قرار بدهید. سپس یک شی جدید ایجاد می کنیم. این شی شامل pokemon و تصویر مناسب آن است. این را با return برمی گردانیم.

const pokemon = results.map((pokemon, index) => {
    const paddedId = ('00' + (index + 1)).slice(-3);

    const image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
    return { ...pokemon, image };
});

پس از آن باید pokemon را برگردانیم تا در فایل های دیگر بتوانیم از آن استفاده کنیم:

return {
    props: { pokemon },
};

برای نمایش pokemon ها در بالای همین فایل (index.js) یعنی در کامپوننت Home تغییرات زیر را اعمال می کنیم:

export default function Home({ pokemon }) {
    return (
        <Layout title="NextJS Pokedex">
            <h1 className="text-4xl mb-8 text-center ">The Nextjs Pokedex</h1>
            <ul>
                {pokemon.map((pokeman, index) => (
                    <li key={index}>
                        <Link href={`/pokemon?id=${index + 1}`}>
                            <a className="border p-4 border-grey my-2 hover:shadow-md capitalize flex items-center text-lg bg-gray-200 rounded-md">
                                <img
                                    src={pokeman.image}
                                    alt={pokeman.name}
                                    className="w-20 h-20 mr-3"
                                />
                                <span className="mr-2 font-bold">
                                    {index + 1}.
                                </span>
                                {pokeman.name}
                            </a>
                        </Link>
                    </li>
                ))}
            </ul>
        </Layout>
    );
}

حالا اگر صفحه را باز کنیم باید تصویر زیر را ببینیم:

تصویر برنامه
تصویر برنامه

اگر روی هر pokemon کلیک کنیم تصویر و جزئیات او نمایش داده نمی شود و با تصویر زیر رو به رو می شویم:

404

برای رفع این مشکل یک صفحه جدید به نام pokemon در پوشه pages ایجاد می کنیم و کد زیر را در آن قرار می دهیم:

import React from 'react';
import Layout from '../components/Layout';
import Link from 'next/Link';
export default function pokemon({ pokeman }) {
    return (
        <Layout title={pokeman.name}>
            <h1 className="text-4xl mb-2 text-center capitalize">
                {pokeman.id}. {pokeman.name}
            </h1>
            <img className="mx-auto" src={pokeman.image} alt={pokeman.name} />
            <p>
                <span className="font-bold mr-2">Weight:</span> {pokeman.weight}
            </p>
            <p>
                <span className="font-bold mr-2">Height:</span>
                {pokeman.height}
            </p>
            <h2 className="text-2xl mt-6 mb-2">Types</h2>
            {pokeman.types.map((type, index) => (
                <p key="index">{type.type.name}</p>
            ))}
            <p className="mt-10 text-center">
                <Link href="/">
                    <a className="text-2xl underline">Home</a>
                </Link>
            </p>
        </Layout>
    );
}

export async function getServerSideProps({ query }) {
    const id = query.id;
    try {
        const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
        const pokeman = await res.json();
        const paddedId = ('00' + id).slice(-3);
        pokeman.image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
        return {
            props: { pokeman },
        };
    } catch (err) {
        console.error(err);
    }
}

قسمت ابتدایی این کد برای استایل دهی صفحه است. این فایل برای نمایش تصویر و سایر جزئیات pokemon به کار می رود. در این جا از تابع getServerSideProps استفاده می کنیم. getServerSideProps به ما اجازه می دهد صفحه ای را که داده های آن باید در زمان درخواست واکشی شوند، از پیش رندر کنیم. در این تابع داده ها دوباره از api واکشی می شوند و جای این که همه آن ها نمایش داده شوند یک pokemon نشان داده می شود. برای نمایش یک pokemon از id آن استفاده می شود. این id از پارامتر query می آید. این id با pokemon ترکیب می شود و سپس شی نهایی برگردانده می شود. پس از نوشتن کد بالا اگر صفحه را دوباره نگاه کنیم باید پس از کلیک کردن هر pokemon تصویر و جزئیات مربوط به آن را ببینیم. مانند زیر:

صفحه pokemon
صفحه pokemon

کد کامل این برنامه را می توانید از نشانی دانلود کنید.

امیدوارم این مقاله شما را با Next.js آشنا کرده باشد.

توصیه می کنیم مقاله زیر را که درباره آموزش کامل کار با Next.js است، از دست ندهید:

در یک مقاله جداگانه هم به بررسی قابلیت های جدید Next.js پرداخته ایم.


منابع: وب‌سایت‌های pagepro و tailwindcss و dev.to و nextjs و youtube

نویسنده شوید
دیدگاه‌های شما (2 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سهیل
04 بهمن 1401
با عرض سلام، بسیار توضیح قابل درک و مفیدی بود، درود بر شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محسن
23 شهریور 1400
خیلی کامل و خوب بود

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

روکسو
20 دی 1400
ممنون از همراهی شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.