الترقية إلى الإصدار 9

لترقية إلى الإصدار 9، قم بتنفيذ الأمر التالي:

Terminal
npm install next@9

yarn add next@9

النشر الإنتاجي على Vercel

إذا كنت قد قمت سابقًا بتكوين routes في ملف vercel.json للطرق الديناميكية، فيمكن إزالة هذه القواعد عند استخدام ميزة التوجيه الديناميكي الجديدة في Next.js 9.

طرق Next.js 9 الديناميكية يتم تكوينها تلقائيًا على Vercel ولا تتطلب أي تخصيص في vercel.json.

يمكنك قراءة المزيد حول التوجيه الديناميكي هنا.

تحقق من ملف التطبيق المخصص (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 لم يعد ضروريًا

Next.js سيتجاهل الآن استخدام @zeit/next-typescript وسيحذرك لإزالته. يرجى إزالة هذه الإضافة من next.config.js.

قم بإزالة الإشارات إلى @zeit/next-typescript/babel من ملف .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'

مفتاح 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>جار التحميل</p>,
  }
)

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

Next.js لديه الآن مفهوم التكوين على مستوى الصفحة، لذا تمت إزالة مكون الترتيب العالي withAmp للاتساق.

يمكن إجراء هذا التغيير تلقائيًا عن طريق تنفيذ الأوامر التالية في جذر مشروع Next.js الخاص بك:

Terminal
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

لإجراء هذا الترحيل يدويًا، أو لعرض ما سينتجه التعديل البرمجي، انظر أدناه:

قبل

import { withAmp } from 'next/amp'

function Home() {
  return <h1>صفحتي AMP</h1>
}

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

بعد

export default function Home() {
  return <h1>صفحتي AMP</h1>
}

export const config = {
  amp: true,
  // أو
  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/ بشكل مختلف

الصفحات في pages/api/ تعتبر الآن طرق API. الصفحات في هذا الدليل لن تحتوي على حزمة جانب العميل بعد الآن.

الميزات المهملة

next/dynamic قد أهمل تحميل عدة وحدات في وقت واحد

تم إهمال القدرة على تحميل عدة وحدات في وقت واحد في next/dynamic لتكون أقرب إلى تنفيذ React (React.lazy و Suspense).

تحديث الكود الذي يعتمد على هذا السلوك سهل نسبيًا! لقد قدمنا مثالًا قبل/بعد لمساعدتك في ترحيل تطبيقك:

قبل

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="حزمة ديناميكية" />
}

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="حزمة ديناميكية" />
}

export default DynamicBundle