بعد 26 إصدارًا تجريبيًا و3.4 مليون عملية تنزيل، نفتخر بإطلاق الإصدار 7 من Next.js الجاهز للإنتاج، والذي يتضمن:
- تحسينات تجربة المطور (DX): بدء أسرع بنسبة 57%، إعادة تجميع أسرع بنسبة 42%
- تقارير أخطاء أفضل مع react-error-overlay
- ترقية خط أنابيب التجميع: Webpack 4 و Babel 7
- واردات ديناميكية موحدة
- دعم CDN ثابت
- حمل HTML أولي أصغر
- سياق React مع SSR بين التطبيق والصفحات
وأخيرًا، نحن متحمسون لمشاركة هذه الأخبار على الموقع الجديد Nextjs.org
تحسينات تجربة المطور (DX)
أحد الأهداف الرئيسية لـ Next.js هو توفير أفضل أداء للإنتاج مع أفضل تجربة ممكنة للمطور. يجلب هذا الإصدار العديد من التحسينات الهامة لخطوط أنابيب البناء والتصحيح
سرعة التجميع
بفضل webpack 4 و Babel 7 والعديد من التحسينات على قاعدة الكود الخاصة بنا، أصبح Next.js الآن يبدأ أسرع بنسبة تصل إلى 57% أثناء التطوير.
بفضل ذاكرة التخزين المؤقت الجديدة للتجميع التدريجي، ستكون التغييرات التي تجريها على الكود الآن أسرع بنسبة 40%.
هذه بعض الأرقام التي جمعناها:
6.0 | 7.0 | الفرق | |
---|---|---|---|
وقت البدء (تطبيق أساسي) | 1947 مللي ثانية | 835 مللي ثانية | أسرع بنسبة 57% |
تغيير الكود (تطبيق أساسي) | 304 مللي ثانية | 178 مللي ثانية | أسرع بنسبة 42% |
كمكافأة، أثناء التطوير والبناء، سترى الآن ملاحظات أفضل في الوقت الفعلي بفضل webpackbar:
تقارير أخطاء أفضل مع React Error Overlay
عرض أخطاء دقيقة ومساعدة أمر بالغ الأهمية لتجربة تطوير وتصحيح رائعة. حتى الآن، كنا نعرض رسالة الخطأ وتتبع المكدس الخاص بها. الآن، نستخدم react-error-overlay
لإثراء تتبع المكدس بـ:
- مواقع أخطاء دقيقة لكل من أخطاء الخادم والعميل
- تمييز المصدر لتوفير السياق
- تتبع مكدس كامل غني
هذه مقارنة بين ما قبل وبعد أخطائنا:
الطبقة السابقة على اليسار، react-error-overlay على اليمين
كمكافأة، يجعل react-error-overlay
من السهل فتح محرر النصوص الخاص بك بمجرد النقر على كتلة كود محددة.
Webpack 4
منذ إطلاقه الأول، كان Next.js يعمل بواسطة webpack لتجميع الكود الخاص بك وإعادة استخدام النظام البيئي الغني للإضافات والامتدادات. نحن متحمسون للإعلان عن أن Next.js يعمل الآن بأحدث إصدار من webpack 4، والذي يأتي مع العديد من التحسينات وإصلاحات الأخطاء.
من بين هذه الميزات:
- دعم ملفات المصدر
.mjs
- تحسينات في تقسيم الكود
- دعم أفضل لـ tree-shaking (إزالة الكود غير المستخدم)
ميزة جديدة أخرى هي دعم WebAssembly، يمكن لـ Next.js حتى عرض WebAssembly من جانب الخادم، هنا مثال.
ملاحظة: هذه الترقية متوافقة تمامًا مع الإصدارات السابقة. ومع ذلك، إذا كنت تستخدم محملات أو إضافات webpack مخصصة عبر next.config.js، فقد تحتاج إلى ترقيتها.
واردات CSS
مع webpack 4، تم تقديم طريقة جديدة لاستخراج CSS من الحزم، تسمى mini-extract-css-plugin.
@zeit/next-css
، @zeit/next-less
، @zeit/next-sass
، و @zeit/next-stylus
تعمل الآن بواسطة mini-extract-css-plugin
.
الإصدار الجديد من هذه الإضافات يحل 20 مشكلة موجودة تتعلق بواردات CSS؛ على سبيل المثال، أصبح استيراد CSS في import()
الديناميكي مدعومًا الآن:
import './my-dynamic-component.css';
export default function MyDynamicComponent() {
return <h1>My dynamic component</h1>;
}
import dynamic from 'next/dynamic'
const MyDynamicComponent = dynamic(import('../components/my-dynamic-component'))
export default function Index() {
return () {
<div>
<MyDynamicComponent/>
</div>
}
}
تحسين رئيسي هو أنك لم تعد بحاجة إلى إضافة ما يلي إلى pages/_document.js
:
<link rel="stylesheet" href="/_next/static/style.css" />
بدلاً من ذلك، يقوم Next.js بحقن ملف CSS تلقائيًا. في الإنتاج، يضيف Next.js أيضًا تلقائيًا تجزئة محتوى إلى عنوان URL لـ CSS، بحيث إذا كانت هناك تغييرات، لضمان أن المستخدمين النهائيين لا يحصلون أبدًا على إصدارات قديمة من الملف ولديهم القدرة على تقديم تخزين مؤقت دائم غير قابل للتغيير.
باختصار، كل ما عليك فعله لدعم استيراد ملفات .css
في مشروع Next.js الخاص بك هو تسجيل إضافة withCSS في next.config.js
:
const withCSS = require('@zeit/next-css');
module.exports = withCSS({
/* my next config */
});
واردات ديناميكية موحدة
كان Next.js يدعم الواردات الديناميكية عبر next/dynamic
منذ الإصدار 3.
كمتبنين مبكرين لهذه التقنية، كان علينا كتابة حلنا الخاص للتعامل مع import()
.
نتيجة لذلك، بدأ Next.js يتباعد عن الدعم الذي قدمه webpack لاحقًا له وكانت بعض الميزات مفقودة.
بسبب هذا، لم يدعم Next.js بعض ميزات import()
التي قدمها webpack منذ ذلك الحين.
على سبيل المثال، لم يكن من الممكن تسمية وتجميع ملفات معينة معًا يدويًا:
import(/* webpackChunkName: 'my-chunk' */ '../lib/my-library');
مثال آخر هو استخدام import()
دون أن يتم تغليفه في وحدة next/dynamic
.
بدءًا من Next.js 7، لم نعد نغير سلوك import()
الافتراضي. هذا يعني أنك تحصل على دعم كامل لـ import() مباشرةً.
هذا التغيير متوافق تمامًا مع الإصدارات السابقة أيضًا. يظل استخدام مكون ديناميكي بسيطًا كما يلي:
import dynamic from 'next/dynamic';
const MyComponent = dynamic(import('../components/my-component'));
export default function Index() {
return (
<div>
<MyComponent />
</div>
);
}
ما يفعله هذا المثال هو إنشاء ملف JavaScript جديد لـ my-component
وتحميله فقط عند عرض <MyComponent />
.
الأهم من ذلك، إذا لم يتم عرضه، فإن علامة <script>
لا يتم تضمينها في حمل HTML الأولي للمستند.
لمزيد من تبسيط قاعدة الكود لدينا والاستفادة من النظام البيئي الرائع لـ React، في Next.js 7 تمت إعادة كتابة next/dynamic
لاستخدام react-loadable
خلف الكواليس (مع بعض التعديلات الطفيفة). هذا يقدم أيضًا ميزتين رائعتين جديدتين للمكونات الديناميكية:
- مهلات باستخدام خيار
timeout
فيnext/dynamic
- تأخير مكون التحميل، باستخدام خيار
delay
فيnext/dynamic
. يسمح هذا التأخير لمكونloading
الخاص بك بالانتظار لفترة x قبل عرض حالة التحميل، على سبيل المثال، إذا كان الاستيراد سريعًا جدًا.
Babel 7
قدم Next.js 6 Babel 7 بينما كان لا يزال في مرحلة التجريب. منذ ذلك الحين، تم إصدار النسخة المستقرة من Babel 7، و Next.js 7 يستخدم الآن هذه النسخة.
للحصول على قائمة كاملة بالتغييرات، يمكنك الرجوع إلى ملاحظات الإصدار الخاصة بـ Babel.
بعض الميزات الرئيسية هي:
- دعم Typescript، بالنسبة لـ Next.js يمكنك استخدام
@zeit/next-typescript
- دعم بناء جملة Fragment
<>
- دعم
babel.config.js
- خاصية
overrides
لتطبيق الإعدادات المسبقة/الإضافات فقط على مجموعة فرعية من الملفات أو الدلائل
إذا لم يكن لديك تكوين Babel مخصص في مشروع Next.js الخاص بك، فلا توجد تغييرات غير متوافقة.
إذا كان لديك تكوين Babel مخصص، فيجب عليك ترقية الإضافات/الإعدادات المسبقة المخصصة إلى أحدث إصدار.
في حالة الترقية من إصدار أقدم من Next.js 6، يمكنك تشغيل أداة babel-upgrade
الممتازة.
بالإضافة إلى الترقية إلى Babel 7، فإن الإعداد المسبق لـ Babel في Next.js (next/babel
) يحدد الآن خيار modules
إلى commonjs
عندما يتم تعيين NODE_ENV
إلى test
.
كان خيار التكوين هذا غالبًا هو السبب الوحيد لإنشاء .babelrc
مخصص في مشروع Next.js:
{
"env": {
"development": {
"presets": ["next/babel"]
},
"production": {
"presets": ["next/babel"]
},
"test": {
"presets": [["next/babel", { "preset-env": { "modules": "commonjs" } }]]
}
}
}
مع Next.js 7 يصبح هذا:
{
"presets": ["next/babel"]
}
في هذه المرحلة، يمكن إزالة .babelrc
، حيث سيقوم Next.js بعد ذلك تلقائيًا باستخدام next/babel
عندما لا يكون هناك تكوين Babel.
حمل HTML أولي أصغر
بما أن Next.js يعرض HTML مسبقًا، فإنه يلف الصفحات في بنية افتراضية مع <html>
، <head>
، <body>
وملفات JavaScript اللازمة لعرض الصفحة.
كان هذا الحمل الأولي سابقًا حوالي 1.62 كيلوبايت. مع Next.js 7 قمنا بتحسين حمل HTML الأولي، وهو الآن 1.5 كيلوبايت، بانخفاض 7.4%، مما يجعل صفحاتك أكثر خفة.
6.0 | 7.0 | الفرق | |
---|---|---|---|
حجم المستند (عرض من الخادم) | 1.62 كيلوبايت | 1.50 كيلوبايت | أصغر بنسبة 7.4% |
الطرق الرئيسية التي قللنا بها الحجم هي:
- تمت إزالة div
__next-error
- تم تصغير النصوص البرمجية المضمنة، وفي إصدار مستقبلي سيتم إزالتها تمامًا
- تم تجميع خصائص
__NEXT_DATA__
غير المستخدمة عندما لا تكون مستخدمة، على سبيل المثال، خصائصnextExport
وassetPrefix
.
دعم CDN ثابت
في Next.js 5 قدمنا دعم assetPrefix
، وهي طريقة لجعل Next.js يقوم تلقائيًا بتحميل الأصول من موقع معين، عادةً CDN. يعمل هذا الخيار بشكل رائع إذا كان CDN الخاص بك يدعم التكرار، فأنت تطلب عنوان URL مثل
https://cdn.example.com/_next/static/<buildid>/pages/index.js
عادةً، يتحقق CDN مما إذا كان لديه الملف في ذاكرته المؤقتة، أو يطلبه مباشرة من المصدر.
هذا بالضبط كيف تعمل شبكة Edge.
ومع ذلك، تتطلب بعض الحلول تحميل دليل مباشرةً إلى CDN. المشكلة في القيام بذلك هي أن بنية URL الخاصة بـ Next.js لم تكن تطابق بنية المجلد داخل مجلد .next
. على سبيل المثال مثالنا السابق
https://cdn.example.com/_next/static/<buildid>/pages/index.js
// تم تعيينه إلى:
.next/page/index.js
مع Next.js 7 قمنا بتغيير بنية الدليل لـ .next
لتطابق بنية URL:
https://cdn.example.com/_next/static/<buildid>/pages/index.js
// تم تعيينه إلى:
.next/static/<buildid>/pages/index.js
بينما نوصي باستخدام نوع CDN الذي يعمل بالتكرار، تسمح هذه البنية الجديدة لمستخدمي نوع مختلف من CDN بتحميل دليل .next
إلى CDN الخاص بهم.
Styled JSX v3
نحن متحمسون لتقديم styled-jsx 3، حل CSS-in-JS المضمن افتراضيًا في Next.js أصبح الآن جاهزًا لـ React Suspense.
كان أحد الأشياء التي كانت غالبًا غير واضحة هو كيفية تنسيق مكون فرعي إذا لم يكن ذلك المكون جزءًا من نطاق المكون الحالي، على سبيل المثال، إذا قمت بتضمين مكون فرعي يحتاج إلى أنماط محددة فقط عند استخدامه داخل المكون الأصلي:
const ChildComponent = () => (
<div>
<p>some text</p>
</div>
);
export default function Index() {
return (
<div>
<ChildComponent />
<style jsx>{`
p {
color: black;
}
`}</style>
</div>
);
}
الكود أعلاه يحاول تحديد علامة p
لا يعمل لأن أنماط styled-jsx محدودة بالمكون الحالي، فهي لا تتسرب إلى المكونات الفرعية. إحدى الطرق للالتفاف حول هذا كانت استخدام طريقة :global
، وإزالة البادئة من علامة p
. ومع ذلك، هذا يقدم مشكلة جديدة، وهي أن الأنماط تتسرب عبر الصفحة.
في styled-jsx 3 تم حل هذه المشكلة عن طريق تقديم واجهة برمجة تطبيقات جديدة، css.resolve
، والتي ستولد className
وعلامات <style>
(خاصية styles
) لسلسلة styled-jsx المحددة:
import css from 'styled-jsx/css';
const ChildComponent = ({ className }) => (
<div>
<p className={className}>some text</p>
</div>
);
const { className, styles } = css.resolve`
p {
color: black;
}
`;
export default function Index() {
return (
<div>
<ChildComponent className={className} />
{styles}
</div>
);
}
تسمح واجهة برمجة التطبيقات الجديدة هذه بتمرير التنسيق المخصص إلى المكونات الفرعية بشكل شفاف.
نظرًا لأن هذا إصدار رئيسي لـ styled-jsx، فهناك تغيير غير متوافق واحد يحسن أحجام الحزم إذا كنت تستخدم styles-jsx/css
. في styled-jsx 2 كنا ننشئ إصدارًا "محدودًا" و"عامًا" من الأنماط الخارجية، حتى عندما كان يتم استخدام الإصدار "المحدود" فقط، كنا ما زلنا نضمن الإصدار "العام" من تلك الأنماط الخارجية.
مع styled-jsx 3 يجب وضع علامة على الأنماط العامة بـ css.global
بدلاً من css
، حتى يتمكن styled-jsx من تحسين حجم الحزمة.
لجميع التغييرات، يرجى الرجوع إلى ملاحظات الإصدار.
سياق React مع SSR بين التطبيق والصفحات
بدءًا من Next.js 7، ندعم الآن واجهة برمجة تطبيقات سياق React الجديدة بين pages/_app.js
ومكونات الصفحة.
سابقًا لم يكن من الممكن استخدام سياق React بين الصفحات على جانب الخادم. كان السبب في ذلك هو أن webpack يحتفظ بذاكرة تخزين مؤقت داخلية للوحدة بدلاً من استخدام require.cache، لقد كتبنا إضافة webpack مخصصة تغير هذا السلوك لمشاركة مثيلات الوحدة بين الصفحات.
بذلك لا نسمح فقط باستخدام سياق React الجديد، ولكننا أيضًا نقلل من بصمة ذاكرة Next.js عند مشاركة الكود بين الصفحات.
6.0 | 7.0 | الفرق | |
---|---|---|---|
استخدام الذاكرة | 57.5 ميجابايت | 48.1 ميجابايت | -16% ذاكرة |
nextjs.org
بالتزامن مع إصدار Next.js 7، نطلق nextjs.org جديدًا بالكامل.
المدونة
مقالة المدونة التي تقرأها الآن هي بالفعل جزء من قسم المدونة الجديد على nextjs.org. ستكون هذه المدونة المنزل الجديد للتواصل المتعلق بـ Next.js، على سبيل المثال، إعلانات الإصدارات الجديدة.
الموقع الجديد nextjs.org
احصل على الإلهام
مع تزايد عدد التطبيقات التي تستخدم Next.js باستمرار، احتجنا إلى طريقة لعرض كل هذه التطبيقات الجميلة في نظرة واحدة. تعرّف على صفحة /showcase
الجديدة:
احصل على الإلهام من nextjs.org/showcase
تتيح لنا هذه النافذة الجديدة إضافة تطبيقات جديدة مبنية باستخدام Next.js بشكل مستمر.
ندعوك لزيارة /showcase
للحصول على الإلهام، أو لتقديم تطبيقك الذي يستخدم Next.js!
المجتمع
منذ إطلاقه الأول، تم استخدام Next.js في كل شيء بدءًا من شركات فورتشن 500 وصولاً إلى المدونات الشخصية. نحن متحمسون جدًا لرؤية نمو اعتماد Next.js.
- حاليًا، هناك أكثر من 12,500 نطاق عام مفهرس يستخدم Next.js.
- ساهم لدينا أكثر من 500 مساهم بإرسال ما لا يقل عن commit واحد.
- على GitHub، حصل المشروع على أكثر من 29,000 نجمة.
- تم تقديم ما يقارب 2200 طلب دمج (pull request) منذ الإطلاق الأول.
يضم مجتمع Next.js ما يقارب 2000 عضو. انضم إلينا!