انتشار نسخه پروداکشن اپلیکیشن در Next.js — آموزش Next.js (بخش پنجم و پایانی)
آخرین بخش هر راهنمای نرمافزاری به انتشار اپلیکیشن اختصاص دارد و از این رو در این بخش پایانی سری مقالات آموزش نکست در مورد انتشار نسخه پروداکشن اپلیکیشن در Next.js صحبت خواهیم کرد. برای مطالعه بخش قبلی روی لینک زیر کلیک کنید:
انتشار یک اپلیکیشن Next.js کار بسیار آسانی است. در بخشهای قبلی و بحث مربوط به نصب Next.js اشاره کردیم که باید 3 خط زیر را به بخش اسکریپت فایل package.json اضافه کنید:
1"scripts": {
2 "dev": "next",
3 "build": "next build",
4 "start": "next start"
5}
تا به اینجا از npm run dev برای فراخوانی دستور next که به صورت محلی در مسیر node_modules/next/dist/bin/next نصب شده است استفاده کردیم. بدین ترتیب سرور توسعه آغاز به کار کرد که نگاشتهای منبع و امکان بارگذاری مجدد سریع را در اختیار ما قرار داد. این دو امکان در زمان دیباگ کردن اپلیکیشن بسیار حائز اهمیت هستند.
میتوانیم با ارسال فلگ build و با اجرای دستور زیر، همین دستور را برای ساخت وبسایت فراخوانی کنیم:
npm run build
در ادامه همین دستور با ارسال فلگ start و اجرای دستور زیر میتواند برای آغاز اپلیکیشن پروداکشن مورد استفاده قرار گیرد:
npm run start
این دو دستور جهت انتشار موفق نسخه پروداکشن سایت به صورت لوکال ضروری هستند. نسخه پروداکشن کاملاً بهینهسازی شده است و نگاشتهای منبع و یا چیزهای دیگری مانند بارگذاری مجدد کد که به درد کاربران نهایی نمیخورد را حذف کرده است.
بنابراین در ادامه تلاش میکنیم نسخه پروداکشن اپلیکیشن خود را انتشار دهیم. آن را با دستور زیر میسازیم:
npm run build
خروجی دستور فوق به ما اعلام میکند که برخی مسیرها (/ و /blog) هماینک به صورت HTML استاتیک پیش-رندر شدهاند. در حالی که برخی مسیرهای دیگر مانند /blog/[id] از سوی بکاند Node.js عرضه میشوند. در ادامه میتوانید با اجرای دستور زیر نسخه پروداکشن را به صورت لوکال آغاز کنید:
npm run start
با مراجعه به آدرس http://localhost:3000 نسخه پروداکشن اپلیکیشن را به صورت لوکال خواهیم دید.
انتشار اپلیکیشن روی سرور
در بخش قبلی با روش انتشار لوکال نسخه پروداکشن اپلیکیشن Next.js آشنا شدیم. در این بخش مراحل انتشار اپلیکیشن روی سرور را ملاحظه خواهیم کرد.
یکی از سادهترین روشهای انتشار اپلیکیشن Next استفاده از پلتفرم Now است که به وسیله Zeit (+) ساخته شده است. این همان شرکتی است که پروژه اوپنسورس Next.js را ساخته است. میتوانید از Now برای انتشار اپلیکیشنهای Next.js، وبسایتهای استاتیک و مواردی از این دست استفاده کنید.
Now موجب میشود که مرحله انتشار و توزیع اپلیکیشن بسیار ساده و سریع شود. این پلتفرم علاوه بر اپلیکیشنهای Node.js از انتشار اپلیکیشنهای Go ،PHP ،Python و زبانهای دیگر نیز پشتیبانی میکند. Now را میتوان به عنوان یک فضای ابری تصور کرد که نمیدانیم اپلیکیشن دقیقاً کجا منتشر میشود، اما یک URL داریم که میتوانیم با آن به اپلیکیشن دسترسی داشته باشیم.
نسخه رایگان Now امکانات نسبتاً خوبی ارائه میکند که شامل 100 گیگابایت فضای میزبانی، 1000 اجرای تابع بدون سرور (Serverless) به صورت روزانه، 1000 build در ماه، 100 گیگابایت پهنای باند ماهانه و یک مکان CDN است. بهترین روش برای شروع استفاده از Now استفاده از CLI رسمی آن است:
npm install -g now
زمانی که دستور زیر آماده شد آن را اجرا کنید:
now login
اپلیکیشن از شما تقاضای یک ایمیل خواهد کرد. اگر قبلاً ثبت نام نکردهاید، پیش از ادامه باید یک حساب در این آدرس (https://zeit.co/signup) بسازید و سپس ایمیل آن را به کلاینت Cli بدهید. سپس در پروژه Next.js به پوشه روت رفته و دستور زیر را اجرا کنید:
Now
بدین ترتیب اپلیکیشن بیدرنگ روی فضای ابری Now انتشار مییابد و یک Url یکتا در اختیار شما قرار میگیرد:
زمانی که برنامه now را اجرا کنید، اپلیکیشن روی یک URL تصادفی زیردامنه now.sh انتشار مییابد. 3 URL متفاوت را در تصویر فوق میبینیم:
- https://firstproject-2pv7khwwr.now.sh
- https://firstproject-sepia-ten.now.sh
- https://firstproject.flaviocopes.now.sh
نخستین دلیل این که تعداد URL-ها زیاد است این است که هر بار که اپلیکیشن را توزیع کنید، URL تغییر خواهد یافت. میتوانید با تغییر دادن چیزی در اپلیکیشن و اجرای مجدد دستور now این موضوع را خودتان تحقیق کنید:
2 URL دیگر تغییر نمییابند. آدرس اول تصادفی است، آدرس دوم نام پروژه، نام حساب و سپس now.sh است. اگر به این URL بروید میبینید که اپلیکیشن به صورت پروداکشن انتشار یافته است:
میتوانید Now را طوری پیکربندی کنید که دامنه یا سابدامین فرعی شما را داشته باشد. سابدامین now.sh جهت مقاصد تست ما در حال حاضر کافی است.
تحلیل باندلهای اپلیکیشن
Next روشی برای تحلیل باندلهای کد که تولید کرده است در اختیار ما قرار میدهد. فایل package.json اپلیکیشن را باز کرده و در بخش اسکریپتها 3 دستور جدید زیر را اضافه کنید:
1"analyze": "cross-env ANALYZE=true next build",
2"analyze:server": "cross-env BUNDLE_ANALYZE=server next build",
3"analyze:browser": "cross-env BUNDLE_ANALYZE=browser next build"
به این ترتیب فایل به صورت زیر درمیآید:
1{
2 "name": "firstproject",
3 "version": "1.0.0",
4 "description": "",
5 "main": "index.js",
6 "scripts": {
7 "dev": "next",
8 "build": "next build",
9 "start": "next start",
10 "analyze": "cross-env ANALYZE=true next build",
11 "analyze:server": "cross-env BUNDLE_ANALYZE=server next build",
12 "analyze:browser": "cross-env BUNDLE_ANALYZE=browser next build"
13 },
14 "keywords": [],
15 "author": "",
16 "license": "ISC",
17 "dependencies": {
18 "next": "^9.1.2",
19 "react": "^16.11.0",
20 "react-dom": "^16.11.0"
21 }
22}
سپس دو پکیج را نصب کنید:
npm install --dev cross-env @next/bundle-analyzer
یک فایل به نام next.config.js در ریشه پروژه با محتوای زیر بسازید:
1const withBundleAnalyzer = require('@next/bundle-analyzer')({
2 enabled: process.env.ANALYZE === 'true'
3})
4
5module.exports = withBundleAnalyzer({})
سپس دستور زیر را اجرا کنید:
npm run analyze
بدین ترتیب 2 صفحه در مرورگر باز میشود که یکی باندلهای کلاینت و دیگر باندلهای سرور را نمایش میدهد:
این ابزار بسیار مفید است. بدین ترتیب میتوانید متوجه شوید کدام باندلهای حجم بیشتری اشغال کردهاند. همچنین میتوانید از سایدبار برای حذف باندلها و دستیابی به بصریسازی سادهتر استفاده کنید:
بارگذاری با تأخیر ماژولها
امکان تحلیل بصری باندل عالی است، چون میتوانیم اپلیکیشن خود را به صورتی کاملاً ساده بهینهسازی کنیم. فرض کنید میخواهیم کتابخانه Moment را در نوشتههای بلاگ بارگذاری کنیم. دستور زیر را اجرا میکنیم:
npm install moment
به این ترتیب در پروژه جای میگیرد. اکنون این واقعیت که در دو جا یعنی در /blog و /blog/[id] به آن نیاز داریم را شبیهسازی میکنیم. ابتدا در pages/blog/[id].js ایمپورت میکنیم:
1import moment from 'moment'
2
3...
4
5const Post = props => {
6 return (
7 <div>
8 <h1>{props.post.title}</h1>
9 <p>Published on {moment().format('dddd D MMMM YYYY')}</p>
10 <p>{props.post.content}</p>
11 </div>
12 )
13}
برای نمونه تنها تاریخ امروز را اضافه میکنیم. بدین ترتیب Moment.js در باندل صفحه نوشته بلاگ جای میگیرد. این نکته را با اجرای دستور زیر میتوانید تحقیق کنید:
npm run analyze
میبینید که هماینک یک مدخل قرمز در blog/[id]/ داریم. این مسیری است که Moment.js را اضافه کردهایم. چنان که میبینید حجم آن از حدود 1 کیلوبایت به 350 کیلوبایت رسیده است که بسیار بزرگ است. دلیل این مسئله آن است که حجم کتابخانه Moment.js 349 کیلوبایت است.
بصریسازی باندلهای کلاینت هماینک نشان میدهند که باندل بزرگتر، صفحه اول است که قبلاً کوچک بود و 99% کد آن نیز کتابخانه Moment.js است.
هر بار که صفحهای از وبسایت بارگذاری میشود این کتابخانه به کلاینت انتقال مییابد که وضعیت مناسبی محسوب نمیشود.
یکی از راهحلهای این مشکل آن است که به دنبال کتابخانهای با اندازه کوچکتر بگردیم، چون Moment.js با توجه به این که بهصورت پیشفرض همه locale-ها را شامل میشود، چندان سبک نیست، اما برای مثال تصور کنید میخواهیم همچنان از آن استفاده کنیم. کاری که میتوانیم انجام دهیم این است که همه کدهای Moment را در یک باندل جداگانه قرار دهیم.
بدین ترتیب به جای ایمپورت کردن Moment در سطح کامپوننت یک ایمپورت همگامسازی درون getInitialProps اجرا میکنیم و مقداری که باید به کامپوننت ارسال شود را محاسبه میکنیم. به خاطر داشته باشید که نمیتوانیم اشیای پیچیده را درون شیء بازگشتی ()getInitialProps ارسال کنیم و از این رو تاریخ را درون آن محاسبه میکنیم:
1import posts from '../../posts.json'
2
3const Post = props => {
4 return (
5 <div>
6 <h1>{props.post.title}</h1>
7 <p>Published on {props.date}</p>
8 <p>{props.post.content}</p>
9 </div>
10 )
11}
12
13Post.getInitialProps = async ({ query }) => {
14 const moment = (await import('moment')).default()
15 return {
16 date: moment.format('dddd D MMMM YYYY'),
17 post: posts[query.id]
18 }
19}
20
21export default Post
آیا به آن فراخوانی خاص به ()default. پس از await import توجه کردید؟ این فراخوانی جهت ارجاع به اکسپورت پیشفرض در یک ایمپورت دینامیک ضروری است. اکنون اگر دستور زیر را دوباره اجرا کنیم، نتیجهای مانند تصویر زیر میبینیم:
npm run analyze
هم اینک باندل blog/[id]/ ما دوباره بسیار کوچک شده است، چون Moment به فایل باندل خودش جابجا شده است و به صورت جداگانه از سوی مرورگر بارگذاری میشود.
سخن پایانی
موارد زیادی در خصوص فریمورک Next.js وجود دارند که باید بیاموزید. ما در این سری مقالات پنجگانه در مورد مدیریت نشستهای کاربر با لاگین، کد بدون سرور، مدیریت پایگاه داده و موارد زیاد دیگر صحبت نکردیم. هدف این راهنما این نبوده است که همه چیز را در مورد Next.js به شما آموزش دهد، بلکه قصد ما آشنا ساختن شما با قدرت Next.js بوده است.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- آموزش JavaScript ES6 (جاوا اسکریپت)
- آموزش Node.js: مفاهیم مقدماتی — بخش اول
- راهنمای جامع React (بخش اول) — از صفر تا صد
==
مرسی میثم جان. مقالاتت عالی بود واقعا