يسعدنا أن نقدم Next.js 5.0 للعالم. وهو متاح الآن على npm. للترقية، قم بتنفيذ:
npm i next@latest react@latest react-dom@latest
بالإضافة إلى تحديث Next.js، نقوم بترقية التبعيات المطلوبة
react
وreact-dom
Next.js هو مجموعة أدوات لتطبيقات React.js الشاملة المعروضة من جانب الخادم (أو المقدمة مسبقًا بشكل ثابت). بدء تطوير تطبيق بأي حجم أصبح سهلاً مثل تنفيذ next
. (اقرأ المزيد.)
مع كل إصدار جديد، نلتزم بالحفاظ على التوافق مع الإصدارات السابقة، وتقديم مسارات ترقية بسيطة وإجراء تغييرات على واجهة برمجة التطبيقات فقط عند الضرورة القصوى. Next.js 5.0 ليس استثناءً.
تحت الغطاء، خضع Next.js لتحول جذري لتمكين حالات استخدام جديدة قوية وقابلية التوسعة. بدأنا بجعل Next.js يشارك خط أنابيب Webpack الشامل لكل من كود الخادم والعميل.
Webpack الشامل وإضافات Next
يستفيد Next.js من الأدوات القوية الموجودة مثل Webpack و Babel و Uglify، ويقدمها للمستخدم النهائي بواجهة بسيطة ملحوظة: next
(للتطوير)، next build
(للتحضير للإنتاج) و next start
(للخدمة) أو next export
للتقديم المسبق إلى ملفات ثابتة.
أحد القرارات المبكرة التي اتخذناها كان توفير نقاط توسعة قوية جدًا لكيفية تكوين هذه الأدوات. لم نكن نريد فقط سهولة الاستخدام، بل أردنا تمكين المرونة لتوسيع مجموعة الأدوات كما تريد.
على سبيل المثال، يمكنك توسيع تكوين webpack لـ Next.js عن طريق إعداد خاصية webpack
في ملف next.config.js
.
لأن webpack يعمل بشكل مختلف للإنتاج والتطوير، قررنا في ذلك الوقت جعله دالة تزين تكوين webpack الافتراضي لدينا:
module.exports = {
webpack(config, { dev }) {
// تعديله!
return config;
},
};
مثال على ملف
next.config.js
الاختياري
ومع ذلك، فإن Webpack سيعمل فقط على حزم العميل (المتصفح)، وسوف تفوتك إمكانية استخدام هذه السلسلة الرائعة من الأدوات لعرض الخادم.
يسعدنا أن نعلن أننا قمنا بإعادة هيكلة شاملة لقاعدة الكود لدينا لجعل Webpack يعمل بشكل شامل.
من وجهة نظرك، كل ما يتغير هو أن خاصية إضافية isServer
يتم تمريرها إلى دالة التزيين أعلاه. ومع ذلك، فإن الدلالات الجديدة تعني أن النظام البيئي الواسع لـ Webpack loaders أصبح متاحًا لك لاستخدامه.
CSS، LESS، SASS، SCSS ووحدات CSS
إحدى الميزات الأكثر طلبًا هي القدرة على استيراد ملفات CSS والاستفادة من Webpack loaders:
import './index.css';
export default function Index() {
return (
<div>
<p>I love CSS!</p>
</div>
);
}
مثال على صفحة (
pages/index.js
) تستخدم استيراد CSS بفضل Webpack الشامل
لجعل هذا يعمل، يمكنك إحضار loaders التي تحتاجها كتبعيات مطلوبة:
npm i --save css-loader style-loader postcss-loader
Next.js يمنحك الحرية في اختيار loaders التي تحتاجها وترقيتها إلى إصدارات مختلفة حسب الرغبة.
ثم قم بتوسيع التكوين لتكوين loaders الخاصة بك. في next.config.js
:
module.exports = {
webpack(config, options) {
const { dev, isServer } = options;
const extractCSSPlugin = new ExtractTextPlugin({
filename: 'static/style.css',
disable: dev,
});
config.module.rules.push({
test: /\\.css$/,
use: cssLoaderConfig(extractCSSPlugin, {
cssModules,
dev,
isServer,
}),
});
return config;
},
};
توسيع تكوين webpack الخام يمنحك مرونة وتحكمًا كبيرًا
بينما نوصي عمومًا باستخدام حلول التصميم المحلية للمكونات، مثل الإضافة المضمنة styled-jsx
babel plugin، نعتقد أن Webpack loaders لديها العديد من المزايا المهمة، مثل تسهيل إعادة استخدام قواعد كود CSS الموجودة وتبسيط نقل قواعد الكود القديمة إلى Next.js بشكل كبير.
بدلاً من تمكين كل ميزة و loader يمكن تصوره افتراضيًا، نقدم إضافات Next.js، وهي وظائف بسيطة تزين تكوينك. بدلاً من توسيع التكوين يدويًا لإعداد loaders كما فعلنا أعلاه، يمكنك فقط القيام بما يلي:
const withCss = require('next-css');
module.exports = withCss({
/* تكوين إضافي اختياري */
});
كل ما يتطلبه الأمر لتمكين استيراد ملفات
.css
هو إحضارnext-css
اقرأ المزيد حول استخدام CSS Loaders مع Next.JS، أو راجع بعض الحزم التي أنشأناها لك بالفعل:
هدفنا هو تمكين المجتمع من تطوير ونمو نظام بيئي من الامتدادات العملية البسيطة. لهذا الغرض، نفتح مستودع next-plugins لمجتمع Next.js للحفاظ عليه. جميع طلبات السحب مرحب بها!
دعم TypeScript
إحدى أسرع التقنيات نموًا في نظام JavaScript البيئي هي TypeScript. لدرجة أنها أصبحت مدعومة رسميًا من قبل Babel 7، مما يعني أنها ستكون مدعومة بشكل طبيعي بواسطة Next.js فقط عن طريق تخصيص ملف .babelrc الخاص بك.
في الوقت الحالي، بفضل دعم Webpack الشامل الجديد لدينا، يمكنك الحصول على دعم TypeScript كامل اليوم!
يمكنك توسيع تكوين webpack الخاص بك مثل هذا:
module.exports = {
webpack(config, options) {
const { dir, defaultLoaders } = options;
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\\.+(ts|tsx)$/,
include: [dir],
exclude: /node_modules/,
use: [
defaultLoaders.babel,
{ loader: 'ts-loader', options: { transpileOnly: true } },
],
});
return config;
},
};
كل ما علينا فعله هو تمكين
ts-loader
مثل CSS loaders والمعالجات المسبقة، كانت TypeScript واحدة من أكثر الميزات المطلوبة. لجعل دمجها في المشاريع بنفس سهولة أي loader آخر، لدينا الآن إضافة next-typescript
يمكنك تضمينها في ملف next.config.js
الخاص بك:
const withTs = require('next-typescript');
module.exports = withTs({
/* تكوين إضافي */
});
يمكن تكوين الإضافات بسهولة: إنها مجرد دوال
دعم أفضل لمكتبات React البديلة وتحميل الوحدات
ظهرت العديد من تطبيقات الاستبدال المباشر لـ React بمرور الوقت. من بينها، بعض الملحوظات هي [preact
](https://preactjs.com/)، nervjs
و inferno
.
تركز مكتبات أخرى على استبدال عارض DOM، مثل react-dom-lite
، والتي تهدف إلى جعل بناء React أصغر عن طريق تقديم بعض التنازلات الطفيفة في توافق المتصفح.
يجعل دعم Webpack الشامل عملية دمج هذه المكتبات كبدائل مباشرة أسهل. على غرار الإضافات الأخرى، هذا كل ما عليك فعله لاستخدام Next.js مع preact:
npm i @zeit/next-preact preact preact-compat
نقوم بتثبيت إضافة preact والتبعيات المطلوبة الضرورية
const withPreact = require('@zeit/next-preact');
module.exports = withPreact();
ملف
next.config.js
الجديد لدينا جاهز لـ preact
تحقق من الوحدة البسيطة جدًا @zeit/next-preact أو أنشئ الخاصة بك!
خرائط المصادر الخارجية الاختيارية في الإنتاج (Optional External Sourcemaps in Production)
الآن بعد أن أصبح Next.js يستخدم webpack لكل من كود العميل والخادم، تمكين خرائط المصادر (source maps) في بناء الإنتاج يحتاج فقط إلى تعديل بسيط في الإعدادات.
في وضع التطوير (development)، تكون خرائط المصادر مفعلة تلقائيًا، لذلك نقوم بتكوينها بشكل مختلف للإنتاج:
module.exports = {
webpack(config, { dev }) {
if (!dev) {
config.devtool = 'source-map';
}
return config;
},
};
نقوم ببساطة بتكوين خيار
devtool
بشكل مختلف عندما لا نكون في وضع التطوير
المناطق (Zones)
كان أحد الأهداف المعلنة لـ Next.js منذ البداية هو إعادة وبساطة الويب والحفاظ عليها.
عرض الخادم (Server-rendering)، ونهج بسيط وغير متحيز لجلب البيانات والصفحات التصريحية (declarative pages) بناءً على هيكل نظام الملفات هي بعض الميزات التي قدمناها تماشيًا مع هذا التفكير.
جانب غالبًا ما يتم تجاهله في خدمات الويب ومواقع الويب هو مدى قابليتها للتكوين والتوسع بشكل طبيعي.
على سبيل المثال، mydomain.com/settings
و mydomain.com/
يمكن أن يكونا تطبيقين مختلفين تمامًا، يتم نشرهما بشكل مستقل، وتوسيعهما بشكل مستقل، وحتى تشغيل إصدارات مختلفة من نفس البرنامج.
كل ما يتطلبه الأمر "لربطهما معًا" في تجربة موحدة للمستخدم النهائي هو بعض الإعدادات البسيطة لطبقة التوجيه الخلفية أو موازنات الحمل التي تعرضهما للعالم. يسعدنا الآن تقديم القدرة على تكوين تطبيقات متعددة مبنية باستخدام Next.js، متصلة معًا باستخدام مكونات <Link>
العادية. نسمي هذه الميزة المناطق (Zones).
كمثال، ضع في اعتبارك هذين التطبيقين المستقلين لـ Next.js المنشورين على Vercel:
- https://front.vercel.app
- https://zeit-docs-zbqbsrucga.vercel.app/docs https://zeit-docs-zbqbsrucga.vercel.app/api
كلا الصفحتين لدينا تجربة سلسة، لكنهما تنتميان إلى تطبيقات منفصلة
عندما قمنا بإعادة تصميم وثائقنا، أردنا جعل قبول المساهمات المجتمعية أمرًا سهلاً قدر الإمكان.
قررنا فصل "موقع الويب المصغر" للوثائق إلى مستودعه الخاص. بالإضافة إلى ذلك، كلما تم تقديم طلب سحب (pull-request) واقتراح تغيير، نقوم بنشره تلقائيًا، بشكل معزول:
في كل مرة يحدث تغيير داخل طلب السحب، يقوم بوتنا بنشره تلقائيًا
ما انتهينا إليه هو منطقتين، تم دمجهما معًا في النطاق الرئيسي https://vercel.com
باستخدام ميزة اسم المسار (path alias feature). يبدو الأمر كالتالي:
{
"rules": [
{ "pathname": "/docs", "dest": "our-docs.vercel.app" },
{ "pathname": "/api", "dest": "our-docs.vercel.app" },
{ "dest": "my-main-website.vercel.app" }
]
}
هذه القواعد البسيطة تسمح لك بتكوين الخدمات المصغرة (microservices) والمناطق معًا
كل ما تبقى هو استدعاء أمر now alias
:
now alias -r rules.json my-domain.com
مهمتنا هي جعل النشر عالميًا ومفتوحًا قدر الإمكان. للمساعدة في التطوير المحلي، قمنا مؤخرًا بفتح مصدر micro-proxy
، وهو أداة تعمل بنفس تنسيق الإعدادات الموضح أعلاه.
يمكنك بالمثل ربط المناطق مع حلول أخرى مثل Nginx أو HAProxy أو API Gateway.
أوقات بناء إنتاج أسرع (Faster Production Build Times)
نعتقد أن تجربة المطور وتجربة المستخدم يسيران جنبًا إلى جنب. كلما زادت كفاءة كتابة التغييرات واختبارها ونشرها، زادت سرعة إضافة الميزات الجديدة، وإصلاح الأخطاء، وتحسين تجربة المستخدم بشكل عام.
وبالتالي، نركز باستمرار على التكرار المستمر لملف أداء اللبنات الأساسية للنظام.
مع Next.js 5.0، كانت لدينا فرصة لإلقاء نظرة مرة أخرى على next build
، الأمر الذي تقوم بتشغيله قبل النشر إلى الإنتاج أو تصدير تطبيق Next.js الخاص بك كموقع ثابت (static site).
يسعدنا الإبلاغ عن أنه بالنسبة لـ vercel.com، وهو تطبيق React يتكون من آلاف المكونات، لاحظنا تحسينات كبيرة مع Next.js 5.0، تصل إلى 23.6% أسرع في أوقات بناء الإنتاج:
بناء التطبيق الرئيسي لدينا للإنتاج يستغرق الآن 38 ثانية أقل لإكماله
تحسين التخزين المؤقت للواردات الديناميكية (Improved Caching for Dynamic Imports)
عندما تستخدم import()
الديناميكية، فإن هذا يشير إلى WebPack أن نقطة دخول جديدة لتقسيم الكود (code-splitting) موجودة.
في وقت البناء، يعني هذا إنشاء حزمة (bundle) محددة للشجرة الفرعية المقابلة للوحدات (modules).
قبل Next.js 5.0، كانت الحزم الديناميكية تتلقى عنوان URL يشبه ما يلي:
/_next/1517592683901/webpack/chunks/components_hello1_1345d10fc951cd6717c5676c467579a6.js
الآن، قمنا بتحويل الواردات الديناميكية إلى تجزئات قابلة للعنونة حسب المحتوى (content-addressable hashes) لمحتويات الشجرة الفرعية:
/_next/webpack/chunks/components_hello1_1345d10fc951cd6717c5676c467579a6-b7874680a9e21fb6eb89.js
هذا يعني أنه عبر عمليات النشر المختلفة، لن يضطر المستخدمون والعملاء إلى إعادة تنزيل الكود الذي استخدموه بالفعل دون داع.
القطع (Fragments)
يقوم Next.js ببناء مكون <Document>
عالي المستوى يتم عرضه من جانب الخادم (server-rendered) مع كل صفحة. تجاوز هذا المكون يمنحك سيطرة كاملة على ترميزك (markup)، مما يتيح العديد من حالات الاستخدام المتقدمة.
جزء من ذلك الترميز الأولي هو قائمة البرامج النصية (scripts) التي يحتاجها Next.js لتقييمها على جانب العميل (client side). يبدو _document
المخصص كما يلي:
import Document, { Head, Main, NextScript } from 'next/document';
export default class extends Document {
render() {
return (
<html>
<Head />
<body>
<Main />
<NextScript />
</body>
</html>
);
}
}
Document
يسمح لك بتخصيص ناتج العرض من جانب الخادم بالكامل للصفحة
حتى وقت قريب، كنا مضطرين لتفريغ برامجنا النصية داخل <div>
.
مع Next.js 5.0، نستفيد الآن من دعم Fragment
الجديد، مما يترجم إلى صفحات أخف وزنًا وسيطرة كاملة على تنسيق الصفحة، بدون ترميز إضافي.
أخطاء أكثر دقة (More Accurate Errors)
Node.js لا يدعم خرائط المصادر (source maps)، الأخطاء التي تحدث على جانب الخادم تكون مصحوبة بتتبع المكدس (stack trace) يشير إلى الكود المترجم.
مع Next 5 قمنا بتحسين دعم خرائط المصادر على جانب الخادم. الأخطاء التي تحدث عند عرض الخادم تشير الآن إلى الوظيفة ورقم السطر الصحيح.
الأخطاء تظهر الآن السطر والملف واسم الوظيفة بشكل صحيح
الختام (Conclusion)
Universal Webpack يعزز أسس Next.js ويجعلها أكثر استعدادًا للمستقبل. بشكل عام، لم يعد هناك فصل اصطناعي بين أي إضافات (plugins) أو محمِّلات (loaders) قابلة للتطبيق على Next.js وأيها غير ذلك.
بروح الإعدادات الصفرية (zero configuration)، يسعدنا تقديم Next Plugins، المستودع المجتمعي للوصفات التي توسع وظائف Next.js تلقائيًا، دون الحاجة إلى تعديل إعدادات محددة.
مع هذا، ندعم الآن الطيف الكامل لحلول CSS، ولغات التحويل إلى js مثل TypeScript وبدائل React مثل Nerve، فقط عن طريق إضافة وحدة إضافية والتصريح عن تضمينها في next.config.js
. البساطة دون غموض.
تسمح المناطق (Zones) بربط تطبيقات Next.js التي لا تنتمي إلى نفس المستودع أو حتى الخوادم. نعتبر هذا معلمًا مهمًا جدًا في فئة تحسينات "قابلية التوسع للفريق".
وبالتالي يصبح Next.js مرشحًا رائعًا للتطبيقات الكبيرة التي تحافظ عليها فرق متعددة. يمكنهم الآن نشر التحسينات بشكل متزامن، وتقليل أسطح الخطأ، وزيادة سرعة التكرار، وحتى تجربة تقنيات مختلفة بالإضافة إلى نواتنا، مثل العديد من الأساليب المختلفة لإدارة الحالة (state management) أو جلب البيانات (data fetching).
نريد أن ننتهز هذه الفرصة لتقديم الشكر لـ Deep Varma وفريق هندسة Trulia على تقديم رؤى رئيسية ورمز واختبار أدى إلى تصميم هذه الميزة.
كالعادة، هذا الإصدار لم يكن ليصبح ممكنًا بدون العديد من المساهمين في المصادر المفتوحة ومجتمعنا الرائع.