الفرق بين المراجعتين ل"Next.js/upgrading"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 1: سطر 1:
 
<noinclude>{{DISPLAYTITLE:دليل ترقية إصدارات Next.js}}</noinclude>
 
<noinclude>{{DISPLAYTITLE:دليل ترقية إصدارات Next.js}}</noinclude>
إليك قائمة بالتغييرات التي تحدث عن ترقية إصدارات Next.js والمتطلبات اللازمة لكل منها.
+
إليك قائمة بالتغييرات التي تحدث عند ترقية إصدارات Next.js والمتطلبات اللازمة لكل منها.
 
== ترقية Next.js من النسخة 11 إلى 12 ==
 
== ترقية Next.js من النسخة 11 إلى 12 ==
  
سطر 7: سطر 7:
  
 
=== ترقية React إلى أحدث نسخة ===
 
=== ترقية React إلى أحدث نسخة ===
إن أدنى نسخة مدعومة React من هي <code>17.0.2</code>. نفِّذ الأمر التالي لترقية الإصدار الذي لديك:<syntaxhighlight lang="bash">
+
إن أدنى نسخة مدعومة من React هي <code>17.0.2</code>. نفِّذ الأمر التالي لترقية الإصدار الذي لديك:<syntaxhighlight lang="bash">
 
npm install react@latest react-dom@latest
 
npm install react@latest react-dom@latest
 
</syntaxhighlight>أو باستخدام  <code>yarn</code>:<syntaxhighlight lang="bash">
 
</syntaxhighlight>أو باستخدام  <code>yarn</code>:<syntaxhighlight lang="bash">
سطر 20: سطر 20:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== استبدال بالمفسّر Babel بالمصرِّف SWR ===
+
=== استبدال المفسّر Babel بالمصرِّف SWR ===
 
تستخدم Next.js حاليًا المصرِّف [https://swc.rs/ SWC] المكتوب بلغة Rust لتصريف شيفرة JavaScript و TypeScript. وهذا المصرِّف أسرع بسبع عشرة مرة من Babel عند تصريف الملفات المفردة وأسرع بخمس مرات عندما يتعلق الأمر بميزة التحديث السريع.
 
تستخدم Next.js حاليًا المصرِّف [https://swc.rs/ SWC] المكتوب بلغة Rust لتصريف شيفرة JavaScript و TypeScript. وهذا المصرِّف أسرع بسبع عشرة مرة من Babel عند تصريف الملفات المفردة وأسرع بخمس مرات عندما يتعلق الأمر بميزة التحديث السريع.
  
تدعم Next.js بشكل كامل التوافقية الرجعية للتطبيقات التي تستخدم [[Next.js/customizing babel config|تهيئة خاصة بمفسِّر Babel]]، ونُقلت جميع التحويلات التي تتعامل معها افتراضيًا مثل "styled-jsx" و "tree-shaking" الخاصة بالدوال <code>getStaticProps</code> / <code>getStaticPaths</code> / <code>getServerSideProps</code> إلى Rust.
+
تدعم Next.js بشكل كامل التوافقية الرجعية للتطبيقات التي تستخدم [[Next.js/customizing babel config|تهيئة خاصة بمفسِّر Babel]]، ونُقلت جميع التحويلات التي تتعامل معها افتراضيًا مثل "styled-jsx" و"tree-shaking" الخاصة بالدوال <code>getStaticProps</code> / <code>getStaticPaths</code> / <code>getServerSideProps</code> إلى Rust.
  
تتوقف Next.js عن استخدام SWC عندما يكون للتطبيق تهيئة Babel مخصصة، ويتراجع ليستخدم Babel عند تصريف شيفرة JavaScript/Typescript بنفس الطريقة التي استُخدمت في النسخة 11 من Next.js.
+
تتوقف Next.js عن استخدام SWC عندما يكون للتطبيق تهيئة Babel مخصصة، ويتراجع ليستخدم Babel عند تصريف شيفرة JavaScript/Typescript بنفس الطريقة التي استُخدمت في النسخة 11 من Next.js.
  
 
ستُنقل العديد من آليات التكامل مع المكتبات الخارجية التي تتطلب حاليًا تحويلات مخصصة إلى تحويلات في المستقبل القريب، ومن بين هذه التحويلات:
 
ستُنقل العديد من آليات التكامل مع المكتبات الخارجية التي تتطلب حاليًا تحويلات مخصصة إلى تحويلات في المستقبل القريب، ومن بين هذه التحويلات:
سطر 34: سطر 34:
  
 
=== استبدال المجمّع Terser بالمصرِّف SWR ===
 
=== استبدال المجمّع Terser بالمصرِّف SWR ===
يساعد استخدام SWC بدلًا Terser من سرعة تصغير شيفرة JavaScript، وذلك بتفعيل الراية <code>swcMinify</code> في الملف <code>next.config.js</code>:<syntaxhighlight lang="javascript">
+
يزيد استخدام SWC بدلًا من Terser من سرعة تصغير شيفرة JavaScript، وذلك بتفعيل الراية <code>swcMinify</code> في الملف <code>next.config.js</code>:<syntaxhighlight lang="javascript">
 
module.exports = {
 
module.exports = {
 
   swcMinify: true,
 
   swcMinify: true,
 
}
 
}
</syntaxhighlight>لا بد حاليًا من التأكيد عل استخدام SWC لتصغير الشيفرة لاختباره في تطبيقات Next.js الحقيقة قبل أن يُعتمد كمصرّف افتراضي في النسخة 12.1.
+
</syntaxhighlight>لا بد حاليًا من التأكيد على استخدام SWC لتصغير الشيفرة لاختباره في تطبيقات Next.js الحقيقية قبل أن يُعتمد كمصرّف افتراضي في النسخة 12.1.
  
 
=== التحسينات على تفسير تنسيقات styled-jsx ===
 
=== التحسينات على تفسير تنسيقات styled-jsx ===
أنجزنا مفسّر CSS جديد مبني على المفسّر الذي استُخدم في تحويل Babel الخاص يتنسيقات styled-jsx. طوّرت آلي  التعامل مع تنسيقات CSS في المفسّر الجديد، وستظهر أخطاء CSS الآن أثناء التطوير وعند تنفيذ الأمر <code>next build</code> بدلًا من تجاهلها و ظهور مشاكل غير متوقعة. لكن هذه التغييرات ستُطبق فقط عند استخدام styled-jsx.  
+
أنجزنا مفسّر CSS جديد مبني على المفسّر الذي استُخدم في تحويل Babel الخاص يتنسيقات styled-jsx. طوّرت آلية التعامل مع تنسيقات CSS في المفسّر الجديد، وستظهر أخطاء CSS الآن أثناء التطوير وعند تنفيذ الأمر <code>next build</code> بدلًا من تجاهلها وظهور مشاكل غير متوقعة. لكن هذه التغييرات ستُطبق فقط عند استخدام styled-jsx.  
  
 
=== تغير عنصر تغليف <code>next/image</code> ===
 
=== تغير عنصر تغليف <code>next/image</code> ===
تصير <code>next/image</code> الآن العنصر  <code><img></code> داخل عنصر <code><nowiki><span></nowiki></code> وليس <code><nowiki><div></nowiki></code>. فإن استخدم تطبيقك قاعدة CSS محددة تستهدف العنصر <code><nowiki><span></nowiki></code> مثل <code>container span.</code>، سيؤدي تحديث التطبيق إلى مطابقة عناصر التغليف ضمن المكوّن <code><Image></code>، لهذا لا بد من تحاشي ذلك بتقييد محدد التنسيق إلى قاعدة محددة مثل <code>container span.item.</code>، وتحديث المكوّن بإضافة الخاصية <code>className</code> ليصبح بالشكل <code></ "span className="item"></code>.  
+
تصير <code>next/image</code> الآن العنصر  <code><img></code> داخل عنصر <code><nowiki><span></nowiki></code> وليس <code><nowiki><div></nowiki></code>. فإن استخدم تطبيقك قاعدة CSS محددة تستهدف العنصر <code><nowiki><span></nowiki></code> مثل <code>container span.</code>، سيؤدي تحديث التطبيق إلى مطابقة عناصر التغليف ضمن المكوّن <code><Image></code>، لهذا لا بد من تحاشي ذلك بتقييد محدد التنسيق إلى قاعدة محددة مثل <code>container span.item.</code>، وتحديث المكوّن بإضافة الخاصية <code>className</code> ليصبح بالشكل <code></ "span className="item"></code>.  
  
إن كان لتطبيقك قاعدة تنسيق محددة تستهدف العنصر <code><nowiki><div></nowiki></code> الخاص بالمكوّن <code>next/image</code> مثل ، فقد لا تجده القاعدة بعد الآن. بإمكانك في هذه الحالة تحديث المحدد ليصبح <code>container span.</code>، أو يُفضّل إضافة العنصر <code><"div className="wrapper></code> ليغلّف المكوّن <code><Image></code> ومن ثم استهدف هذا الغلاف بقاعدة مثل <code>container .wrapper.</code>.
+
إن كان لتطبيقك قاعدة تنسيق محددة تستهدف العنصر <code><nowiki><div></nowiki></code> الخاص بالمكوّن <code>next/image</code> مثل <code>container span.</code>، فقد لا تجده القاعدة بعد الآن. بإمكانك في هذه الحالة تحديث المحدد ليصبح <code>container span.</code>، أو يُفضّل إضافة العنصر <code><"div className="wrapper></code> ليغلّف المكوّن <code><Image></code> ومن ثم استهدف هذا الغلاف بقاعدة مثل <code>container .wrapper.</code>.
  
 
لن تتغير الخاصية <code>className</code> وستبقى قادرًا على تمريرها إلى العنصر الداخلي <code><img></code>. لمزيد من المعلومات راجع صفحة [[Next.js/image optimization|تحسين الصور]] في توثيق Next.js.
 
لن تتغير الخاصية <code>className</code> وستبقى قادرًا على تمريرها إلى العنصر الداخلي <code><img></code>. لمزيد من المعلومات راجع صفحة [[Next.js/image optimization|تحسين الصور]] في توثيق Next.js.
  
 
=== استخدام WebSocket في تأسيس اتصالات HMR في Next.js ===
 
=== استخدام WebSocket في تأسيس اتصالات HMR في Next.js ===
استخدمت سابقًا تقنية دفع التحديثات من الخادم إلى العميل عبر اتصال HTTP أو ما يُعرف بالأحداث المرسلة من قبل الخادم SSEن وذلك لاستقبال تحديثات HMR (الاستبدال السريع للوحدات Hot Modules Replacement). تستخدكم الآن اتصالات مقبس ويب WebSocket.
+
استخدمت سابقًا تقنية دفع التحديثات من الخادم إلى العميل عبر اتصال HTTP أو ما يُعرف بالأحداث المرسلة من قبل الخادم SSE، وذلك لاستقبال تحديثات HMR (الاستبدال السريع للوحدات Hot Modules Replacement). تُستخدم الآن اتصالات مقبس ويب WebSocket.
  
في بعض الحالات التي تُستخدم فيها خوادم وسيطة لإرسال الطلبات إلى خادم ، لا بد من التأكد من صحة تخديم الطلب عند ترقيته. إذ قد تحتاج أن تضيف مثلًا الإعدادات التالية عند استخدام الخادم الوسيط nginx:<syntaxhighlight lang="javascript">
+
في بعض الحالات التي تُستخدم فيها خوادم وسيطة لإرسال الطلبات إلى خادم تطوير Next.js، لا بد من التأكد من صحة تخديم الطلب عند ترقيته. إذ قد تحتاج أن تضيف مثلًا الإعدادات التالية عند استخدام الخادم الوسيط nginx:<syntaxhighlight lang="javascript">
 
location /_next/webpack-hmr {
 
location /_next/webpack-hmr {
 
     proxy_pass http://localhost:3000/_next/webpack-hmr;
 
     proxy_pass http://localhost:3000/_next/webpack-hmr;
سطر 60: سطر 60:
 
     proxy_set_header Connection "upgrade";
 
     proxy_set_header Connection "upgrade";
 
}
 
}
</syntaxhighlight>أما في خوادم أخرى مثل <code>express</code>، فقد تحتاج إلى استخدام الدالة <code>app.all</code> للتاكد من صحة تمرير الطلب . إليك مثالًا:<syntaxhighlight lang="javascript">
+
</syntaxhighlight>أما في خوادم أخرى مثل <code>express</code>، فقد تحتاج إلى استخدام الدالة <code>app.all</code> للتاكد من صحة تمرير الطلب. إليك مثالًا:<syntaxhighlight lang="javascript">
 
app.all('/_next/webpack-hmr', (req, res) => {
 
app.all('/_next/webpack-hmr', (req, res) => {
 
   nextjsRequestHandler(req, res)
 
   nextjsRequestHandler(req, res)
سطر 78: سطر 78:
 
ألغي الخيار لمصلحة الدعم المدمج لتعقب الاعتماديات اللازمة لتشغيل الصفحة. فخلال عملية البناء <code>next build</code>، تتعقب Next.js تلقائيًا كل صفحة واعتمادياتها لتحديد كل الملفات التي يحتاجها التطبيق لنشر نسخة إنتاج منه.
 
ألغي الخيار لمصلحة الدعم المدمج لتعقب الاعتماديات اللازمة لتشغيل الصفحة. فخلال عملية البناء <code>next build</code>، تتعقب Next.js تلقائيًا كل صفحة واعتمادياتها لتحديد كل الملفات التي يحتاجها التطبيق لنشر نسخة إنتاج منه.
  
راجع صفحة [[Next.js/output file tracing|تعقب ملفات الخرج]] من توثيق لمعلومات أكثر، إن كنت تستخدم الخيار <code>target</code> مضبوطًا على القيمة <code>serverless</code>.
+
راجع صفحة [[Next.js/output file tracing|تعقب ملفات الخرج]] من توثيق Next.js لمعلومات أكثر، إن كنت تستخدم الخيار <code>target</code> مضبوطًا على القيمة <code>serverless</code>.
  
 
== الترقية من النسخة 10 إلى 11 ==
 
== الترقية من النسخة 10 إلى 11 ==
  
 
=== ترقية React إلى أحدث نسخة ===
 
=== ترقية React إلى أحدث نسخة ===
إن أدنى نسخة مدعومة React من هي  <code>17.0.2</code>. نفِّذ الأمر التالي لترقية الإصدار الذي لديك:<syntaxhighlight lang="bash">
+
إنّ أدنى نسخة مدعومة من React هي  <code>17.0.2</code>. نفِّذ الأمر التالي لترقية الإصدار الذي لديك:<syntaxhighlight lang="bash">
 
npm install react@latest react-dom@latest
 
npm install react@latest react-dom@latest
 
</syntaxhighlight>أو باستخدام  <code>yarn</code>:<syntaxhighlight lang="bash">
 
</syntaxhighlight>أو باستخدام  <code>yarn</code>:<syntaxhighlight lang="bash">
سطر 99: سطر 99:
 
يُعد Webpack 5 المحزّم الافتراضي لنسخ Next.js الآن. إن لم تستخدم تهيئة خاصة لهذا المحزّم في تطبيقك ستستخدم Next.js المحزّم Webpack 5. أما إن كنت تستخدم إعدادات خاصة، راجع [https://nextjs.org/docs/messages/webpack5 توثيق استخدام مع Next.js].
 
يُعد Webpack 5 المحزّم الافتراضي لنسخ Next.js الآن. إن لم تستخدم تهيئة خاصة لهذا المحزّم في تطبيقك ستستخدم Next.js المحزّم Webpack 5. أما إن كنت تستخدم إعدادات خاصة، راجع [https://nextjs.org/docs/messages/webpack5 توثيق استخدام مع Next.js].
  
=== مسح سيكون <code>distDir</code> الخيار الافتراضي الآن ===
+
=== مسح <code>distDir</code> سيكون الخيار الافتراضي الآن ===
سُتمسح محتويات المجلد الذي يضم خرج عملية البناء افتراضيًا (وهو <code>next.</code> افتراضيًا) ما عدا ذاكرة Next.js المؤقتة. فإن كان يتعلق تطبيقك بهذه الناحية، تستطيع تعطيل هذه الميزة الافتراضية الجديدة بإضافة الراية <code>cleanDistDir: false</code> ضمن الملف <code>next.config.js</code>.
+
ستُمسح محتويات المجلد الذي يضم خرج عملية البناء افتراضيًا (وهو <code>next.</code> افتراضيًا) ما عدا ذاكرة Next.js المؤقتة. فإن كان يتعلق تطبيقك بهذه الناحية، تستطيع تعطيل هذه الميزة الافتراضية الجديدة بإضافة الراية <code>cleanDistDir: false</code> ضمن الملف <code>next.config.js</code>.
  
 
=== دعم استخدام <code>PORT</code> عند تنفيذ الأمرين <code>next dev</code> و <code>next start</code> ===
 
=== دعم استخدام <code>PORT</code> عند تنفيذ الأمرين <code>next dev</code> و <code>next start</code> ===
تدعم استخدام متغير البيئة لضبط المنفذ الذي سيعمل عليه التطبيق. ينصح باستخدام <code>p-</code> و <code>port--</code> حتى الآن، لكن حين تُمنع من استخدام <code>p-</code> يمكنك الآن استخدام <code>PORT</code>. إليك مثالًا:<syntaxhighlight lang="bash">
+
تدعم استخدام متغير البيئة لضبط المنفذ الذي سيعمل عليه التطبيق. ينصح باستخدام <code>p-</code> و <code>port--</code> حتى الآن، لكن حين تُمنع من استخدام <code>p-</code> يمكنك الآن استخدام <code>PORT</code>. إليك مثالًا:<syntaxhighlight lang="bash">
 
PORT=4000 next start
 
PORT=4000 next start
 
</syntaxhighlight>
 
</syntaxhighlight>
سطر 116: سطر 116:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== إزالة التابع <code>()super.componentDidCatch</code> من <code>pages/_app.js</code> ===
+
=== إزالة التابع <code>()super.componentDidCatch</code> من <code>pages/_app.js</code> ===
ألغي التابع العائد <code>()super.componentDidCatch</code> منذ الإصدارة 9 ولم يعد هنالك أي حاجة لاستخدامه، وقد أزيل في النسخة 11. إن احتوت الصفحة <code>pages/_app.js</code> تابع مخصص <code>componentDidCatch</code>، يمكنك إزالة <code>super.componentDidCatch</code> لأنك لن تحتاجه بعد الآن.
+
ألغي التابع العائد <code>()super.componentDidCatch</code> منذ الإصدار 9 ولم يعد هنالك أي حاجة لاستخدامه، وقد أزيل في النسخة 11. إن احتوت الصفحة <code>pages/_app.js</code> تابع مخصص <code>componentDidCatch</code>، يمكنك إزالة <code>super.componentDidCatch</code> لأنك لن تحتاجه بعد الآن.
  
=== إزالة <code>Container</code> من الصفحة <code>pages/_app.js</code> ===
+
=== إزالة <code>Container</code> من الصفحة <code>pages/_app.js</code> ===
 
ألغي هذا التصدير منذ الإصدار 9 ولم يعد هنالك حاجة إلى استخدامه، وقد أزيل في النسخة 11. إن أدرجت الصفحة <code>pages/_app.js</code> العنصر <code>Container</code> من المكوّن <code>next/app</code> يمكن إزالته.
 
ألغي هذا التصدير منذ الإصدار 9 ولم يعد هنالك حاجة إلى استخدامه، وقد أزيل في النسخة 11. إن أدرجت الصفحة <code>pages/_app.js</code> العنصر <code>Container</code> من المكوّن <code>next/app</code> يمكن إزالته.
  
سطر 130: سطر 130:
  
 
=== إزالة الخاصية <code>modules</code> من المكوّن <code>next/dynamic</code> ===
 
=== إزالة الخاصية <code>modules</code> من المكوّن <code>next/dynamic</code> ===
ألغيت الخاصيتان <code>modules</code> و <code>render</code> العائدتان للمكوّن <code>next/dynamic</code> ابتداءً من النسخة 9.5، وتعرض Next.js تنبيهًا أنهما ملغيتان. والسبب في ذلك جعل المكوّن <code>next/dynamic</code> قريبًا من <code>React.lazy</code> في الواجهة البرمجية API. أُزيلت الخاصيتان تمامًا في النسخة 11.
+
ألغيت الخاصيتان <code>modules</code> و <code>render</code> العائدتان للمكوّن <code>next/dynamic</code> ابتداءً من النسخة 9.5، وتعرض Next.js تنبيهًا أنهما ملغيّتان. والسبب في ذلك جعل المكوّن <code>next/dynamic</code> قريبًا من <code>React.lazy</code> في الواجهة البرمجية API. أُزيلت الخاصيتان تمامًا في النسخة 11.
  
 
لم يُشر إلى هذا الخيار في توثيق Next.js منذ النسخة 8 لهذا من غير المحتمل أن تراه مستخدمًا في أي تطبيق.
 
لم يُشر إلى هذا الخيار في توثيق Next.js منذ النسخة 8 لهذا من غير المحتمل أن تراه مستخدمًا في أي تطبيق.
سطر 138: سطر 138:
  
 
=== استثناء الإعدادات المحلية Moment.js افتراضيًا ===
 
=== استثناء الإعدادات المحلية Moment.js افتراضيًا ===
يتضمن الملف "Moment.js" ترجمة للكثير من الإعدادات المحلية افتراضيًا. وتستثني Next.js الآن افتراضيًا هذه الملفات لتحسين حجم تجميعة التطبيقات التي تستخدمها . ولهذا عليك أن تستخدم الشيفرة التالية لتضمين أي إعداد محلي:<syntaxhighlight lang="javascript">
+
يتضمن الملف "Moment.js" ترجمة للكثير من الإعدادات المحلية افتراضيًا. وتستثني Next.js الآن افتراضيًا هذه الملفات لتحسين حجم تجميعة التطبيقات التي تستخدمها . ولهذا عليك أن تستخدم الشيفرة التالية لتضمين أي إعداد محلي:<syntaxhighlight lang="javascript">
 
import moment from 'moment'
 
import moment from 'moment'
 
import 'moment/locale/ja'
 
import 'moment/locale/ja'
  
 
moment.locale('ja')
 
moment.locale('ja')
</syntaxhighlight>تستطيع تعطيل هذا الخيار الافتراضي بإضافة <code>excludeDefaultMomentLocales: false</code> إلى ملف التهيئة <code>next.config.js</code>. لكن عليك الانتباه بأن تعطيله غير محبّذ إطلاقًا لأنه يؤثر على إجراءات تحسين التي تساهم بشكل كبير في تقليل حجم الملف "Moment.js".
+
</syntaxhighlight>تستطيع تعطيل هذا الخيار الافتراضي بإضافة <code>excludeDefaultMomentLocales: false</code> إلى ملف التهيئة <code>next.config.js</code>. لكن عليك الانتباه بأن تعطيله غير محبّذ إطلاقًا لأنه يؤثر على إجراءات التحسين التي تساهم بشكل كبير في تقليل حجم الملف "Moment.js".
  
 
=== تحديث استخدام <code>router.events</code> ===
 
=== تحديث استخدام <code>router.events</code> ===
إن كنت تصل إلى <code>router.events</code> خلال التصيير فلن تتمكن من ذلك بعد الآن في خلال التصيير المسبق. تأكد من استخدام <code>useEffect</code> للوصول إلى <code>router.events</code> :<syntaxhighlight lang="javascript">
+
إن كنت تصل إلى <code>router.events</code> خلال التصيير فلن تتمكن من ذلك بعد الآن في Next.js 11 خلال التصيير المسبق. تأكد من استخدام <code>useEffect</code> للوصول إلى <code>router.events</code>:<syntaxhighlight lang="javascript">
 
useEffect(() => {
 
useEffect(() => {
 
   const handleRouteChange = (url, { shallow }) => {
 
   const handleRouteChange = (url, { shallow }) => {
سطر 166: سطر 166:
 
</syntaxhighlight>إن كنت تستخدم <code>router.router.events</code> في تطبيقك وهي خاصية داخلية لم تكن عامة، تأكد من استخدام <code>router.events</code> أيضًا.
 
</syntaxhighlight>إن كنت تستخدم <code>router.router.events</code> في تطبيقك وهي خاصية داخلية لم تكن عامة، تأكد من استخدام <code>router.events</code> أيضًا.
  
== استخدام React 16 و React 17 ==
+
== استخدام React 16 وReact 17 ==
أضافت React 17 تحويلات [https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html JSX Transform] جديدة أتاحت إمكانية استخدام  الإدراج <code>import React from 'react'</code> في Next.js عند استخدام بيئة React. تستخدم Next.js التحويل الجديد تلقائيًا مع النسخة 17 من React، والذي لا يجعل المتغير <code>React</code> متغيرًا عامًا لأن ذلك أدى إلى آثار جانبية غير مقصودة سابقًا. بالإمكان الآن استخدام [[Next.js/codemode|تحويلات Codemode]] لإصلاح الحالات التي تستخدم فيها <code>React</code> دون إدراج.
+
أضافت React 17 تحويلات [https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html JSX Transform] جديدة أتاحت إمكانية استخدام  الإدراج <code>import React from 'react'</code> في Next.js عند استخدام بيئة React. تستخدم Next.js التحويل الجديد تلقائيًا مع النسخة 17 من React، والذي لا يجعل المتغير <code>React</code> متغيرًا عامًا لأن ذلك أدى إلى آثار جانبية غير مقصودة سابقًا. بالإمكان الآن استخدام [[Next.js/codemods|تحويلات Codemode]] لإصلاح الحالات التي تستخدم فيها <code>React</code> دون إدراج.
  
 
== الترقية من الإصدار 9 إلى 10 في Next.js ==
 
== الترقية من الإصدار 9 إلى 10 في Next.js ==
سطر 181: سطر 181:
  
 
=== نشر نسخة الإنتاج على Vercel ===
 
=== نشر نسخة الإنتاج على Vercel ===
إن كنت قد هيأت في ملف لتكون ديناميكية، بالإمكان إزالة هذه القواعد عند الانتقال إلى الإصدار 9 لوجود ميزة [[Next.js/Routing|التوجيه الديناميكي]]. لا تتطلب الوجهات الديناميكية في الإصدار 9 أية تهيئة مخصصة <code>vercel.json</code> عند النشر على [https://vercel.com/ Vercel] بل تُهيأ تلقائيًا.
+
إن كنت قد هيأت <code>routes</code> في ملف <code>vercel.json</code> لتكون ديناميكية، بالإمكان إزالة هذه القواعد عند الانتقال إلى الإصدار 9 لوجود ميزة [[Next.js/Routing|التوجيه الديناميكي]]. لا تتطلب الوجهات الديناميكية في الإصدار 9 أية تهيئة مخصصة عند النشر على [https://vercel.com/ Vercel] بل تُهيأ تلقائيًا.
  
 
=== التحقق من التطبيقات المخصصة <code>pages/_app.js</code> ===
 
=== التحقق من التطبيقات المخصصة <code>pages/_app.js</code> ===
 
إن اطلعت سابقًا على المثال الذي أوردناه في صفحة [[Next.js/custom app|التطبيقات المخصصة باستخدام <code>App</code>]]"، سترى أنه من الممكن إزالة الدالة <code>getInitialProps</code>.
 
إن اطلعت سابقًا على المثال الذي أوردناه في صفحة [[Next.js/custom app|التطبيقات المخصصة باستخدام <code>App</code>]]"، سترى أنه من الممكن إزالة الدالة <code>getInitialProps</code>.
  
من المهم جدًا إزالة <code>getInitialProps</code> من التطبيقات المخصصة <code>pages/_app.js</code> عندما يكون ذلك ممكنًا لاستخدام ميزات الجديدة Next.js. فليس للدالة <code>getInitialProps</code> مثلًا عمل في هذه الشيفرة وبالإمكان إزالتها:<syntaxhighlight lang="javascript">
+
من المهم جدًا إزالة <code>getInitialProps</code> من التطبيقات المخصصة <code>pages/_app.js</code> عندما يكون ذلك ممكنًا لاستخدام ميزات Next.js الجديدة. فليس للدالة <code>getInitialProps</code> مثلًا عمل في هذه الشيفرة وبالإمكان إزالتها:<syntaxhighlight lang="javascript">
 
class MyApp extends App {
 
class MyApp extends App {
   // أزل هذه الشيفرة، فليس له وظيفة
+
   // أزل هذه الشيفرة،فليس لهاوظيفة
 
   static async getInitialProps({ Component, ctx }) {
 
   static async getInitialProps({ Component, ctx }) {
 
     let pageProps = {}
 
     let pageProps = {}

مراجعة 18:43، 12 يوليو 2022

إليك قائمة بالتغييرات التي تحدث عند ترقية إصدارات Next.js والمتطلبات اللازمة لكل منها.

ترقية Next.js من النسخة 11 إلى 12

النسخة الأدنى من Node.js

رُفع متطلب الحد الأدنى لنسخة Node.js من 12.0.0 إلى 12.22.0، وهي أولى نسخ Node.js التي تدعم وحدات ES الأساسية.

ترقية React إلى أحدث نسخة

إن أدنى نسخة مدعومة من React هي 17.0.2. نفِّذ الأمر التالي لترقية الإصدار الذي لديك:

npm install react@latest react-dom@latest

أو باستخدام yarn:

yarn add react@latest react-dom@latest

ترقية Next.js إلى الإصدار 12

نفِّذ الأمر التالي:

npm install next@12

أو:

yarn add next@12

استبدال المفسّر Babel بالمصرِّف SWR

تستخدم Next.js حاليًا المصرِّف SWC المكتوب بلغة Rust لتصريف شيفرة JavaScript و TypeScript. وهذا المصرِّف أسرع بسبع عشرة مرة من Babel عند تصريف الملفات المفردة وأسرع بخمس مرات عندما يتعلق الأمر بميزة التحديث السريع.

تدعم Next.js بشكل كامل التوافقية الرجعية للتطبيقات التي تستخدم تهيئة خاصة بمفسِّر Babel، ونُقلت جميع التحويلات التي تتعامل معها افتراضيًا مثل "styled-jsx" و"tree-shaking" الخاصة بالدوال getStaticProps / getStaticPaths / getServerSideProps إلى Rust.

تتوقف Next.js عن استخدام SWC عندما يكون للتطبيق تهيئة Babel مخصصة، ويتراجع ليستخدم Babel عند تصريف شيفرة JavaScript/Typescript بنفس الطريقة التي استُخدمت في النسخة 11 من Next.js.

ستُنقل العديد من آليات التكامل مع المكتبات الخارجية التي تتطلب حاليًا تحويلات مخصصة إلى تحويلات في المستقبل القريب، ومن بين هذه التحويلات:

  • Styled Components
  • Emotion
  • Relay

استبدال المجمّع Terser بالمصرِّف SWR

يزيد استخدام SWC بدلًا من Terser من سرعة تصغير شيفرة JavaScript، وذلك بتفعيل الراية swcMinify في الملف next.config.js:

module.exports = {
  swcMinify: true,
}

لا بد حاليًا من التأكيد على استخدام SWC لتصغير الشيفرة لاختباره في تطبيقات Next.js الحقيقية قبل أن يُعتمد كمصرّف افتراضي في النسخة 12.1.

التحسينات على تفسير تنسيقات styled-jsx

أنجزنا مفسّر CSS جديد مبني على المفسّر الذي استُخدم في تحويل Babel الخاص يتنسيقات styled-jsx. طوّرت آلية التعامل مع تنسيقات CSS في المفسّر الجديد، وستظهر أخطاء CSS الآن أثناء التطوير وعند تنفيذ الأمر next build بدلًا من تجاهلها وظهور مشاكل غير متوقعة. لكن هذه التغييرات ستُطبق فقط عند استخدام styled-jsx.

تغير عنصر تغليف next/image

تصير next/image الآن العنصر <img> داخل عنصر <span> وليس <div>. فإن استخدم تطبيقك قاعدة CSS محددة تستهدف العنصر <span> مثل container span.، سيؤدي تحديث التطبيق إلى مطابقة عناصر التغليف ضمن المكوّن <Image>، لهذا لا بد من تحاشي ذلك بتقييد محدد التنسيق إلى قاعدة محددة مثل container span.item.، وتحديث المكوّن بإضافة الخاصية className ليصبح بالشكل </ "span className="item">.

إن كان لتطبيقك قاعدة تنسيق محددة تستهدف العنصر <div> الخاص بالمكوّن next/image مثل container span.، فقد لا تجده القاعدة بعد الآن. بإمكانك في هذه الحالة تحديث المحدد ليصبح container span.، أو يُفضّل إضافة العنصر <"div className="wrapper> ليغلّف المكوّن <Image> ومن ثم استهدف هذا الغلاف بقاعدة مثل container .wrapper..

لن تتغير الخاصية className وستبقى قادرًا على تمريرها إلى العنصر الداخلي <img>. لمزيد من المعلومات راجع صفحة تحسين الصور في توثيق Next.js.

استخدام WebSocket في تأسيس اتصالات HMR في Next.js

استخدمت سابقًا تقنية دفع التحديثات من الخادم إلى العميل عبر اتصال HTTP أو ما يُعرف بالأحداث المرسلة من قبل الخادم SSE، وذلك لاستقبال تحديثات HMR (الاستبدال السريع للوحدات Hot Modules Replacement). تُستخدم الآن اتصالات مقبس ويب WebSocket.

في بعض الحالات التي تُستخدم فيها خوادم وسيطة لإرسال الطلبات إلى خادم تطوير Next.js، لا بد من التأكد من صحة تخديم الطلب عند ترقيته. إذ قد تحتاج أن تضيف مثلًا الإعدادات التالية عند استخدام الخادم الوسيط nginx:

location /_next/webpack-hmr {
    proxy_pass http://localhost:3000/_next/webpack-hmr;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

أما في خوادم أخرى مثل express، فقد تحتاج إلى استخدام الدالة app.all للتاكد من صحة تمرير الطلب. إليك مثالًا:

app.all('/_next/webpack-hmr', (req, res) => {
  nextjsRequestHandler(req, res)
})

إلغاء دعم الإصدار الرابع من Webpack

إن كنت تستخدم الإصدار الخامس من webpack فتجاوز هذه الفقرة.

تستخدم Next.js النسخة 11 برنامج التحزيم webpack 5 افتراضيًا أثناء تصريف التطبيقات. وتوقف دعم النسخة 4.

إن كنت لا تزال تستخدم webpack 4 في تطبيقاتك بوضع راية التحييد في ملف الإعدادات، سترى الآن رسالة خطأ تشير إلى موضوع رفع الدعم عن هذه النسخة.

إلغاء الخيار target

إن لم تستخدم الخيار target في ملف الإعدادات next.config.js يمكنك تجاوز هذه الفقرة.

ألغي الخيار لمصلحة الدعم المدمج لتعقب الاعتماديات اللازمة لتشغيل الصفحة. فخلال عملية البناء next build، تتعقب Next.js تلقائيًا كل صفحة واعتمادياتها لتحديد كل الملفات التي يحتاجها التطبيق لنشر نسخة إنتاج منه.

راجع صفحة تعقب ملفات الخرج من توثيق Next.js لمعلومات أكثر، إن كنت تستخدم الخيار target مضبوطًا على القيمة serverless.

الترقية من النسخة 10 إلى 11

ترقية React إلى أحدث نسخة

إنّ أدنى نسخة مدعومة من React هي 17.0.2. نفِّذ الأمر التالي لترقية الإصدار الذي لديك:

npm install react@latest react-dom@latest

أو باستخدام yarn:

yarn add react@latest react-dom@latest

ترقية Next.js إلى الإصدار 11

نفِّذ الأمر التالي:

npm install next@11

أو:

yarn add next@11

برنامج Webpack 5

يُعد Webpack 5 المحزّم الافتراضي لنسخ Next.js الآن. إن لم تستخدم تهيئة خاصة لهذا المحزّم في تطبيقك ستستخدم Next.js المحزّم Webpack 5. أما إن كنت تستخدم إعدادات خاصة، راجع توثيق استخدام مع Next.js.

مسح distDir سيكون الخيار الافتراضي الآن

ستُمسح محتويات المجلد الذي يضم خرج عملية البناء افتراضيًا (وهو next. افتراضيًا) ما عدا ذاكرة Next.js المؤقتة. فإن كان يتعلق تطبيقك بهذه الناحية، تستطيع تعطيل هذه الميزة الافتراضية الجديدة بإضافة الراية cleanDistDir: false ضمن الملف next.config.js.

دعم استخدام PORT عند تنفيذ الأمرين next dev و next start

تدعم استخدام متغير البيئة لضبط المنفذ الذي سيعمل عليه التطبيق. ينصح باستخدام p- و port-- حتى الآن، لكن حين تُمنع من استخدام p- يمكنك الآن استخدام PORT. إليك مثالًا:

PORT=4000 next start

تخصيص إعدادات next.config.js لإدراج الصور

تدعم النسخة الإدراج الساكن للصور من خلال المكوّن next/image. وتعتمد على معالجة الصورة المُدرجة. إن أضفت سابقًا الحزمتين next-images أو next-optimized-images، فبإمكانك الانتقال إلى الدعم المدمج الجديد باستخدام next/image أو إلغاء الميزة:

module.exports = {
  images: {
    disableStaticImages: true,
  },
}

إزالة التابع ()super.componentDidCatch من pages/_app.js

ألغي التابع العائد ()super.componentDidCatch منذ الإصدار 9 ولم يعد هنالك أي حاجة لاستخدامه، وقد أزيل في النسخة 11. إن احتوت الصفحة pages/_app.js تابع مخصص componentDidCatch، يمكنك إزالة super.componentDidCatch لأنك لن تحتاجه بعد الآن.

إزالة Container من الصفحة pages/_app.js

ألغي هذا التصدير منذ الإصدار 9 ولم يعد هنالك حاجة إلى استخدامه، وقد أزيل في النسخة 11. إن أدرجت الصفحة pages/_app.js العنصر Container من المكوّن next/app يمكن إزالته.

إزالة استخدام الخاصية props.url من مكوّنات الصفحة.

ألغي استخدام هذه الخاصية في الإصدار 4، ومنذ ذلك الوقت بدأت تظهر تنبيهات إلى هذا الموضوع أثناء تطوير التطبيق. لكن مع ظهور الدالتين getStaticProps و getServerSideProps لم يعد يُسمح باستخدام props.url. وقد ألغي تمامًا في الإصدار 11.

إزالة الخاصية unsized من المكوّن next/image

ألغيت الخاصية unsized في المكوّن next/image ابتداءً من النسخة 10.0.1، ويمكنك استخدام layout="fill" بدلًا منها. أزيلت هذه الخاصية تمامًا في النسخة 11.

إزالة الخاصية modules من المكوّن next/dynamic

ألغيت الخاصيتان modules و render العائدتان للمكوّن next/dynamic ابتداءً من النسخة 9.5، وتعرض Next.js تنبيهًا أنهما ملغيّتان. والسبب في ذلك جعل المكوّن next/dynamic قريبًا من React.lazy في الواجهة البرمجية API. أُزيلت الخاصيتان تمامًا في النسخة 11.

لم يُشر إلى هذا الخيار في توثيق Next.js منذ النسخة 8 لهذا من غير المحتمل أن تراه مستخدمًا في أي تطبيق.

إزالة Head.rewind

لم يعد للتابع Head.rewind استخدام منذ النسخة 9.5 وأزيل في النسخة 11. بإمكانك إزالة هذا التابع بأمان إن كنت قد استخدمته.

استثناء الإعدادات المحلية Moment.js افتراضيًا

يتضمن الملف "Moment.js" ترجمة للكثير من الإعدادات المحلية افتراضيًا. وتستثني Next.js الآن افتراضيًا هذه الملفات لتحسين حجم تجميعة التطبيقات التي تستخدمها . ولهذا عليك أن تستخدم الشيفرة التالية لتضمين أي إعداد محلي:

import moment from 'moment'
import 'moment/locale/ja'

moment.locale('ja')

تستطيع تعطيل هذا الخيار الافتراضي بإضافة excludeDefaultMomentLocales: false إلى ملف التهيئة next.config.js. لكن عليك الانتباه بأن تعطيله غير محبّذ إطلاقًا لأنه يؤثر على إجراءات التحسين التي تساهم بشكل كبير في تقليل حجم الملف "Moment.js".

تحديث استخدام router.events

إن كنت تصل إلى router.events خلال التصيير فلن تتمكن من ذلك بعد الآن في Next.js 11 خلال التصيير المسبق. تأكد من استخدام useEffect للوصول إلى router.events:

useEffect(() => {
  const handleRouteChange = (url, { shallow }) => {
    console.log(
      `App is changing to ${url} ${
        shallow ? 'with' : 'without'
      } shallow routing`
    )
  }

  router.events.on('routeChangeStart', handleRouteChange)

  // إن لم يكن المكوّن مثبتًا، فألغ الوصول إلى 
  // `off` الحدث باستخدام التابع 
  return () => {
    router.events.off('routeChangeStart', handleRouteChange)
  }
}, [router])

إن كنت تستخدم router.router.events في تطبيقك وهي خاصية داخلية لم تكن عامة، تأكد من استخدام router.events أيضًا.

استخدام React 16 وReact 17

أضافت React 17 تحويلات JSX Transform جديدة أتاحت إمكانية استخدام الإدراج import React from 'react' في Next.js عند استخدام بيئة React. تستخدم Next.js التحويل الجديد تلقائيًا مع النسخة 17 من React، والذي لا يجعل المتغير React متغيرًا عامًا لأن ذلك أدى إلى آثار جانبية غير مقصودة سابقًا. بالإمكان الآن استخدام تحويلات Codemode لإصلاح الحالات التي تستخدم فيها React دون إدراج.

الترقية من الإصدار 9 إلى 10 في Next.js

لا توجد تغييرات كبيرة بين الإصدارين 9 و 10، وكل ما عليك للترقية هو تنفيذ الأمر التالي:

npm install next@10

أو:

yarn add next@10

الترقية من الإصدار 8 إلى 9 في Next.js

تمهيد

نشر نسخة الإنتاج على Vercel

إن كنت قد هيأت routes في ملف vercel.json لتكون ديناميكية، بالإمكان إزالة هذه القواعد عند الانتقال إلى الإصدار 9 لوجود ميزة التوجيه الديناميكي. لا تتطلب الوجهات الديناميكية في الإصدار 9 أية تهيئة مخصصة عند النشر على Vercel بل تُهيأ تلقائيًا.

التحقق من التطبيقات المخصصة pages/_app.js

إن اطلعت سابقًا على المثال الذي أوردناه في صفحة التطبيقات المخصصة باستخدام App"، سترى أنه من الممكن إزالة الدالة getInitialProps.

من المهم جدًا إزالة getInitialProps من التطبيقات المخصصة pages/_app.js عندما يكون ذلك ممكنًا لاستخدام ميزات Next.js الجديدة. فليس للدالة getInitialProps مثلًا عمل في هذه الشيفرة وبالإمكان إزالتها:

class MyApp extends App {
  // أزل هذه الشيفرة،فليس لهاوظيفة
  static async getInitialProps({ Component, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx)
    }

    return { pageProps }
  }

  render() {
    // الخ
  }
}

تغييرات مفصلية

لا ضرورة لاستخدام التوجيه zeit/next-typescript@

تتجاهل في هذا الإصدار التوجيه zeit/next-typescript@ وتنبهك إلى ضرورة إزالته.

  • أزل الإضافة zeit/next-typescript@ من الملف next.config.js.
  • أزل الإشارات المرجعية إلى zeit/next-typescript@ في الملف babelrc. إن وجد.
  • أزل الملحق fork-ts-checker-webpack-plugin من الملف next.config.js.
  • تُنشر تعريفات TypeScript ضمن حزمة next، لهذا عليك إزالة types/next@ لمنع حدوث تعارض.
  • تختلف الأنواع التالية من:
import { NextContext } from 'next'
import { NextAppContext, DefaultAppIProps } from 'next/app'
import { NextDocumentContext, DefaultDocumentIProps } from 'next/document'

إلى:

import { NextPageContext } from 'next'
import { AppContext, AppInitialProps } from 'next/app'
import { DocumentContext, DocumentInitialProps } from 'next/document'

ملاحظة: أعدَّ هذه القائمة مجتمع Next لمساعدتك على الترقية، فإن وجدت اختلافات أخرى يمكن إرسال طلب سحب pull-request على هذه القائمة (في GitHub) لمساعدة بقية المستخدمين.

تصدير المفتاح config

لم يعد بالإمكان تصدير متغير اسمه config من صفحة كالتالي:

export { config }
// أو
export const config ...

يُستخدم هذا المتغيّر المُصدّر الآن لتخصيص إعداد Next.js على مستوى الصفحة مثل حالة استخدام AMP أو موجهات API.

عليك إعادة تسمية أي متغير config عند تصديره إن كان لا يتعلق بإعدادات Next.js

لا يصيّر next/dynamic أي شيء افتراضيًا أثناء التحميل

على الرغم من ذلك، يمكنك تخصيص هذا السلوك بضبط قيمة الخاصية loading:

import dynamic from 'next/dynamic'

const DynamicComponentWithCustomLoading = dynamic(
  () => import('../components/hello2'),
  {
    loading: () => <p>Loading</p>,
  }
)

إزالة withAmp لصالح كائن تهيئة مُصدّر

تعتمد Next.js في هذا الإصدار مفهوم التهيئة على مستوى الصفحات، لهذا أزيل مكوّن المستوى الأعلى withAmp. يمكن تهجير migrate هذا الإعداد تلقائيًا بتنفيذ الشيفرة التالية في جذر مشروعك:

curl -L https://github.com/vercel/next-codemod/archive/master.tar.gz | tar -xz --strip=2 next-codemod-master/transforms/withamp-to-config.js npx jscodeshift -t ./withamp-to-config.js pages/**/*.js

لتنفيذ هذا التهجير يدويًا أو متابعة ما يوّلده تحويل codemode، إلق نظرة على التالي: قبل:

import { withAmp } from 'next/amp'

function Home() {
  return <h1>My AMP Page</h1>
}

export default withAmp(Home)
// or
export default withAmp(Home, { hybrid: true })

بعد:

export default function Home() {
  return <h1>My AMP Page</h1>
}

export const config = {
  amp: true,
  // or
  amp: 'hybrid',
}

لن تصدر next export الصفحات إلى index.html

صُدِّر الملف pages/about.js سابقًا إلى out/about/index.html. لكنه يُصدَّر الآن إلى out/about.html.

يمكنك العودة إلى السلوك السابق بإضافة الإعداد التالي إلى next.config.js:

// next.config.js
module.exports = {
  trailingSlash: true,
}

معاملة مختلف لمكونات المجلد /pages/api

تُعد جميع الملفات في هذا المجلد وجهات API، ولن يتضمن تجميعات خاصة بواجهة العميل.

الميزات الملغاة في Next.js

إلغاء تحميل عدة وحدات برمجية معًا من خلال next/dynamic

وذلك كي يشابه المكوّن next/dynamic الكائنات (React.lazy و Suspense) في React.

لن تصادفك أية عقبات تقريبًا في تحديث الشيفرة المتعلقة بهذا الموضوع، وقد أوردنا مثالًا لمساعدتك على تهجير التطبيق.

قبل:

import dynamic from 'next/dynamic'

const HelloBundle = dynamic({
  modules: () => {
    const components = {
      Hello1: () => import('../components/hello1').then((m) => m.default),
      Hello2: () => import('../components/hello2').then((m) => m.default),
    }

    return components
  },
  render: (props, { Hello1, Hello2 }) => (
    <div>
      <h1>{props.title}</h1>
      <Hello1 />
      <Hello2 />
    </div>
  ),
})

function DynamicBundle() {
  return <HelloBundle title="Dynamic Bundle" />
}

export default DynamicBundle

بعد:

import dynamic from 'next/dynamic'

const Hello1 = dynamic(() => import('../components/hello1'))
const Hello2 = dynamic(() => import('../components/hello2'))

function HelloBundle({ title }) {
  return (
    <div>
      <h1>{title}</h1>
      <Hello1 />
      <Hello2 />
    </div>
  )
}

function DynamicBundle() {
  return <HelloBundle title="Dynamic Bundle" />
}

export default DynamicBundle

المصادر