مترجم Next.js

مترجم Next.js، المكتوب بلغة Rust باستخدام SWC، يسمح لـ Next.js بتحويل وتصغير كود JavaScript الخاص بك للإنتاج. هذا يحل محل Babel للملفات الفردية و Terser لتصغير حزم الإخراج.

التجميع باستخدام مترجم Next.js أسرع بـ 17 مرة من Babel وتم تمكينه افتراضيًا منذ إصدار Next.js 12. إذا كان لديك تكوين Babel موجود أو تستخدم ميزات غير مدعومة، فسوف يختار تطبيقك عدم استخدام مترجم Next.js وسيستمر في استخدام Babel.

لماذا SWC؟

SWC هو منصة قابلة للتوسيع مبنية على Rust لأدوات المطورين السريعة من الجيل التالي.

يمكن استخدام SWC للتجميع، التصغير، التجميع، والمزيد - وهو مصمم ليكون قابلاً للتوسيع. إنه شيء يمكنك استدعاؤه لتنفيذ تحويلات الكود (سواء كانت مدمجة أو مخصصة). يتم تنفيذ هذه التحويلات من خلال أدوات عالية المستوى مثل Next.js.

اخترنا البناء على SWC لعدة أسباب:

  • القابلية للتوسيع: يمكن استخدام SWC كـ Crate داخل Next.js، دون الحاجة إلى تفرع المكتبة أو حلول بديلة للقيود التصميمية.
  • الأداء: تمكنا من تحقيق تحديث سريع أسرع بـ ~3 مرات وبناء أسرع بـ ~5 مرات في Next.js عن طريق التحول إلى SWC، مع وجود مجال لمزيد من التحسينات قيد التقدم.
  • WebAssembly: دعم Rust لـ WASM ضروري لدعم جميع المنصات الممكنة وجعل تطوير Next.js متاحًا في كل مكان.
  • المجتمع: مجتمع Rust والنظام البيئي رائعون ولا يزالان في نمو.

الميزات المدعومة

Styled Components

نعمل على نقل babel-plugin-styled-components إلى مترجم Next.js.

أولاً، قم بالتحديث إلى أحدث إصدار من Next.js: npm install next@latest. ثم، قم بتحديث ملف next.config.js الخاص بك:

next.config.js
module.exports = {
  compiler: {
    styledComponents: true,
  },
}

للحالات المتقدمة، يمكنك تكوين خصائص فردية لتجميع styled-components.

ملاحظة: تحويلات ssr و displayName هي المتطلب الرئيسي لاستخدام styled-components في Next.js.

next.config.js
module.exports = {
  compiler: {
    // انظر https://styled-components.com/docs/tooling#babel-plugin لمزيد من المعلومات حول الخيارات.
    styledComponents: {
      // مفعل افتراضيًا في وضع التطوير، معطل في الإنتاج لتقليل حجم الملف،
      // تعيين هذا سيتجاوز الافتراضي لجميع البيئات.
      displayName?: boolean,
      // مفعل افتراضيًا.
      ssr?: boolean,
      // مفعل افتراضيًا.
      fileName?: boolean,
      // فارغ افتراضيًا.
      topLevelImportPaths?: string[],
      // الافتراضي هو ["index"].
      meaninglessFileNames?: string[],
      // مفعل افتراضيًا.
      minify?: boolean,
      // مفعل افتراضيًا.
      transpileTemplateLiterals?: boolean,
      // فارغ افتراضيًا.
      namespace?: string,
      // معطل افتراضيًا.
      pure?: boolean,
      // مفعل افتراضيًا.
      cssProp?: boolean,
    },
  },
}

Jest

يقوم مترجم Next.js بتحويل اختباراتك وتبسيط تكوين Jest مع Next.js بما في ذلك:

  • المحاكاة التلقائية لـ .css، .module.css (والمتغيرات .scss الخاصة بهم)، واستيراد الصور
  • إعداد transform تلقائيًا باستخدام SWC
  • تحميل .env (وجميع المتغيرات) إلى process.env
  • تجاهل node_modules من تحويل الاختبارات والتحويلات
  • تجاهل .next من تحويل الاختبارات
  • تحميل next.config.js للعلامات التي تمكن تحويلات SWC التجريبية

أولاً، قم بالتحديث إلى أحدث إصدار من Next.js: npm install next@latest. ثم، قم بتحديث ملف jest.config.js الخاص بك:

jest.config.js
const nextJest = require('next/jest')

// توفير المسار إلى تطبيق Next.js الخاص بك مما سيمكن تحميل next.config.js وملفات .env
const createJestConfig = nextJest({ dir: './' })

// أي تكوين مخصص تريد تمريره إلى Jest
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}

// يتم تصدير createJestConfig بهذه الطريقة لضمان أن next/jest يمكنه تحميل تكوين Next.js، وهو غير متزامن
module.exports = createJestConfig(customJestConfig)

Relay

لتمكين دعم Relay:

next.config.js
module.exports = {
  compiler: {
    relay: {
      // يجب أن يتطابق هذا مع relay.config.js
      src: './',
      artifactDirectory: './__generated__',
      language: 'typescript',
      eagerEsModules: false,
    },
  },
}

جيد للمعرفة: في Next.js، جميع ملفات JavaScript في دليل pages تعتبر مسارات. لذلك، بالنسبة لـ relay-compiler ستحتاج إلى تحديد إعدادات تكوين artifactDirectory خارج pages، وإلا فإن relay-compiler سينشئ ملفات بجانب ملف المصدر في دليل __generated__، وسيعتبر هذا الملف مسارًا، مما سيكسر عمليات البناء للإنتاج.

إزالة خصائص React

يسمح بإزالة خصائص JSX. هذا يستخدم غالبًا للاختبار. مشابه لـ babel-plugin-react-remove-properties.

لإزالة الخصائص التي تطابق التعبير العادي الافتراضي ^data-test:

next.config.js
module.exports = {
  compiler: {
    reactRemoveProperties: true,
  },
}

لإزالة الخصائص المخصصة:

next.config.js
module.exports = {
  compiler: {
    // التعبيرات العادية المعرفة هنا تتم معالجتها في Rust لذا فإن الصيغة مختلفة عن
    // JavaScript `RegExp`s. انظر https://docs.rs/regex.
    reactRemoveProperties: { properties: ['^data-custom$'] },
  },
}

إزالة Console

هذا التحويل يسمح بإزالة جميع استدعاءات console.* في كود التطبيق (وليس node_modules). مشابه لـ babel-plugin-transform-remove-console.

إزالة جميع استدعاءات console.*:

next.config.js
module.exports = {
  compiler: {
    removeConsole: true,
  },
}

إزالة إخراج console.* باستثناء console.error:

next.config.js
module.exports = {
  compiler: {
    removeConsole: {
      exclude: ['error'],
    },
  },
}

Legacy Decorators

سيكتشف Next.js تلقائيًا experimentalDecorators في jsconfig.json أو tsconfig.json. تستخدم الـ decorators القديمة بشكل شائع مع إصدارات أقدم من المكتبات مثل mobx.

هذه العلامة مدعومة فقط للتوافق مع التطبيقات الموجودة. لا نوصي باستخدام الـ decorators القديمة في التطبيقات الجديدة.

أولاً، قم بالتحديث إلى أحدث إصدار من Next.js: npm install next@latest. ثم، قم بتحديث ملف jsconfig.json أو tsconfig.json الخاص بك:

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

importSource

سيكتشف Next.js تلقائيًا jsxImportSource في jsconfig.json أو tsconfig.json وسيطبق ذلك. هذا يستخدم بشكل شائع مع مكتبات مثل Theme UI.

أولاً، قم بالتحديث إلى أحدث إصدار من Next.js: npm install next@latest. ثم، قم بتحديث ملف jsconfig.json أو tsconfig.json الخاص بك:

{
  "compilerOptions": {
    "jsxImportSource": "theme-ui"
  }
}

Emotion

نعمل على نقل @emotion/babel-plugin إلى مترجم Next.js.

أولاً، قم بالتحديث إلى أحدث إصدار من Next.js: npm install next@latest. ثم، قم بتحديث ملف next.config.js الخاص بك:

next.config.js

module.exports = {
  compiler: {
    emotion: boolean | {
      // الافتراضي هو true. سيتم تعطيله عندما يكون نوع البناء هو production.
      sourceMap?: boolean,
      // الافتراضي هو 'dev-only'.
      autoLabel?: 'never' | 'dev-only' | 'always',
      // الافتراضي هو '[local]'.
      // القيم المسموح بها: `[local]` `[filename]` و `[dirname]`
      // هذا الخيار يعمل فقط عندما يتم تعيين autoLabel إلى 'dev-only' أو 'always'.
      // يسمح لك بتحديد تنسيق التسمية الناتجة.
      // يتم تعريف التنسيق عبر سلسلة حيث يتم إحاطة الأجزاء المتغيرة بأقواس مربعة [].
      // على سبيل المثال labelFormat: "my-classname--[local]"، حيث سيتم استبدال [local] باسم المتغير الذي يتم تعيين النتيجة له.
      labelFormat?: string,
      // الافتراضي هو undefined.
      // هذا الخيار يسمح لك بإخبار المترجم بالواردات التي يجب
      // أن ينظر إليها لتحديد ما يجب تحويله حتى إذا كنت تعيد تصدير
      // صادرات Emotion، فلا يزال بإمكانك استخدام التحويلات.
      importMap?: {
        [packageName: string]: {
          [exportName: string]: {
            canonicalImport?: [string, string],
            styledBaseImport?: [string, string],
          }
        }
      },
    },
  },
}

التصغير

يتم استخدام مترجم swc الخاص بـ Next.js للتصغير افتراضيًا منذ الإصدار v13. هذا أسرع بـ 7 مرات من Terser.

جيد للمعرفة: بدءًا من v15، لا يمكن تخصيص التصغير باستخدام next.config.js. تم إزالة دعم علامة swcMinify.

تحويل الوحدات

يمكن لـ Next.js تحويل وتجميع التبعيات تلقائيًا من الحزم المحلية (مثل monorepos) أو من التبعيات الخارجية (node_modules). هذا يحل محل حزمة next-transpile-modules.

next.config.js
module.exports = {
  transpilePackages: ['@acme/ui', 'lodash-es'],
}

Modularize Imports

تم استبدال هذا الخيار بـ optimizePackageImports في Next.js 13.5. نوصي بالترقية لاستخدام الخيار الجديد الذي لا يتطلب تكوينًا يدويًا لمسارات الاستيراد.

Define (استبدال المتغيرات أثناء البناء)

خيار define يسمح لك باستبدال المتغيرات في كودك بشكل ثابت أثناء البناء. يأخذ الخيار كائنًا كأزواج مفتاح-قيمة، حيث تكون المفاتيح هي المتغيرات التي يجب استبدالها بالقيم المقابلة.

استخدم حقل compiler.define في next.config.js لتعريف المتغيرات لجميع البيئات (الخادم، الحافة، والعميل). أو، استخدم compiler.defineServer لتعريف المتغيرات فقط لكود جانب الخادم (الخادم والحافة):

next.config.js
module.exports = {
  compiler: {
    define: {
      MY_VARIABLE: 'my-string',
      'process.env.MY_ENV_VAR': 'my-env-var',
    },
    defineServer: {
      MY_SERVER_VARIABLE: 'my-server-var',
    },
  },
}

خطافات دورة حياة البناء

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

runAfterProductionCompile

وظيفة خطاف تنفذ بعد انتهاء تجميع بناء الإنتاج، ولكن قبل تشغيل مهام ما بعد التجميع مثل التحقق من النوع وإنشاء الصفحات الثابتة. يوفر هذا الخطاف وصولاً إلى بيانات وصفية للمشروع بما في ذلك دليل المشروع ودليل إخراج البناء، مما يجعله مفيدًا للأدوات الخارجية لجمع مخرجات البناء مثل خرائط المصدر.

next.config.js
module.exports = {
  compiler: {
    runAfterProductionCompile: async ({ distDir, projectDir }) => {
      // الكود المخصص الخاص بك هنا
    },
  },
}

يتلقى الخطاف كائنًا بالخصائص التالية:

  • distDir: دليل إخراج البناء (الافتراضي هو .next)
  • projectDir: الدليل الجذري للمشروع

الميزات التجريبية

تتبع أداء SWC

يمكنك إنشاء تحويلات SWC الداخلية كتنسيق trace event لـ chromium.

next.config.js
module.exports = {
  experimental: {
    swcTraceProfiling: true,
  },
}

بمجرد التمكين، سينشئ SWC تتبعًا باسم swc-trace-profile-${timestamp}.json تحت .next/. يمكن لمشاهد تتبع chromium (chrome://tracing/, https://ui.perfetto.dev/)، أو مشاهد flamegraph متوافق (https://www.speedscope.app/) تحميل وتصور التتبعات المُنشأة.

إضافات SWC (تجريبي)

يمكنك تكوين تحويل SWC لاستخدام دعم الإضافات التجريبي لـ SWC المكتوب بـ wasm لتخصيص سلوك التحويل.

next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      [
        'plugin',
        {
          ...pluginOptions,
        },
      ],
    ],
  },
}

يقبل swcPlugins مصفوفة من tuples لتكوين الإضافات. يحتوي tuple للإضافة على مسار الإضافة وكائن لتكوين الإضافة. يمكن أن يكون مسار الإضافة اسم حزمة npm أو مسارًا مطلقًا لملف .wasm نفسه.

الميزات غير المدعومة

عندما يحتوي تطبيقك على ملف .babelrc، سيعود Next.js تلقائيًا إلى استخدام Babel لتحويل الملفات الفردية. هذا يضمن التوافق مع الإصدارات السابقة للتطبيقات الحالية التي تستخدم إضافات Babel المخصصة.

إذا كنت تستخدم إعداد Babel مخصصًا، يرجى مشاركة تكوينك. نحن نعمل على نقل أكبر عدد ممكن من تحويلات Babel الشائعة، وكذلك دعم الإضافات في المستقبل.

سجل الإصدارات

الإصدارالتغييرات
v13.1.0تحويل الوحدات و Modularize Imports أصبحا مستقرين.
v13.0.0تمكين مصغر SWC افتراضيًا.
v12.3.0مصغر SWC مستقر.
v12.2.0تمت إضافة دعم تجريبي لـ إضافات SWC.
v12.1.0تمت إضافة دعم لـ Styled Components، Jest، Relay، إزالة خصائص React، Legacy Decorators، إزالة Console، و jsxImportSource.
v12.0.0تم إدخال مترجم Next.js.