---
title: 'فشل بناء Vite 8 بعد التحديث: الأسباب والحلول (2026)'
description: استبدل Vite 8 كلاً من Rollup و esbuild بـ Rolldown و Oxc. إليك سبب فشل عملية البناء (build) بعد التحديث، وما الذي تم حذفه بالفعل، وكيفية إصلاح كل خطأ.
url: https://nerdleveltech.com/ar/vite-8-build-fails-after-upgrade
language: ar
date: '2026-09-03'
category: frontend
tags:
  - vite 8
  - rolldown
  - oxc
  - lightning css
  - build tools
  - frontend
  - javascript
  - migration
markdown_url: https://nerdleveltech.com/ar/vite-8-build-fails-after-upgrade.md
attribution: 'Source: NerdLevelTech — https://nerdleveltech.com/ar/vite-8-build-fails-after-upgrade'
terms: https://nerdleveltech.com/llms.txt
---

# فشل بناء Vite 8 بعد التحديث: الأسباب والحلول (2026)

استبدل Vite 8 كل من Rollup و esbuild بـ Rolldown و Oxc، لذا فإن عمليات البناء (builds) التي كانت تعمل على Vite 7 قد تفشل بسبب تغييرات في السلوك بدلاً من أخطاء في الإعدادات. تشمل الأسباب الموثقة تصغير Lightning CSS، واستخدام top-level await غير المتوافق مع ESM، والتعامل الموحد مع CommonJS interop، والمزخرفات الأصلية (native decorators) غير المخفضة، وقائمة قصيرة من الخيارات التي تم إزالتها.

## ملخص

تم إطلاق النسخة المستقرة من Vite 8 في **12 مارس 2026** واستبدل كلا المجمعين (bundlers) في Vite — esbuild لتحويلات التطوير، و Rollup للإنتاج — بمجمع واحد مكتوب بلغة Rust وهو Rolldown، بالإضافة إلى مجموعة أدوات Oxc للتحويلات والتصغير.[^announce] يوفر Vite طبقة توافق: `build.rollupOptions` لا يزال يعمل كـ **اسم مستعار (alias)** مهجور، كما يتم **تحويل** خيارات `esbuild` و `optimizeDeps.esbuildOptions` تلقائياً إلى ما يعادلها في Oxc و Rolldown.[^build-options][^migration]

ما يتسبب في المشاكل بدلاً من ذلك هو التفاصيل الدقيقة: مجمّعان جديدان للتصغير بشكل افتراضي، قاعدة أكثر صرامة لـ top-level-`await`، قاعدة موحدة لاستيراد CommonJS `default`، المزخرفات الأصلية التي لا يقوم Oxc بتخفيضها، وقائمة قصيرة من الخيارات التي تمت إزالتها فعلياً. تتناول هذه الصفحة كل فشل موثق وصولاً إلى حله، وتم التحقق منها مقابل Vite **8.2.2**.[^npm][^migration]

## ما ستتعلمه

- لماذا يعد تبديل المجمع (bundler)، وليس إعداداتك، هو السبب الجذري لمعظم حالات فشل بناء Vite 8
- ما إذا كان `build.rollupOptions` قد تم تغيير اسمه، أو إزالته، أو لا شيء من ذلك — وماذا يحدث إذا قمت بتعيين كليهما
- ما هي الخيارات التي تمت إزالتها تماماً، مقابل تلك المهجورة، أو التي لا تؤدي وظيفة، أو غير المدعومة من الأدوات الجديدة
- كيف يقوم تصغير Lightning CSS بتغيير أو رفض ملفات CSS الخاصة بك بصمت، وأربع طرق لإلغاء ذلك
- ماذا يعني `The "TopLevelAwait" is not supported with the "iife" output format`، ولماذا يكون `worker.format` هو السبب عادةً
- لماذا قد يتوقف `resolve.alias` عن العمل في استدعاء `build()` برمجياً، والفخ الموجود في الحل البديل
- لماذا يعيد استيراد `default` من حزمة CommonJS كائناً (object) الآن
- لماذا تتوقف المزخرفات الأصلية عن التجميع بينما يستمر كود `experimentalDecorators` في العمل
- ماذا تقول الأدلة فعلياً عن Yarn PnP، في كلا الاتجاهين
- لماذا يستهدف المجمع الخاص بك متصفحات أحدث مما كان يفعل في Vite 7
- ما إذا كنت لا تزال بحاجة إلى تثبيت `esbuild`
- كيف تجد فعلياً الإضافة (plugin) الوحيدة التي تسبب فشل عملية البناء الخاصة بك
- لماذا يمكن لإصدار تصحيحي (patch release) من Vite 8 أن يكسر عملية بناء كانت تعمل بالأمس
- لماذا تنجح عملية البناء محلياً وتفشل في CI، وهي مشكلة مختلفة عن كل ما سبق
- مسار الهجرة التدريجية، وإجراء تراجع (rollback) حقيقي
- ما هي تكلفة زيادة السرعة، ومن الذي قام بقياسها

## لماذا تفشل عملية البناء بعد الترقية إلى Vite 8؟

لأن Vite 8 قام بتغيير المجمعات، وليس لأن إعداداتك خاطئة. كان Vite يستخدم esbuild لتحويلات وقت التطوير، والتحزيم المسبق للاعتمادات والتصغير، و Rollup لتجميع الإنتاج؛ أما Vite 8 فيستخدم Rolldown للتجميع وتحسين الاعتمادات، و Oxc لتحويلات JavaScript والتصغير.[^migration] أي شيء كان يعتمد على سلوك محدد لـ Rollup أو esbuild — سواء كانت قاعدة تنسيق المخرجات، أو خطاف إضافة (plugin hook)، أو افتراضاً في المصغر — يتم تشغيله الآن عبر كود مختلف.

تصف Vite هذا التغيير بأنه "أهم تغيير معماري منذ Vite 2".[^announce] وهذا توقع مفيد لوضعه: ففشل عملية البناء (build) بعد الترقية عادة ما يكون نتيجة اختلاف حقيقي في السلوك، وليس مجرد نقص في إعادة تسمية.

النتيجة العملية هي أن الحل نادراً ما يكون في البحث عن نص الخطأ. بل يكمن في واحدة من سبع فئات:

| الفئة                                   | العرض الشائع                                               | أين يتم تغطيتها أدناه                             |
| --------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------- |
| خيار محذوف                              | إعداد لم يعد سارياً، ولا يوجد بديل له                      | الخيارات التي تم حذفها                            |
| مقلل حجم (minifier) افتراضي جديد        | رفض ملفات CSS وقت البناء، أو مخرجات مكسورة بصرياً بدون خطأ | لماذا تتعطل ملفات CSS الخاصة بك                   |
| قيود تنسيق المخرجات                     | خطأ في البناء يشير إلى ملف داخل `node_modules`             | Top-level await                                   |
| تحويل غير مدعوم                         | Decorators، أو مخرجات ES5، كانت تُترجم سابقاً              | Decorators                                        |
| اختلافات في تحليل المسارات (Resolution) | "failed to resolve import" لمسار كان يعمل سابقاً           | Aliases، وتراجعات إصدارات التصحيح (patch-release) |
| تغيير في وقت التشغيل فقط                | بناء ناجح، ولكن سلوك خاطئ في المتصفح أو على الخادم         | CommonJS interop                                  |
| البيئة، وليس الكود                      | يعمل البناء محلياً، ويفشل فقط في CI                        | لماذا يفشل في CI                                  |

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

## هل أحتاج إلى إعادة تسمية `build.rollupOptions` إلى `build.rolldownOptions`؟

لا. لا يزال `build.rollupOptions` يعمل في Vite 8. يوثقه مرجع الإعدادات على أنه "اسم مستعار (alias) لـ `build.rolldownOptions`" ويصنفه كـ **Deprecated** (مهجور)، وليس محذوفاً.[^build-options] كما يتم توثيق `worker.rollupOptions` بنفس الطريقة.[^worker-options] وبشكل منفصل، يتم *تحويل* `optimizeDeps.esbuildOptions` وخيار `esbuild` الرئيسي: حيث ينشر الدليل جداول مطابقة وتطبقها Vite نيابة عنك، على الرغم من أن هناك مدخلين ليسا آليين — حيث يتم مطابقة `esbuild.banner` و `esbuild.footer` مع "إضافة مخصصة تستخدم transform hook"، بينما تم وضع علامة "(دعم جزئي)" على `esbuildOptions.plugins`.[^migration]

من الجدير بذكر ذلك بوضوح لأن الكثير من المقالات المكتوبة في 2026 حول Vite 8 تبدأ بعبارة "`rollupOptions` تم تغيير اسمه إلى `rolldownOptions`" كما لو كانت إعادة التسمية هي أول خطوة مطلوبة في عملية الترحيل. إنها عملية تنظيف موصى بها، وليست حلاً لمشكلة.

وهذه المقالات لم تخترع الكلمة من تلقاء نفسها. فدليل الترحيل الخاص بـ Vite يدرج الخيار تحت "إهمالات أخرى ذات صلة" كـ "`build.rollupOptions`: تم تغيير اسمه إلى `build.rolldownOptions`"، بينما يصفه مرجع الإعدادات لنفس الإصدار بأنه اسم مستعار مهجور فحسب.[^migration][^build-options] صفحتان في نفس مجموعة الوثائق، بصياغتين مختلفتين. مرجع الإعدادات هو الذي يصف سلوك وقت التشغيل.

**الشيء الوحيد الذي قد يسبب لك مشكلة حقيقية هو تعيين كليهما.** إذا كان ملف الإعدادات يحتوي على `build.rollupOptions` *و* `build.rolldownOptions`، فإن الوثائق لا تذكر شيئاً عن الأولوية — ولكن كود Vite يفعل ذلك، في تعليق فوق السطر الذي ينفذ العملية: "إذا كان كل من rollupOptions و rolldownOptions موجودين، يتم تجاهل rollupOptions واستخدام rolldownOptions".[^vite-src] لا يتم دمجهما، بل يتم التخلص من كائن `rollupOptions` بالكامل. وهذا أمر مهم لأن حل مشكلة الـ alias لاحقاً في هذه الصفحة يطلب منك إضافة كتلة `build.rolldownOptions` — فإذا كان لديك بالفعل إعدادات externals أو chunking أو output تحت `build.rollupOptions`، فإن إضافة تلك الكتلة ستؤدي بصمت إلى حذفها جميعاً. قم بنقل الكائن بالكامل، وليس جزءاً منه.

هناك تحذير ذو صلة يظهر فقط للإعدادات المقدمة من الإضافات (plugins)، وليس لإعداداتك الخاصة: "تم تحديد كل من `rollupOptions` و `rolldownOptions` بواسطة إضافة ... سيتم تجاهل `rollupOptions` المحددة بواسطة تلك الإضافة."[^vite-src]

هناك تفصيل دقيق بشأن تحذيرات الإلغاء (deprecation warnings)، لأنه عكس ما قد تتوقعه. تحذير الإلغاء في وقت التشغيل (runtime) الخاص بـ Vite لاسم `rollupOptions` محصور في الكود في `optimizeDeps` و `ssr.optimizeDeps` فقط — أما `build` و `worker` فليسا ضمن هذه المجموعة.[^vite-src] لذا فإن `optimizeDeps.rollupOptions` يعطي تحذيراً بينما `build.rollupOptions` لا يفعل. عندما يظهر تحذير ويكون الخيار قد تم تعيينه بواسطة تبعية (dependency) وليس بواسطتك، فإن رسالة Vite تحدد مخرج الطوارئ: "قم بتعيين VITE\_DEPRECATION\_TRACE=1 لرؤية أين يتم استدعاؤه"، وهو ما يحول السجل من `console.warn` إلى `console.trace` لتعرف موقع الاستدعاء.[^vite-src] متغير البيئة هذا غير موثق في vite.dev؛ ولكنه مرئي في الكود المصدري.

الخطوة الأساسية الأخرى هي فحص ما أنتجته طبقة التوافق. لاحظ أن هذا يجب أن يكون إضافة *مسجلة* — فمجرد كائن تم تعيينه لمتغير لا يفعل شيئاً:

```js
// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    {
      name: 'log-config',
      configResolved(config) {
        console.dir(config.optimizeDeps.rolldownOptions, { depth: null })
        console.dir(config.oxc, { depth: null })
      },
    },
  ],
})
```

كلا مساري الخصائص يأتيان من أمثلة `configResolved` الموجودة في دليل الهجرة نفسه.[^migration] تنبيهان قبل قراءة المخرجات: سيكون `config.optimizeDeps.rolldownOptions` عبارة عن `undefined` إذا لم تقم أبداً بتعيين `optimizeDeps.esbuildOptions` ولم تفعل أي إضافة ذلك أيضاً، وهذا أمر طبيعي وليس خطأً؛ كما أن استخدام `console.dir` مع `depth: null` هو أمر متعمد، لأن `console.log` على إعدادات محلولة (resolved config) يطبع `[Function]` بالضبط للمدخلات التي ترغب في رؤيتها بشدة.

## ما هي خيارات Vite 7 التي تم حذفها فعلياً في Vite 8؟

أقل مما توحي به نقاشات الهجرة، ويقوم الدليل بتصنيفها إلى فئات يستحق إبقاؤها متميزة، لأن الفئة الأولى فقط هي التي ستتركك بدون أي بديل على الإطلاق.[^migration]

**محذوفة فعلياً.**

- `build.rollupOptions.watch.chokidar` — استخدم `build.rolldownOptions.watch.watcher`.
- **صيغة الكائن (object form)** لـ `output.manualChunks`. صيغة الدالة (function form) ملغاة ولكنها لا تزال موجودة.
- تمرير URL إلى `import.meta.hot.accept` — قم بتمرير id بدلاً من ذلك.

**غير مدعوم بواسطة Rolldown**، والذي يدرجه الدليل بشكل منفصل تحت عنوان "Missing support by Rolldown": تنسيقات المخرجات `system` و `amd`، والخطافات (hooks) `shouldTransformCachedModule`، و `resolveImportMeta`، و `renderDynamicImport` و `resolveFileUrl`.[^migration]

**غير مدعوم بواسطة Oxc**، حيث يظل اسم الخيار موجوداً ولكن القدرة الوظيفية تختفي: `esbuild.supported`، وخيارات تشويه الخصائص (property-mangling) في esbuild (`mangleProps`، `reserveProps`، `mangleQuoted`، `mangleCache`).[^migration]

**أصبح الآن عملية فارغة (no-op)** — الخيار لا يزال يُحلل ولكن لا يفعل شيئاً: `build.commonjsOptions`، و `build.dynamicImportVarsOptions.warnOnError`.[^migration] هذه هي الفئة التي يجب التحقق منها أولاً، لأن العملية الفارغة لا يمكنها الإعلان عن نفسها. إذا كنت تعتمد على `commonjsOptions` لتشكيل معالجة CJS، فإن هذا السلوك قد اختفى.

هناك عنصر غالباً ما يتم تصنيفه كإزالة ولكنه في الحقيقة تحقق جديد من المدخلات: تمرير نفس المتصفح بإصدارات متعددة منه إلى `build.target` يؤدي الآن إلى حدوث خطأ، بينما كان esbuild "يختار أحدث إصدار منه، وهو ما لم يكن على الأرجح ما كنت تقصده".[^migration]

تغيير `manualChunks` هو الأمر الذي يستحق التحقق منه أولاً، لأن شكل الكائن (object form) هو النمط الذي علمته إرشادات "تقسيم حزمة الموردين (vendor bundle)" لسنوات:

```js
// Vite 7 — the object form is no longer supported in Vite 8
build: {
  rollupOptions: {
    output: {
      manualChunks: { vendor: ['react', 'react-dom'] },
    },
  },
}
```

البديل هو `codeSplitting` الخاص بـ Rolldown، في `build.rolldownOptions.output.codeSplitting`. هذا ليس مجرد تغيير اسم — فالشكل مختلف. الـ `test` الخاص بالمجموعة اختياري ويقبل سلسلة نصية، أو تعبيراً نمطياً (regular expression)، أو دالة شرطية (predicate function) على معرف الوحدة (module id)، بدلاً من قائمة بأسماء الحزم، لذا فإن الترجمة هي إعادة كتابة وليست مجرد نسخ:[^rolldown-cs]

```js
// Vite 8
build: {
  rolldownOptions: {
    output: {
      codeSplitting: {
        groups: [
          { name: 'vendor', test: /node_modules[\\/]react(-dom)?[\\/]/ },
        ],
      },
    },
  },
}
```

هناك سلوكان موثقان يجب توقعهما من هذا الخيار قبل نشره. إرشادات Rolldown تقول: "إذا كنت تستخدم تقسيم الكود اليدوي مع المجموعات، سيقوم rolldown بإنشاء قطعة `runtime.js` قسراً لضمان تنفيذ كود وقت التشغيل (runtime code) دائماً قبل أي قطع أخرى"، و "عندما يتم التقاط وحدة بواسطة مجموعة، سيحاول Rolldown التقاط تبعياتها بشكل متكرر (recursively) دون النظر إلى القيود".[^rolldown-cs] كلاهما يغير مخطط القطع (chunk graph) بطرق لن تتوقعها الترجمة السطحية، لذا قم بمقارنة قائمة القطع الناتجة بدلاً من الثقة في أن الإعدادات متكافئة.

## لماذا يتعطل الـ CSS الخاص بي أو يفشل تصغيره في Vite 8؟

لأن `build.cssMinify` أصبح الآن افتراضياً `'lightningcss'` بدلاً من esbuild — مع استثناء واحد وهو أنه يكون `false` عندما يتم تعطيل `build.minify` لبناء العميل (client build).[^build-options] Lightning CSS أكثر صرامة بشأن الصيغ التي لا يتعرف عليها وأكثر تحديداً بشأن ما يعيد كتابته، وينتج عن ذلك نمطان متميزان من الفشل.

**المشكلة الصاخبة هي خطأ في بناء (build error) الـ CSS الحديث.** هناك مشكلة تم تتبعها فُتحت في 17 مارس 2026 — "مقلل حجم CSS الافتراضي في Vite\@8 يمنع بعض ميزات CSS الحديثة والتدريجية" — تشير إلى فشل عملية البناء لأن قاعدة `@scope` يتم رفضها أثناء عملية التصغير (minification)، إلى جانب مشاكل في `::scroll-marker`، و `::scroll-marker-group`، و `::scroll-button()`، و `:target-current`، و `::search-text`.[^css21911] تم تصنيفها كخطأ في المصدر (upstream bug) وكانت لا تزال مفتوحة وقت الكتابة. الحل المؤقت الذي ذكره المُبلغ: "العودة إلى استخدام `esbuild` كمقلل لحجم CSS يحل المشكلة."[^css21911]

**أما المشكلة الصامتة فهي أسوأ.** تقرير من 9 يونيو 2026، على إصدار Vite 8.0.16 مع lightningcss 1.32.0 يصف حذف إعلان `backdrop-filter` غير المسبوق (unprefixed) من المخرجات، مما يترك فقط `-webkit-backdrop-filter` ويؤدي إلى تعطل تأثيرات الزجاج والتمويه (blur) — دون ظهور أي خطأ في أي مرحلة.[^css22649] تم إغلاقها كنسخة مكررة من مشكلة سابقة يوضح عنوانها المسبب الدقيق: "`backdrop-filter` قبل `-webkit-backdrop-filter` يتم حذفه عند استخدام `cssMinify: 'lightningcss'`".[^css21954] لذا فإن ترتيب الإعلانين هو الأمر المهم، وتلك المشكلة السابقة — التي فُتحت في 20 نوفمبر 2025 وصُنفت أيضاً كخطأ في المصدر — كانت لا تزال **مفتوحة** وقت الكتابة.[^css21954] هذه المشكلة لم يتم إصلاحها؛ بل يتم تتبعها.

لديك أربعة خيارات، من الأخف إلى الأثقل. الخيارات الثلاثة الأولى تستحق التجربة قبل الخيار الأخير، وهو الوحيد الذي يغير مسار عمل (pipeline) الـ CSS بالكامل:

1. **تجاوز إصدار Lightning CSS الانتقالي.** كلتا المشكلتين هما أخطاء في Lightning CSS وليس في Vite، لذا فإن إدخال `overrides` (npm)، أو `resolutions` (Yarn) أو `pnpm.overrides` لتثبيت إصدار يعمل بشكل صحيح هو الحل الأكثر دقة ومحدودية.
2. **ضبط `build.cssTarget`.** عندما يكون `cssMinify` هو `'lightningcss'`، فإن `build.cssTarget` له الأولوية على `css.lightningcss.targets` في خطوة التصغير، وهو المفتاح المسؤول عن سلوك خفض مستوى الصيغة (syntax-lowering) — بما في ذلك الحالة التي *زاد* فيها حجم حزمة CSS بعد التحديث.[^build-options]
3. **تعطيل تصغير CSS بالكامل** باستخدام `build.cssMinify: false` كخطوة تشخيصية، للتأكد من أن مقلل الحجم هو المسبب قبل إجراء أي تغيير دائم.
4. **العودة إلى استخدام esbuild كمقلل للحجم**، وهو ما يعيد مسار عمل CSS بالكامل وهو الخيار الذي استخدمه مُبلغو المشكلتين:

```js
// vite.config.js
export default defineConfig({
  build: { cssMinify: 'esbuild' },
})
```

```bash
npm add -D "esbuild@^0.27.0 || ^0.28.0"
```

ينص مرجع الإعدادات على متطلبات التبعية مباشرة: "يجب تثبيت esbuild عندما يتم ضبط الإعداد على `'esbuild'`."[^build-options] قم بتثبيته ضمن النطاق الذي يعلنه Vite كـ peer dependency بدلاً من تثبيت أحدث إصدار متاح، وإلا فإن إصدار esbuild رئيسي مستقبلي قد يتسبب في فشل التثبيت الصارم (strict install).[^npm]

يشير دليل الهجرة أيضاً إلى أن Lightning CSS "يدعم تحويلاً أفضل للصيغ (syntax lowering) وقد يزداد حجم حزمة CSS الخاصة بك قليلاً"، لذا من المتوقع أن يكون ملف CSS أكبر نوعاً ما بعد الترقية — ولكن إذا كانت الزيادة كبيرة، فإن `build.cssTarget` هو الحل، وليس الاستسلام.[^migration]

## ماذا يعني `The "TopLevelAwait" is not supported with the "iife" output format`؟

هذا يعني أن هناك شيئاً ما في حزمتك يستخدم `await` على المستوى الأعلى (top-level)، وتنسيق المخرجات لا يمكنه التعبير عن ذلك. هذا القيد ليس خاصاً بـ IIFE فقط: قاعدة Rolldown هي أنه "إذا كان الإدخال يحتوي على TLA، فلا يمكن تجميعه وإصداره إلا بتنسيق `esm`."[^rolldown-tla] كل تنسيق غير ESM يتأثر بذلك، لذا فإن التبديل من IIFE إلى UMD أو CJS سيفشل بنفس الطريقة.

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

**العمال (Workers).** القيمة الافتراضية لـ `worker.format` هي `'iife'`، والقيمة الأخرى المسموح بها هي `'es'`.[^worker-options] لذا، فإن تبعية تحتوي على \_\_PRESER preserve\_\_`await` على المستوى الأعلى، والتي تعمل بشكل جيد في حزمتك الرئيسية، يمكن أن تتسبب في تعطل حزمة الـ worker وحدها. وهذا يجعل هذا الأمر هو أسهل شيء يمكن تجربته:

```js
// vite.config.js
export default defineConfig({
  worker: { format: 'es' },
})
```

تحقق من دعم المتصفح قبل شحنها — دعم module-worker هو السبب في أن القيمة الافتراضية لا تزال `'iife'`.

**بناء المكتبات (Library builds).** تنسيقات `build.lib.formats` الافتراضية في Vite هي "`['es', 'umd']`، أو `['es', 'cjs']` في حال استخدام مداخل متعددة" — لذا فإن بناء المكتبة يصدر حزمة غير ESM سواء طلبت ذلك أم لا.[^build-options] توقع أن يذكر الخطأ أيًا من هذه التنسيقات بدلاً من `"iife"`؛ القيد هو نفسه، لأن Rolldown يصدر `await` على المستوى الأعلى فقط في `esm`.[^rolldown-tla]

**لا شيء مما سبق.** هناك تقرير تم تقديمه في 23 أبريل 2026 يمثل هذه الحالة بالضبط: عملية `vite build` عادية نجحت في Vite **8.0.5** ولكنها فشلت في **8.0.10**، مع إشارة الخطأ إلى `node_modules/@novnc/novnc/lib/util/browser.js` مع عدم وجود أي worker في عملية إعادة الإنتاج على الإطلاق.[^tla] هناك أمران يستحقان الاستفادة منهما هنا. الملف المذكور في الخطأ هو تبعية (dependency) وليس من الكود المصدري الخاص بك، لذا فإن البحث في الكود الخاص بك سيكون مضيعة للوقت. كما أن الفشل حدث بين إصدارات التصحيح (patch releases)، مما يعني أن جملة "لقد كان يعمل الأسبوع الماضي" ليست دليلاً على أن إعداداتك سليمة — راجع قسم إصدارات التصحيح أدناه.

إذا كان التنسيق ليس من صلاحيتك تغييره — مكتبة يجب أن تستمر في نشر `umd` أو `iife` لمستخدمي وسوم `<script>` — فإن الخيارات المتبقية هي إزالة `await` على المستوى الأعلى من مخطط التبعيات، أو البناء بتنسيق ESM ثم تحويله لإصدارات أقدم لاحقاً. تثبيت الإصدار (Pinning) هو الملاذ الأخير ويجب تحديده بدقة: آخر إصدار جيد في التقرير المذكور كان 8.0.5، وهو بعيد جداً عن 8.2.2.

## لماذا توقف `resolve.alias` عن العمل في استدعاء `build()` البرمجي الخاص بي؟

لأن في مسار بناء واحد على الأقل، لا يصل الـ alias أبداً إلى resolver الخاص بـ Rolldown. الحالة الضيقة والمؤكدة هي استدعاء `build()` من Cypress preprocessor. يشير نقاش فُتح في 1 مايو 2026 ضد Vite 8.0.10 إلى هذه المشكلة مع الخطأ `Rolldown failed to resolve import "@/model/Alert.model"`، كما أن تقرير خلل لاحق تم تقديمه في 8 مايو ضد 8.0.11 يعيد إنتاج المشكلة كـ `Rolldown failed to resolve import "@/foo.js"`.[^alias][^alias-issue]

النطاق مهم هنا، لأن عناوين المشكلات تقول "library mode" بينما يقول إعادة الإنتاج شيئاً أكثر تحديداً. يُظهر إعادة الإنتاج الخاص بالمبلغ أن *نفس الدالة* تنجح عند تشغيلها كـ script مستقل وتفشل فقط تحت Cypress preprocessor.[^alias-issue] هذا لا يعني أن "البناء البرمجي معطل"، ولا يعني أن "library mode معطل".

الحل المؤقت هو التصريح عن الـ alias في المكان الذي سيراه فيه Rolldown أيضاً:

```js
import path from 'node:path'

await build({
  configFile: false,
  resolve: { alias: { '@': path.resolve('./src') } },
  build: {
    rolldownOptions: {
      resolve: { alias: { '@': path.resolve('./src') } },
    },
    lib: { entry: filePath, formats: ['es'] },
  },
})
```

يذكر المبلغ أن نقل `resolve.alias` إلى تحت `build.rolldownOptions` "يجعله يعمل في كلتا الحالتين".[^alias-issue] لاحظ المسار المطلق: يتم حل إعادة الإنتاج باستخدام `path.resolve` بدلاً من تمرير سلسلة نصية نسبية.

**تحذيران قبل نسخ هذا.** أولاً، إذا كان الإعداد الخاص بك يحتوي بالفعل على كتلة `build.rollupOptions`، فإن إضافة `build.rolldownOptions` تجعل Vite يتجاهل كائن `rollupOptions` تماماً بدلاً من دمجه — راجع قاعدة الأولوية أعلاه.[^vite-src] قم بنقل كل شيء في نفس التعديل. ثانياً، تم **إغلاق المشكلة اللاحقة كـ "غير مخططة"**، لذا فهذا ليس خللاً ينتظر الإصلاح وقد يكون التكرار دائماً.[^alias-issue] شيئان آخران جربهما المبلغ — `configFile: false` بمفرده، ومفاتيح native-plugin التجريبية — لم يساعدا.[^alias]

هناك تغيير متعلق بالحل ينتج أخطاء مشابهة المظهر ولكن لسبب مختلف. كان Vite يقوم بفحص محتويات الملف عندما تعلن الحزمة عن حقلي `browser` و `module`، وكان يختار ملف ESM للمتصفحات. ألغى Vite 8 هذا الاستنتاج وأصبح يحترم دائماً ترتيب `resolve.mainFields`.[^migration] إذا كانت الحزمة التي كانت تُحل سابقاً إلى بناء ESM تُحل الآن إلى بناء UMD، فهذا هو السبب، والعلاجات الموثقة هي إدخال في `resolve.alias` أو patch لمدير الحزم.[^migration]

## لماذا يعيد استيراد `default` من حزمة CommonJS كائناً (object) الآن؟

لأن Vite 8 جعل التوافق التشغيلي لـ CommonJS `default` متسقاً، والاتساق يغير معنى بعض الاستيرادات. تسمي صفحة استكشاف الأخطاء وإصلاحها في Vite العرض بدقة — "Default import unexpectedly returns an object" — وتصفه كالتالي: "يعيد الاستيراد الافتراضي كائن `module.exports` لوحدات CJS، بينما قد تتوقع أن يعيد قيمة `module.exports.default`."[^troubleshooting]

هذا الأمر يستحق التوضيح بدقة، لأن التخمين البديهي هو أن الاستيراد (import) يصبح `undefined`. لكن الفشل الموثق يحدث بشكل عكسي: حيث تحصل على كائن `module.exports` بالكامل بينما كنت تتوقع خاصية واحدة منه. وعادة ما يكون العرض هو `x.default is not a function`، أو مكون (component) يتم رندرتُه كـ `[object Object]`، وذلك من عملية بناء (build) نجحت.

القاعدة التي ينص عليها دليل الهجرة هي أن استيراد `default` هو قيمة `module.exports` الخاصة بالطرف المستورد إذا تحقق أي من هذه الشروط:[^migration]

- أن يكون المستورد `.mjs` أو `.mts`
- أن يحتوي أقرب ملف `package.json` للمستورد على `"type": "module"`
- ألا تكون قيمة `module.exports.__esModule` للطرف المستورد هي `true`

خلاف ذلك، يكون استيراد `default` هو `module.exports.default`.

توثيقات Rolldown نفسها، والتي يربطها الدليل للحصول على الصورة الكاملة، تسرد مجموعة أطول من الشروط مقارنة بشروط Vite الثلاثة — بما في ذلك شرطان ينطبقان فقط على الاستيرادات الديناميكية (dynamic imports)، وشرط للحالة التي لا يمتلك فيها `module.exports` خاصية `default` على الإطلاق.[^cjs] إذا كانت شروط Vite الثلاثة لا تفسر ما تراه، فإن تلك الصفحة هي المكان الذي توجد فيه الحالات المتبقية.

في إصدار Vite 7، كانت القواعد تختلف بين بيئة التطوير (dev) والبناء (build)، وفي بيئة التطوير كانت تعتمد إضافياً على ما إذا كان المستورد مدرجاً في تحسين التبعيات (dependency optimization).[^migration] هذا التباين هو بالضبط ما يسمح لثغرة (bug) بالوصول إلى الإنتاج فقط بعد عملية البناء، وإزالتها هي الهدف من هذا التغيير.

هذا ليس افتراضياً. فقد قام تكامل Storybook Next.js بتقديم بلاغ تحت عنوان "NextImage renders as object with Vite 8 due to Rolldown CJS interop change"، والذي ظهر من خلال التجميع المسبق للتبعيات (dependency pre-bundling) في القصص واختبارات المتصفح؛ والعرض المُبلغ عنه هو رفض React للمكون برسالة "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object."[^storybook-cjs] نص الخطأ هذا هو الدليل — وجود *object* حيث كان من المتوقع وجود مكون. وقد تم إغلاق المشكلة منذ ذلك الحين مع إصلاح مرتبط، وهو الشكل المعتاد لهذا الأمر: كل حزمة متأثرة تقوم بإصلاح عملية فك التغليف (unwrapping) الخاصة بها.

بالنسبة لاستيراد واحد، يمكنك إزالة الغموض في موقع الاستدعاء بدلاً من اللجوء إلى علامة عالمية (global flag). توفر توثيقات Rolldown الاختبار الذي يجب استخدامه — تحقق من علامة `__esModule` بدلاً من التخمين:[^cjs]

```js
import raw from 'some-cjs-package'

const actual =
  typeof raw === 'object' && raw !== null && raw.__esModule ? raw.default : raw
```

إن فحص `__esModule` يقوم بعمل حقيقي هنا، لذا قاوم رغبتك في اختصاره إلى `raw.default ?? raw`. فموديول CommonJS بسيط يصادف أنه يصدر كائناً بخاصية `default` خاصة به، ولا يحدد `__esModule`، هو بالضبط الحالة التي يسلمك إياها استدلال Rolldown كاملاً — والتعبير الأقصر سيقوم بفك تغليفه بصمت إلى تلك الخاصية بدلاً من ذلك. هذه الفقرة تستنتج من القاعدة الموثقة بدلاً من شيء تنص عليه التوثيقات صراحةً، لذا اختبرها مقابل الحزمة المحددة بدلاً من اعتمادها بشكل أعمى.

هناك مخرج عالمي (global escape hatch) مهجور إذا كنت بحاجة إلى الشحن اليوم:

```js
// vite.config.js — temporary, deprecated
export default defineConfig({
  legacy: { inconsistentCjsInterop: true },
})
```

دليل الهجرة صريح في أن هذا حل مؤقت ويطلب منك الإبلاغ عن الحزم المتأثرة للمطورين الأساسيين، مع رابط لتوثيقات Rolldown حتى يكون لدى المسؤول عن الصيانة السياق الكامل.[^migration]

هناك تغييران متجاوران في CommonJS يصاحبان ذلك. استدعاءات `require` للوحدات الخارجية (externalized modules) يتم الحفاظ عليها الآن كـ `require` بدلاً من تحويلها إلى `import`؛ وإذا كنت بحاجة إلى السلوك القديم، فإن Vite يعيد تصدير `esmExternalRequirePlugin` الخاص بـ Rolldown من أجل ذلك — وهو أمر يهم بشكل أساسي عمليات بناء SSR وبناءات Node.[^migration] كما أن `import.meta.url` لم يعد يتم توفيره كـ polyfill في مخرجات UMD أو IIFE، حيث يتم استبداله بـ `undefined` بشكل افتراضي.[^migration] النقطة الثانية تستحق التوقف عندها إذا كنت تنشر مكتبة: `new URL('./worker.js', import.meta.url)` هو نمط Vite الموثق للـ workers وعناوين الـ assets، وفي بناء UMD يصبح الآن `new URL('./worker.js', undefined)` — مما يؤدي إلى خطأ في وقت التشغيل (runtime error) لدى المستخدمين، رغم أن عملية البناء أبلغت عن النجاح. الحل المذكور في الدليل هو خيار `define` مدمجاً مع `build.rolldownOptions.output.intro`.[^migration]

## لماذا تفشل الـ decorators الخاصة بي في التجميع في Vite 8؟

ابدأ بالتحقق من نوع الـ decorators التي تستخدمها، لأن الإجابة تختلف ومعظم الناس يستخدمون النوع الذي لا يزال يعمل.

**الـ `experimentalDecorators` الخاصة بـ TypeScript — والتي تستخدمها Angular و NestJS و TypeORM و MobX — مدعومة، وعلى الأرجح لن تحتاج إلى تكوين أي شيء.** توثيق المحول (transformer) الخاص بـ Oxc صريح في ذلك: "يدعم محول Oxc تحويل الـ decorators القديمة (legacy decorators). يُطلق عليها experimental decorators في TypeScript. إذا كنت تستخدم خيار `experimentalDecorators` في tsconfig، يمكنك استخدام خيار `decorator.legacy`."[^oxc-ts] والأكثر فائدة هو أن Vite "يحترم بعض الخيارات في `tsconfig.json` ويقوم بتعيين خيارات محول Oxc المقابلة لها"، و `experimentalDecorators` موجود في تلك القائمة — لذا فإن `"experimentalDecorators": true` في tsconfig الخاص بك هو المسار الموثق، و Vite يقوم بنقله نيابة عنك.[^features] إذا كنت ترغب في تعيينه من تكوين Vite، فإن هذا يتفوق على tsconfig عند وجود كليهما، والمسار يتبع خيار `oxc` في Vite الذي يوسع خيارات Oxc: `oxc.decorator.legacy`.[^features][^shared-options]

**الـ decorators الأصلية (Native decorators) — الخاصة بـ TC39 stage 3 — لم يتم تحويلها بواسطة Oxc بعد**، وفريق Vite ينتظر تقدم المواصفات.[^migration] إذا كان هذا ما تستخدمه، فإن دليل الهجرة يوثق حلين مؤقتين: `@rolldown/plugin-babel` مع `@babel/plugin-proposal-decorators`، و `@rollup/plugin-swc` مع `@swc/core`. كلاهما يتم تصفيتها للملفات التي تحتوي على `@`، باستخدام `rolldown: { filter: { code: '@' } }` ومساعد `withFilter` الخاص بـ Vite على التوالي.[^migration] الفلاتر مهمة: لأن إعادة إدخال تحويل JavaScript عبر كل ملف سيعيد وقت البناء الذي وفره Rolldown للتو.

```bash
npm install -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
```

```js
// vite.config.ts
import { defineConfig } from 'vite'
import babel from '@rolldown/plugin-babel'

function decoratorPreset(options) {
  return {
    preset: () => ({
      plugins: [['@babel/plugin-proposal-decorators', options]],
    }),
    // Only run this transform if the file contains a decorator.
    rolldown: { filter: { code: '@' } },
  }
}

export default defineConfig({
  plugins: [babel({ presets: [decoratorPreset({ version: '2023-11' })] })],
})
```

تستهدف كلتا المقطعين في الدليل إصدار الـ decorator `2023-11`، لذا فهما متماثلان من حيث السلوك — ولكن إذا قمت بتعديل أي منهما، فحافظ على تثبيت الإصدار بدلاً من ترك الإضافة (plugin) تقرر القيمة الافتراضية، لأن المراجعات تختلف في ترتيب تهيئة الحقول (field-initialisation order).

من جانب البيانات الوصفية (metadata)، أضاف Vite 8 دعماً مدمجاً لـ `emitDecoratorMetadata` الخاص بـ TypeScript، والذي كان يتطلب سابقاً إضافة خارجية — لكن الوثائق توضح ذلك: "هذا الخيار مدعوم جزئياً فقط. الدعم الكامل يتطلب استنتاج الأنواع (type inference) بواسطة مترجم TypeScript، وهو أمر غير مدعوم."[^features] ملاحظة Oxc الخاصة هي أنه "سيعود إلى نوع `Object` إذا لم يتمكن من حساب نوع بيانات الـ decorator الوصفية."[^oxc-ts] بالنسبة لحاوية حقن التبعيات (dependency-injection container) التي تعتمد على أنواع المعاملات، فإن العودة إلى `Object` تعني فشلاً في وقت التشغيل (runtime failure)، وليس مجرد خطأ بسيط.

هناك تحويل واحد غير متاح فعلياً: يذكر دليل الهجرة أن "التحويل إلى ES5 وما دونه باستخدام plugin-legacy غير مدعوم."[^migration] لا تزال مشكلة التتبع التي يشير إليها مفتوحة، وقد نشر مُبلغها تصحيحاً (patch) يعمل لـ Babel في `buildPolyfillChunk()` ينتج قطعة polyfills لـ ES5 — لذا فإن كلمة "غير مدعوم" هنا تعني "لا يوجد مسار مدعوم"، وليس "لا يوجد مسار على الإطلاق".[^es5] إذا كنت تشحن لبيئات ES5، فهذه المشكلة هي المكان الذي يجب البحث فيه قبل استنتاج أنك لا تستطيع الترقية.

## هل لا يزال Vite 8 يعمل مع Yarn PnP؟

جزئياً. النصيحة الأكثر تكراراً في تقارير عام 2026 — تحويل `nodeLinker` إلى `node-modules` قبل الترقية — تستند إلى تقارير تم إغلاقها الآن، بينما لا يزال هناك تقرير أحدث مفتوحاً في المراحل اللاحقة. هذا هو الادعاء الأكثر أهمية للاختبار مقابل مشروعك الخاص في هذه الصفحة، لذا ما يلي هو تتبع للمسار وليس حكماً نهائياً.

التقارير التي شكلت هذه السمعة كانت جميعها في `rolldown-vite`، وجميعها مغلقة. تم فتح بلاغ "rolldown-vite لا يعمل بشكل جيد مع Yarn PnP" في 4 يونيو 2025 ويصف فشلاً مستمراً في حل التبعيات الخارجية تحت PnP.[^pnp215] ثم تبعه بلاغ "Native resolver + yarn pnp: \[sass] Error: Can't find stylesheet to import." في 25 أغسطس 2025، والذي يحصر الفشل في مسار native-plugin resolver.[^pnp392] وتم فتح بلاغ "vite 8.0.0-beta.0 cannot resolve React dependency in Yarn PnP" في 5 ديسمبر 2025 وأُغلق بطلب سحب (pull request) مرتبط بـ Rolldown.[^pnp543] تم أرشفة ذلك المستودع في 19 مارس 2026 وهو للقراءة فقط، لذا فإن قدم هذه التقارير الثلاثة هو أمر هيكلي وليس عرضياً.[^pnp215]

في المصدر الأساسي، تم إغلاق مشكلة التتبع الخاصة بـ resolver الخاص بـ Oxc بطلب سحب مرتبط، وينص محتواها بوضوح: "Yarn PnP يعمل الآن في v11.5.0 بدون أي إعدادات."[^oxc-resolver] لا تذكر الصفحة أي تحذيرات. كما أنها لا تعيد توضيح المشروع الذي ينتمي إليه رقم الإصدار هذا — سياقياً هو oxc-resolver، ولكن الخطوة العملية هي التحقق مما هو مثبت فعلياً بدلاً من الثقة في الرقم: `npm ls rolldown` سيعطيك إصدار Rolldown في شجرتك، وملاحظات إصدار Rolldown تحدد إصدار resolver الذي يتضمنه.

من ناحية أخرى، كانت هناك مشكلة في Vitest تم فتحها في 5 مارس 2026 — "تراجع في 4.1.0-beta.4 في وضع Yarn PnP، حيث تتوقف الاختبارات بشكل غير محدد في Vite 8" — وكانت لا تزال مفتوحة وقت كتابة هذا المقال ومصنفة كـ `upstream`.[^pnp-vitest] اقرأ الآلية قبل تقييمها: تشخيص المُبلغ نفسه هو أن Vitest يستورد تبعية اختيارية، `@opentelemetry/API`، والتي يرفض PnP الصارم حلها لأنها غير مصرح بها، وأن تثبيتها يحل المشكلة.[^pnp-vitest] هذا تراجع في التغليف ظهر بسبب صرامة PnP، وليس دليلاً على وجود خلل في resolver الخاص بـ Rolldown — وهذا بالضبط هو السبب في أنه من الأفضل تسميتها بدقة بدلاً من الاستشهاد بها كدليل.

لذا: لا تقم بإعادة كتابة `.yarnrc.yml` بناءً على مشكلة من عام 2025 في مستودع مؤرشف، ولا تفترض أن PnP خالٍ من المشاكل أيضاً. قم بتشغيل عملية البناء (build) ومجموعة الاختبارات. `nodeLinker: node-modules` هو خيار احتياطي قد لا تحتاجه.

## لماذا يستهدف البناء الخاص بي الآن متصفحات أحدث من ذي قبل؟

لأن القيمة الافتراضية لـ `build.target` قد تغيرت. قيمة `'baseline-widely-available'` في Vite 8 يتم حلها إلى `['chrome111', 'edge111', 'firefox114', 'safari16.4', 'ios16.4']`، وهي مثبتة على Baseline Widely Available اعتباراً من 2026-01-01.[^build-options] في Vite 7، كانت نفس القيمة الخاصة يتم حلها إلى `['chrome107', 'edge107', 'firefox104', 'safari16']`.[^vite7-target]

لا توجد أخطاء ستظهر. ببساطة سيتوقف المخرج الخاص بك عن كونه مُحولاً (transpiled) للمتصفحات الموجودة بين هذين الخطين، وإذا كانت مصفوفة الدعم الخاصة بك تشملها، فقد قمت بشحن تراجع في التوافق دون تحذير. قم بتعيين `build.target` بشكل صريح إذا كان لديك مصفوفة دعم محددة يجب الالتزام بها — يجب أن تكون القيمة هدفاً صالحاً لـ Oxc Transformer، وسيقوم Vite بالتحذير وقت البناء إذا كان الكود الخاص بك يحتوي على ميزات لا يمكن لـ Oxc تحويلها بأمان.[^build-options]

التغيير الافتراضي الثاني في نفس المنطقة هو `build.minify`، والذي أصبح الآن `'oxc'` لعمليات بناء العميل (client builds). يصف Vite أداة Oxc Minifier بأنها "أسرع بـ 30 \~ 90 مرة من terser وبضغط أسوأ بنسبة 0.5 \~ 2% فقط".[^build-options] إذا كنت تشك في أن الـ minifier يقوم بتجميع الكود الخاص بك بشكل خاطئ، فإن دليل الهجرة يشير إلى وثائق الافتراضات المنشورة لكلا الـ minifiers حتى تتمكن من مقارنتها بدلاً من التخمين.[^migration]

## هل لا زلت بحاجة إلى تثبيت esbuild؟

فقط إذا اخترت العودة لاستخدامه. يقول دليل الهجرة أن esbuild "لم يعد مستخدماً بشكل مباشر من قبل Vite وأصبح الآن تبعية اختيارية"؛ في بيانات الحزمة المنشورة للإصدار 8.2.2، يأخذ ذلك شكل `peerDependenciesMeta.esbuild.optional: true`، مع نطاق إصدار `^0.27.0 || ^0.28.0` مُعلن تحت `peerDependencies`.[^migration][^npm]

ستحتاج إلى إضافته كـ `devDependency` في ثلاث حالات:[^migration][^build-options]

- `build.minify: 'esbuild'`، وهو أمر مهجور (deprecated) في حد ذاته
- `build.cssMinify: 'esbuild'` — وهو السبب الأكثر شيوعاً اليوم، وفقاً لقسم CSS أعلاه
- أي إضافة (plugin) تستدعي `transformWithEsbuild`، والتي أصبحت مهجورة لصالح `transformWithOxc`

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

## كيف أعرف أي من الإضافات الخاصة بي تتسبب في تعطل عملية البناء (build)؟

استخدم طريقة التنصيف (Bisect) أولاً، ثم اقرأ. أسرع طريق للوصول إلى المسبب هو تقسيم مصفوفة الـ `plugins` إلى النصف، ثم إعادة البناء، وتكرار العملية — فإجراء بضع عمليات بناء أفضل من قراءة شجرة إضافات متداخلة، وهي طريقة تنجح حتى عندما تكون الإضافة المتعطلة هي إضافة قام الإطار (framework) بتثبيتها بدلاً من واحدة اخترتها أنت.

هناك ثلاثة أشياء تسرع هذه العملية:

- **`vite build --debug`** للحصول على مخرجات تصحيح الأخطاء الخاصة بـ Vite في الخطوة المتعطلة.
- **`VITE_DEPRECATION_TRACE=1`** عندما يكون الفشل بسبب خيار مهجور وليس تعطلاً كاملاً. فهي تحول التحذير إلى تتبع للمكدس (stack trace)، وهي الطريقة الأكثر مباشرة لمعرفة *أي إضافة* قامت بتعيين خيار لم تكتبه أنت أبداً.[^vite-src]
- **نطاقات التبعيات (Peer ranges).** تحقق من الـ `peerDependencies` المعلنة لكل إضافة لـ `vite`. الإضافة التي لم تقم بتوسيع نطاقها إلى `^8` تخبرك بشيء ما قبل أن تقرأ سطراً واحداً من الكود المصدري الخاص بها.

بمجرد تحديد المشتبه به، هناك أربعة اختلافات هيكلية تفسر جزءاً كبيراً من تعطل الإضافات:[^migration]

1. **الخطافات المفقودة (Missing hooks).** تم إدراج `shouldTransformCachedModule` و `resolveImportMeta` و `renderDynamicImport` و `resolveFileUrl` تحت بند "عدم دعم Rolldown" ولم تعد مدعومة. الدليل لا يذكر ماذا تفعل الإضافة المتأثرة أثناء التشغيل، لذا تعامل مع أي إضافة تستخدم أحدها كمشتبه به بدلاً من انتظار رسالة تشخيصية.
2. **الخطافات المتسلسلة (Sequential hooks).** "جميع الخطافات المتوازية في Rollup تعمل كخطافات متسلسلة" في Rolldown.
3. **كائن الـ `bundle`.** التعيين لـ `bundle[foo]` لم يعد مدعوماً — استخدم `this.emitFile()`. المرجع لا يتم مشاركته عبر الخطافات، و `structuredClone(bundle)` تسبب الآن خطأ `DataCloneError`؛ قم بعمل نسخة باستخدام `{ ...bundle }` بدلاً من ذلك.
4. **أنواع الوحدات (Module types).** يقوم Rolldown بتعيين نوع الوحدة تلقائياً من امتداد المعرف الذي تم حله. الإضافة التي تحول محتوى غير JS إلى JavaScript في `load` أو `transform` قد تحتاج إلى إرجاع `moduleType: 'js'` بشكل صريح.

أطلقت Vite موقع `registry.vite.dev` بالتزامن مع Vite 8، وهو دليل قابل للبحث لإضافات Vite و Rolldown و Rollup مبني من بيانات npm اليومية، وهو المكان الصحيح للتحقق من الحالة الحالية للإضافة بدلاً من أي قائمة ثابتة.[^announce]

إذا كنت تستدعي JavaScript API الخاصة بـ Vite مباشرة، فهناك تغيير آخر مهم: `build()` تسبب الآن خطأ `BundleError`، مُعرف كـ `Error & { errors?: RolldownError[] }`، والذي يغلف الأخطاء الفردية في مصفوفة. كتل الـ `catch` الحالية التي تقرأ `e.message` ستقدم تقريراً أقل فائدة بكثير من `e.errors`.[^migration]

## لماذا تسبب إصدار تصحيحي (patch release) من Vite 8 في تعطل بناء (build) كان يعمل بالأمس؟

لأن Rolldown لا يزال يتطور تحت إصدارات Vite التصحيحية، وقد ظهرت تراجعات (regressions) موثقة بهذه الطريقة. هذه حالة منفصلة لأن التشخيص مختلف: لم يتغير شيء في إعداداتك (config)، لذا فإن الخطوة الأولى المفيدة هي العودة لإصدار سابق للتأكيد، وليس تعديل أي شيء.

أبلغت مشكلة فُتحت في 24 أبريل 2026 عن فشل عمليات بناء Astro بعد التحديث من **8.0.8 إلى 8.0.10** مع `Missing field 'tsconfigPaths' on BindingViteResolvePluginConfig.resolveOptions`، والتي ظهرت من `@tailwindcss/vite`؛ وعزا المُبلغ ذلك إلى تحديث إصدار مرشح (release-candidate) لـ Rolldown، بينما ذكر متغير ثانٍ لنفس العرض نقصاً في حقل مختلف.[^resolver22322] وقد أُغلقت المشكلة على أنها غير مخططة.

أبلغت مشكلة فُتحت في 1 يوليو 2026 عن فشل عملية بناء بدءاً من **8.1.0 فصاعداً** مع `[MISSING_EXPORT] "placements" is not exported by "node_modules/@popperjs/core/lib/index.js"`، في مشروع يتم بناؤه بنجاح على إصدار 8.0.16.[^resolver22835] وقد أُغلقت كنسخة مكررة. هناك تفصيلان يستحقان الذكر: الحل المؤقت الذي ذكره المُبلغ هو حرفياً `npm install vite@=8.0.16`، والفشل يحدث في عملية البناء فقط — "لا توجد مشكلة مع `npm run dev`"، وهذا هو الفخ، لأن عمل خادم التطوير (dev server) ليس دليلاً على السلامة.[^resolver22835]

الاستجابة العملية هي التعامل مع إصدار Vite التصحيحي كمتغير في عملية البحث الثنائي (bisect). إذا تعطل البناء دون تغيير في الإعدادات، قم بتثبيت الإصدار التصحيحي السابق، وتأكد من ذلك، ثم اقرأ سجل التغييرات (changelog) بين الإصدارين بدلاً من البحث في الكود المصدري الخاص بك.

## لماذا ينجح البناء محلياً ويفشل في بيئة CI؟

لأن هناك نمطين من الفشل في Vite 8 يعتمدان على خصائص البيئة بدلاً من الكود الخاص بك، ولا يتعلق أي منهما بإصدار Node الخاص بك.

**الملف الثنائي الأصلي (The native binary).** يقوم Rolldown بشحن ملفاته الثنائية الخاصة بكل منصة كـ `optionalDependencies` في npm — خمسة عشر ملفاً في الإصدار الحالي، واحد لكل هدف.[^rolldown-npm] هذا هو نفس نمط التغليف الذي تسبب في فشل عمليات تثبيت Rollup لفترة طويلة، وقد ورثه Rolldown. العرض الخارجي هو `Error: Cannot find native binding`، والذي يغلف خطأ `Cannot find module '../rolldown-binding.<platform>.node'`.[^binding] تعالج صفحة استكشاف الأخطاء في Rolldown هذا الخطأ الداخلي تحت عنوان `Error: "Cannot find module '@rolldown/binding-...'"` وتحدد السبب: "عادة ما يكون ذلك بسبب خطأ معروف في npm مع التبعيات الاختيارية (npm/cli#4828)؛ إذا قمت بالتثبيت باستخدام npm، فإن إزالة `node_modules` و `package-lock.json` وإعادة التثبيت يحل المشكلة."[^rolldown-ts] وتوثق نفس الصفحة سبباً ثانياً يستحق المعرفة إذا كنت تطور عبر Windows و WSL: يمكن لملف إعدادات في دليل مرتبط رمزياً (symlinked directory) أن يوجه `rolldown` إلى `node_modules` مثبت لمنصة مختلفة، والحلول هي إبقاء ملف الإعدادات خارج الدليل المرتبط رمزياً أو تعيين `NODE_OPTIONS=--preserve-symlinks` — مع التنبيه المذكور في تلك الصفحة بأن هذا الخيار "غير متوافق مع pnpm، الذي يعتمد تخطيط `node_modules` الخاص به على الروابط الرمزية."[^rolldown-ts]

يضيف تقرير مجتمعي محفزاً إضافياً من السهل إغفاله لأنه يبدو غير مرتبط. وجد أحد المعلقين أن تغيير حقل `engines` في ملف `package.json` من `"node": ">22"` إلى `">=22.18.0"` "أدى إلى تحميل الملف الثنائي (binary)"، وأشار إلى إعداد `minimumReleaseAge` في مدير الحزم كسبب محتمل آخر.[^binding] قراءة الـ semver هي استنتاجي الشخصي وليست استنتاجهم، وهي على الأقل متسقة: `>22` تُترجم إلى `>=23.0.0`، وهو ما يستبعد نطاق 22.12–22.x الذي يعلن Rolldown دعمه له.[^rolldown-npm] إذا كانت صورة الـ CI الخاصة بك تعتمد على Alpine أو musl، فتأكد أيضاً من أنك تحصل على ربط musl بدلاً من gnu.

**الذاكرة.** هذا هو الأمر الذي لا تهيئك له أرقام حجم التثبيت. يشير تقرير عن مشكلة مفتوحة ومسندة لـ Rolldown في لوحة "عقبات الانتقال إلى Vite 8" إلى زيادة تقريبية بمقدار سبعة أضعاف في بصمة الذاكرة الفعلية في وضع التطوير (dev mode) — حوالي 880 ميجابايت في Vite 7.3.3 مقابل حوالي 6.7 جيجابايت في Vite 8.0.11 — في مشروع واحد كبير.[^mem9330] اقرأ تحذيرات المُبلغ نفسه بشأن ذلك: لم يقم بفحص منفصل لـ `@vitejs/plugin-React` من الإصدار 4 إلى 5، لذا قد يكون جزء من التراجع في الأداء موجوداً هناك؛ ولا يوجد نموذج إعادة إنتاج أدنى (minimal reproduction) حتى الآن؛ كما أن التراجع موجود منذ أول نسخة بيتا من Vite 8 بدلاً من الظهور في تحديث معين، مع اعتبار أن التفاوت عبر الإصدارات المستقرة "ضئيل جداً مقارنة بالقفزة من v7 إلى v8".[^mem9330] هذا قياس لمشروع واحد، وليس اختبار أداء (benchmark). ولكن في بيئة CI محدودة الموارد، غالباً ما يظهر إنهاء العملية بسبب نفاد الذاكرة (out-of-memory kill) على شكل خروج بقيمة غير صفرية بدون رسالة مفيدة، وهو ما يبدو تماماً مثل "فشل البناء بعد الترقية".

لا يتم تغطية أي من هذه النقاط في توثيق Vite أو Rolldown باستثناء صفحة الربط الأصلي (native-binding)، لذا تعامل مع الذاكرة بشكل خاص كشيء يجب قياسه على بيئة التشغيل الخاصة بك بدلاً من البحث عن إجابة موثقة.

## كيف يمكنني الانتقال تدريجياً، أو التراجع؟

استخدم المسار الرسمي المكون من خطوتين. تقوم حزمة `rolldown-vite` بتنفيذ Vite 7 مع Rolldown وبدون أي من تغييرات Vite 8 الأخرى، مما يعزل مشاكل المجمع (bundler) عن كل شيء آخر، وتوصية Vite للمشاريع الكبيرة هي الانتقال إليها في Vite 7 أولاً، ثم الترقية.[^migration][^announce] التخلي عنها هو تغيير من سطر واحد كما يوضح الدليل — استبدال إدخال `"vite": "npm:rolldown-vite@7.2.2"` بـ `"vite": "^8.0.0"`.[^migration]

التراجع إلى Vite 7 هو أكثر من مجرد تغيير في رقم الإصدار، لأن الترقية سحبت معها إصدارات رئيسية مرتبطة. قم بمسح ملف القفل (lockfile) والشجرة أولاً، حتى يتم حل إعادة التثبيت بشكل نظيف بدلاً من الاعتماد على إدخالات قديمة لـ `rolldown` و `lightningcss` والربط الأصلي:

```bash
rm -rf node_modules package-lock.json
# edit package.json: vite ^7, and revert your framework plugin's major
npm install
```

هناك شيئان يجب التحقق منهما أثناء وجودك هناك. يحتاج ملحق الإطار البرمجي (framework plugin) الخاص بك إلى إصدار يقبل Vite 7 في نطاق الـ peer range — حيث يعلن `@vitejs/plugin-React@5.2.0` عن `^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0`، مما يجعل هذا الإصدار تحديداً نقطة توقف آمنة في كلا الاتجاهين؛ الإصدارات السابقة من 5.x تتوقف عند Vite 7، بينما يتطلب خط v6 إصدار Vite 8.[^plugin-React-npm] ولاحظ أن `node_modules/.vite` هو ذاكرة التخزين المؤقت لتحسين التبعيات في Vite ويوجد داخل `node_modules`، لذا فإن حذف الأخير يمسحه بالفعل — ولكن ذاكرة التخزين المؤقت التي كتبها Rolldown ليست شيئاً يجب أن يقرأه Vite 7، لذا لا تتخطى هذه الخطوة. تظل وثائق Vite 7 متاحة على `v7.vite.dev`، والتي تربط بها وثائق Vite 8 مباشرة.[^migration]

Vitest ليس العائق الذي يفترضه الناس: يعلن `vitest@4.1.11` عن نطاق Vite peer range الخاص به كـ `^6.0.0 || ^7.0.0 || ^8.0.0`، لذا فإن هذا الخط يمتد عبر ثلاث إصدارات رئيسية من Vite، ولا يفرض التراجع (rollback) خفض إصدار Vitest.[^vitest-npm] تحقق من الإصدار المثبت لديك بدلاً من الافتراض، لأن النطاق قد تغير عبر إصدارات Vitest.

تحذير واحد بشأن تسلسل الخطوات ينطبق على بعض مجموعات التقنيات (stacks). في تطبيق React أو Vue بسيط، يمكنك ترقية Vite أولاً ثم الملحق بعد ذلك، مما يجعل عملية الـ bisect ذات معنى.[^announce] أما في الإطارات البرمجية الشاملة (meta-framework) — مثل Storybook، Nuxt، SvelteKit، Astro، React Router — فإن نطاق الـ peer range غالباً ما يحدد الترتيب نيابة عنك، وسيرفض مدير الحزم الخاص بك التثبيت أو سينتج شجرة تبعيات مكسورة. تحقق من نطاق Vite المدعوم من الإطار البرمجي قبل التخطيط للتسلسل وليس بعده. إذا قمت بنقل `@vitejs/plugin-React` إلى v6، فإنه يستخدم Oxc لتحويل React Refresh ويتخلى عن Babel كـ dependency، مع مساعد `reactCompilerPreset` للمشاريع التي تحتاج إلى React Compiler — وهو إعداد مختلف عن الإعداد القائم على Babel الذي شحنه v5، ويستحق القراءة عنه أولاً إذا سبق لك تصحيح أخطاء [React Compiler not memoizing a component](https://nerdleveltech.com/React-compiler-not-memoizing-component).[^announce]

## هل عملية البناء أسرع بالفعل، وما هي التكلفة؟

أسرع، بناءً على الأدلة المتاحة، وهذه الأدلة مقدمة بالكامل من المورد. يشير Vite إلى أن Rolldown أسرع بـ 10-30 مرة من Rollup في الاختبارات المرجعية (benchmarks)، ويذكر أربع شركات مع أوقات بناء إنتاجية مقاسة: Linear من 46 ثانية إلى 6 ثوانٍ، وRamp مع انخفاض بنسبة 57%، وMercedes-Benz.io بنسبة تصل إلى 38%، وBeehiiv بنسبة 64%.[^announce] تم الإبلاغ عن هذه النتائج من قبل المتبنين خلال مراحل المعاينة والبيتا، على قواعد الكود الخاصة بهم. لم أجد أي اختبار مرجعي مستقل منشور لـ Vite 8 مقابل Vite 7 حتى سبتمبر 2026، لذا تعامل مع هذا النطاق كمؤشر عام.

التكلفة المعلنة هي حوالي **15 ميجابايت** من حجم التثبيت الإضافي مقارنة بـ Vite 7: حوالي 10 ميجابايت لأن Lightning CSS انتقل من كونها peer dependency اختيارية إلى تبعية عادية، وحوالي 5 ميجابايت لملف Rolldown الثنائي (binary)، وهو أكبر من esbuild بالإضافة إلى Rollup لأنه يفضل السرعة على حجم الملف الثنائي.[^announce] يقول Vite إنه سيواصل العمل لتقليل ذلك.[^announce] رقم القرص هو التكلفة المعلنة؛ أما أرقام الذاكرة في قسم CI أعلاه فهي التكلفة غير المعلنة.

متطلبات Node لم تتغير: يحتاج Vite 8 إلى Node 20.19+ أو 22.12+، وهو نفس الأمر بالنسبة لـ Vite 7، ويؤكد حقل `engines` المنشور للإصدار 8.2.2 ذلك بـ `^20.19.0 || >=22.12.0`.[^announce][^npm] وهذا يجعل إصدار Node غير مؤثر — ولكن كما يغطي قسم CI، فهو ليس الشيء الوحيد المهم في بيئة CI الخاصة بك.

## الأسئلة الشائعة

**هل تم حذف `build.rollupOptions` في Vite 8؟** لا. تم توثيقه كاسم مستعار لـ `build.rolldownOptions` وتم وضع علامة "مهجور" (deprecated) عليه. لا يزال يعمل، وتغيير اسمه لن يؤدي إلى إصلاح عملية بناء (build) فاشلة.[^build-options]

**ماذا يحدث إذا قمت بتعيين كل من `build.rollupOptions` و `build.rolldownOptions`؟** تكون الأولوية لـ `rolldownOptions` ويتم تجاهل `rollupOptions` تماماً، ولا يتم دمجهما. لا تذكر الوثائق ذلك؛ ولكن كود Vite المصدري يذكر ذلك في تعليق على السطر الذي ينفذه.[^vite-src]

**ما الذي تم حذفه فعلياً في Vite 8؟** `build.rollupOptions.watch.chokidar`، وشكل الكائن (object form) لـ `output.manualChunks`، ووسائط URL لـ `import.meta.hot.accept`. وبشكل منفصل، فإن تنسيقات `system` و `amd` وأربعة من خطافات (hooks) Rollup غير مدعومة بواسطة Rolldown؛ و `esbuild.supported` وخيارات تشويه الخصائص (property-mangling) في esbuild غير مدعومة بواسطة Oxc؛ و `build.commonjsOptions` لا يزال يتم تحليله ولكنه أصبح الآن بدون تأثير (no-op).[^migration]

**كيف أستبدل `manualChunks: { vendor: [...] }` في Vite 8؟** باستخدام `build.rolldownOptions.output.codeSplitting`، عبر استخدام مدخلات \_\_PRESERURE\_\_`groups` التي تأخذ `test` الاختيارية سلسلة نصية، أو تعبيراً نمطياً (regular expression)، أو دالة شرطية (predicate) على معرف الموديول — وليس قائمة بأسماء الحزم. توقع وجود قطعة `runtime.js` إجبارية والتقاط تكراري للاعتمادات.[^rolldown-cs]

**تعطل الـ CSS الخاص بي بعد التحديث. ما الذي تغير؟** أصبح `build.cssMinify` الآن يضبط افتراضياً على `'lightningcss'`. يمكنه رفض الصيغ الحديثة مثل `@scope`، ويمكنه حذف `backdrop-filter` غير المسبوق ببادئة إذا كان يسبق نظيره `-webkit-`، دون إظهار خطأ. جرب تجاوز إصدار Lightning CSS أو استخدام `build.cssTarget` قبل التراجع عن خط الإنتاج بالكامل باستخدام `build.cssMinify: 'esbuild'`.[^build-options][^css21911][^css22649][^css21954]

**ماذا يعني `The "TopLevelAwait" is not supported with the "iife" output format`؟** هناك شيء ما في الحزمة يستخدم `await` على المستوى الأعلى (top-level) وتنسيق المخرجات لا يمكنه التعبير عن ذلك. يقوم Rolldown بإصدار `await` على المستوى الأعلى فقط في تنسيق `esm`، لذا فإن التبديل إلى UMD أو CJS لن يساعد. السبب المعتاد هو الـ workers، بما أن `worker.format` يكون افتراضياً `'iife'`؛ جرب استخدام `worker: { format: 'es' }`.[^rolldown-tla][^worker-options][^tla]

**لماذا لا يعمل `resolve.alias` في استدعاء `build()` البرمجي الخاص بي؟** في حالة واحدة تم التحقق منها — وهي استدعاء `build()` في وضع المكتبة (library-mode) من خلال Cypress preprocessor — لا يصل الـ alias أبداً إلى Rolldown؛ بينما تعمل نفس الدالة بشكل مستقل. قم بتعريفه تحت `build.rolldownOptions.resolve.alias` أيضاً، ولكن قم بنقل أي `build.rollupOptions` موجودة في نفس التعديل، لأن تعيين كليهما يؤدي إلى تجاهل الأخير. تم إغلاق المشكلة اللاحقة على أنها غير مخططة.[^alias][^alias-issue][^vite-src]

**لماذا يعيد استيراد `default` من حزمة CommonJS كائناً (object)؟** قام Vite 8 بتوحيد قواعد التوافق لـ CJS `default` عبر مراحل التطوير والبناء، لذا في سياق ESM ستحصل الآن على `module.exports` بدلاً من `module.exports.default`. بالنسبة لاستيراد واحد، قم بالتمييز باستخدام اختبار `__esModule` الخاص بـ Rolldown بدلاً من علامة `legacy.inconsistentCjsInterop` العالمية المهجورة.[^troubleshooting][^migration][^cjs]

**هل تعمل الـ decorators في Vite 8؟** تعمل `experimentalDecorators` الخاصة بـ TypeScript — حيث يدعمها Oxc من خلال خيار `decorator.legacy`. أما الـ decorators الأصلية من TC39 فلم يتم تحويلها (lowered) بعد، ويوثق دليل الهجرة حلولاً بديلة باستخدام Babel و SWC. يتم دعم `emitDecoratorMetadata` ولكن، وفقاً للوثائق، "بشكل جزئي فقط".[^oxc-ts][^migration][^features]

**هل يدعم Vite 8 خاصية Yarn PnP؟** التقارير الثلاثة التي تم تتبعها في `rolldown-vite` مغلقة وقد تم أرشفت هذا المستودع في 19 مارس 2026، وتشير مشكلة resolver الخاصة بـ Oxc إلى أن PnP "يعمل الآن في الإصدار v11.5.0 بدون أي إعدادات". كانت هناك مشكلة واحدة أحدث في Vitest لا تزال مفتوحة وقت الكتابة، على الرغم من أن سببها المذكور هو تبعية اختيارية غير معلنة بدلاً من عيب في الـ resolver. اختبر عملية البناء ومجموعة الاختبارات الخاصة بك.[^pnp215][^pnp392][^pnp543][^oxc-resolver][^pnp-vitest]

**لماذا يستهدف الـ bundle الخاص بي متصفحات أحدث الآن؟** انتقل `'baseline-widely-available'` من `['chrome107', 'edge107', 'firefox104', 'safari16']` في Vite 7 إلى `['chrome111', 'edge111', 'firefox114', 'safari16.4', 'ios16.4']` في Vite 8. قم بتعيين `build.target` بشكل صريح إذا كان لديك مصفوفة دعم فعلية.[^vite7-target][^build-options]

**هل لا زلت بحاجة إلى تثبيت esbuild؟** فقط من أجل `build.minify: 'esbuild'`، أو `build.cssMinify: 'esbuild'`، أو إضافة (plugin) تستدعي `transformWithEsbuild`. إنها تبعية اختيارية في Vite 8، ومعلنة بنطاق peer range هو `^0.27.0 || ^0.28.0`.[^migration][^npm]

**لماذا تنجح عملية البناء محلياً ولكنها تفشل في CI؟** عادة ما يكون السبب أحد أمرين: فشل تثبيت الملف الثنائي الأصلي (native binary) الخاص بـ Rolldown والمخصص لمنصة معينة، وهو ما تعزوه صفحة استكشاف الأخطاء في Rolldown إلى خطأ معروف في التبعيات الاختيارية لـ npm؛ أو الذاكرة، حيث يقيس أحد التقارير المفتوحة زيادة تقريبية بمقدار سبعة أضعاف في استهلاك الذاكرة في وضع التطوير (dev-mode) مقارنة بـ Vite 7.[^rolldown-ts][^rolldown-npm][^mem9330]

**تسبب إصدار إصلاحي (patch release) في تعطل عملية البناء الخاصة بي. هل هذا متوقع؟** لقد حدث ذلك مرتين على الأقل في حالات موثقة — تراجع في إعدادات resolver-plugin بين الإصدارين 8.0.8 و 8.0.10، وفشل بسبب تصدير مفقود (missing-export) في الإصدار 8.1.0 لا يتكرر في خادم التطوير. قم بالرجوع إلى إصدار سابق للتأكيد قبل تعديل إعداداتك.[^resolver22322][^resolver22835]

**هل يمكنني الترقية تدريجياً؟** نعم. انتقل إلى حزمة `rolldown-vite` على Vite 7 أولاً لعزل مشكلات الـ bundler، ثم انتقل إلى Vite 8.[^migration][^announce]

**ما مدى زيادة حجم تثبيت Vite 8؟** أكبر بنحو 15 ميجابايت من Vite 7 — حوالي 10 ميجابايت بسبب تحول Lightning CSS إلى تبعية عادية وحوالي 5 ميجابايت من ملف Rolldown الثنائي.[^announce]

## الخلاصة

تقوم طبقة التوافق في Vite 8 بعمل أكبر مما توحي به سمعتها، والكثير من نصائح الهجرة المتداولة في عام 2026 تقضي فقراتها الافتتاحية في الحديث عن إعادة تسمية ليست مطلوبة لجعل عملية البناء (build) تنجح. الإخفاقات التي توقف عمليات البناء فعلياً هي أكثر تحديداً وضيقاً: مصغر CSS أكثر صرامة، قاعدة ESM-only لـ `await` في المستوى الأعلى، دلالات CommonJS موحدة، مزخرفات (decorators) أصلية بدون خطوة خفض (lowering step)، قائمة قصيرة من الخيارات المحذوفة — وبالنسبة لعدد كبير من الفرق، مشكلة في بيئة CI لا علاقة لها بأي مما سبق.

أربع خطوات، بالترتيب. قم بتشغيل عملية البناء دون تغيير واقرأ الخطأ مقارنة بالمجموعات السبع المذكورة أعلاه. إذا فشلت العملية في CI فقط، فانتقل إلى قسم الملفات الثنائية الأصلية (native-binary) والذاكرة قبل أن تلمس الإعدادات. إذا كان الفشل في CSS، جرب تجاوز Lightning CSS أو `build.cssTarget` قبل التراجع عن خط الإنتاج بالكامل. وإذا كان أي شيء آخر، قم بتسجيل إضافة `configResolved` واطبع ما أنتجته طبقة التوافق قبل أن تغير سطراً واحداً.

ثم اترك تنظيف العناصر المهجورة (deprecation cleanup) لعملية commit منفصلة — وعندما تفعل ذلك، انقل كل كائن `rollupOptions` بالكامل، لأن الإعدادات التي تمت هجرتها جزئياً تفقد بصمت النصف الذي تركته خلفك. إذا كنت تقوم أيضاً بتحديث بقية مجموعة أدواتك، فإن نمط "إعادة كتابة بـ Rust، مع نفس واجهة API" يستحق القراءة عنه في [المترجم الأصلي لـ TypeScript 7](https://nerdleveltech.com/TypeScript-7-native-compiler-tsgo)، وإذا كان هذا التحديث مرتبطاً بتطوير شامل لـ CSS، فإن [Tailwind v4 مع Vite وإعدادات `@theme` التي تعتمد على CSS أولاً](https://nerdleveltech.com/tailwind-v4-vite-css-first-theme-config-tutorial) تغطي جانب الإضافات لهذا المزيج.

## المراجع

[^announce]: "Vite 8.0 is out!", مدونة Vite، 12 مارس 2026 — <https://vite.dev/blog/announcing-vite8> — تاريخ الإصدار، مبررات Rolldown، ادعاء زيادة السرعة من 10 إلى 30 ضعفاً، أوقات بناء المتبنين المحددين، تفصيل حجم التثبيت، متطلبات Node، `@vitejs/plugin-React` الإصدار 6، registry.vite.dev، توصية بالانتقال التدريجي.

[^build-options]: "Build Options"، مرجع تهيئة Vite — <https://vite.dev/config/build-options> — تم توثيق `build.rollupOptions` كاسم مستعار مهجور، وقيم `build.target` المحلولة، والقيم الافتراضية لـ `build.cssMinify` و `build.minify`، وأولوية `build.cssTarget`، ومتطلبات تثبيت esbuild.

[^migration]: "Migration from v7"، توثيق Vite — <https://vite.dev/guide/migration> — الخيارات المهجورة مقابل المزالة مقابل غير المدعومة، جداول التحويل التلقائي، قواعد التوافق مع CJS، حلول بديلة للمزخرفات (decorators)، تغيير هدف المتصفح، وتغييرات في الإضافات و JS API. تم الاسترجاع في 3 سبتمبر 2026 بناءً على توثيقات Vite 8.2.2.

[^npm]: بيانات حزمة `vite@8.2.2`، سجل npm — <https://registry.npmjs.org/vite/latest> — الإصدار الحالي، حقل `engines`، تبعيات `rolldown` و `lightningcss`، و `esbuild` المدرج تحت `peerDependencies` (`^0.27.0 || ^0.28.0`) مع `peerDependenciesMeta.esbuild.optional: true`.

[^worker-options]: "Worker Options"، مرجع تهيئة Vite — <https://vite.dev/config/worker-options> — نوع `worker.format` هو `'es' | 'iife'` مع القيمة الافتراضية `'iife'`؛ تم توثيق `worker.rollupOptions` كاسم مستعار مهجور (deprecated alias).

[^vite-src]: كود Vite المصدري، `packages/vite/src/node/utils.ts` — <https://GitHub.com/vitejs/vite/blob/main/packages/vite/src/node/utils.ts> — التعليق والتنفيذ "إذا كان كل من rollupOptions و rolldownOptions موجودين، يتم تجاهل rollupOptions واستخدام rolldownOptions"؛ تحذير الإهمال المقيد بـ `optimizeDeps` و `ssr.optimizeDeps`؛ ومفتاح `VITE_DEPRECATION_TRACE` للتحويل من `console.warn` إلى `console.trace`. تحذير "سيتم تجاهله" على مستوى الإضافة موجود في `packages/vite/src/node/config.ts`.

[^rolldown-cs]: "OutputOptions.codeSplitting" و "Manual Code Splitting"، توثيق Rolldown — <https://rolldown.rs/reference/OutputOptions.codeSplitting> و <https://rolldown.rs/in-depth/manual-code-splitting> — شكل `groups` / `name` / `test`، وقطعة `runtime.js` الإجبارية، والالتقاط المتكرر للاعتمادات (recursive dependency capture).

[^css21911]: "Default CSS minifier in Vite\@8 blocks some progressive modern CSS features"، مشكلة vitejs/vite رقم 21911، تم فتحها في 17 مارس 2026 — <https://GitHub.com/vitejs/vite/issues/21911> — تم رفض `@scope` أثناء عملية التصغير (minification)؛ الحالة مفتوحة ومصنفة كـ `bug: upstream` وقت كتابة هذا النص.

[^css22649]: "Vite 8 default `cssMinify: 'lightningcss'` drops unprefixed `backdrop-filter`, breaking glass/blur effects (regression vs Vite 7)"، مشكلة vitejs/vite رقم 22649، تم فتحها في 9 يونيو 2026 — <https://GitHub.com/vitejs/vite/issues/22649> — تم الإبلاغ عنها في Vite 8.0.16 مع lightningcss 1.32.0؛ أُغلقت كنسخة مكررة من #21954.

[^css21954]: "`backdrop-filter` before `-webkit-backdrop-filter` is dropped with `cssMinify: 'lightningcss'`"، مشكلة vitejs/vite رقم 21954، تم فتحها في 20 نوفمبر 2025 — <https://GitHub.com/vitejs/vite/issues/21954> — الحالة مفتوحة ومصنفة كـ `bug: upstream` وقت كتابة هذا النص؛ وقد أُغلقت المشكلة #22649 بناءً عليها.

[^rolldown-tla]: "TLA in Rolldown"، توثيق Rolldown — <https://rolldown.rs/in-depth/tla-in-rolldown> — "إذا كان المدخل الخاص بك يحتوي على TLA، فيمكن تجميعه وإصداره فقط بتنسيق `esm`."

[^tla]: "فشل البناء مع top-level await في @novnc/novnc بعد التبديل إلى rolldown في إصدار 8.0.6+"، مشكلة vitejs/vite رقم 22314، تم فتحها في 23 أبريل 2026 — <https://GitHub.com/vitejs/vite/issues/22314> — الإصدار 8.0.10 يفشل بينما نجح 8.0.5؛ تم إغلاقها دون ذكر أي حل بديل في الصفحة.

[^alias]: "\[Vite 8] وضع المكتبة في `build()`: `resolve.alias` لا يعمل إلا إذا تم تضمينه في `rolldownOptions`"، مناقشة vitejs/vite رقم 22377، تم فتحها في 1 مايو 2026 — <https://GitHub.com/vitejs/vite/discussions/22377> — تم الإبلاغ عنها في Vite 8.0.10، مع الخطأ `Rolldown failed to resolve import "@/model/Alert.model"`. الإجابة المحددة هي ملاحظة المؤلف نفسه بأنه فتح المشكلة رقم 22410.

[^alias-issue]: "\[Vite 8] وضع المكتبة في `build()`: `resolve.alias` لا يعمل إلا إذا تم تضمينه في `build.rolldownOptions`"، مشكلة vitejs/vite رقم 22410، تم فتحها في 8 مايو 2026 — <https://GitHub.com/vitejs/vite/issues/22410> — تم الإبلاغ عنها في Vite 8.0.11؛ **أُغلقت على أنها غير مخططة**. تحتوي على إعادة إنتاج توضح نجاح البناء المستقل وفشل مسار معالج Cypress المسبق فقط، والخطأ `Rolldown failed to resolve import "@/foo.js"`.

[^troubleshooting]: "استكشاف الأخطاء وإصلاحها — الاستيراد الافتراضي يعيد كائنًا بشكل غير متوقع"، توثيق Vite — <https://vite.dev/guide/troubleshooting> — "الاستيراد الافتراضي يعيد كائن `module.exports` لوحدات CJS، بينما قد تتوقع أن يعيد قيمة `module.exports.default`."

[^cjs]: "تجميع CJS"، توثيق Rolldown — <https://rolldown.rs/in-depth/bundling-cjs> — قائمة الشروط الكاملة لاستيرادات `default` الغامضة من وحدات CJS، وهي أطول من الشروط الثلاثة التي يذكرها دليل هجرة Vite، واختبار `__esModule` المستخدم لفك غموض استيراد واحد.

[^storybook-cjs]: "\[Bug] NextImage renders as object with Vite 8 due to Rolldown CJS interop change", مشكلة رقم 114 في storybookjs/vite-plugin-storybook-nextjs، تم فتحها في 24 مارس 2026 — <https://GitHub.com/storybookjs/vite-plugin-storybook-nextjs/issues/114> — مثال واقعي على العرض، تم الإبلاغ عنه عبر pre-bundling التبعيات في القصص واختبارات المتصفح، مع ظهور الخطأ "Element type is invalid … but got: object" من React. تم إغلاقها مع وجود pull request مرتبط.

[^oxc-ts]: "TypeScript", توثيق Oxc Transformer — <https://oxc.rs/docs/guide/usage/transformer/TypeScript> — "يدعم Oxc transformer تحويل الـ decorators القديمة. يُطلق عليها experimental decorators في TypeScript"، وخيارات `decorator.legacy` و `decorator.emitDecoratorMetadata`، والرجوع إلى نوع `Object` لبيانات الـ decorator الوصفية.

[^features]: "Features"، توثيق Vite — <https://vite.dev/guide/features> — دعم `emitDecoratorMetadata` "مدعوم جزئياً فقط. الدعم الكامل يتطلب استنتاج النوع بواسطة مترجم TypeScript، وهو أمر غير مدعوم."

[^shared-options]: "Shared Options"، مرجع إعدادات Vite — <https://vite.dev/config/shared-options> — خيار `oxc`، الموثق على أنه يوسع خيارات Oxc Transformer.

[^es5]: "legacy: support lowering to ES5"، مشكلة رقم 21951 في vitejs/vite، تم فتحها في 17 أكتوبر 2025 — <https://GitHub.com/vitejs/vite/issues/21951> — مشكلة التتبع التي يشير إليها دليل الهجرة لـ `@vitejs/plugin-legacy`؛ مفتوحة، وتحتوي على تصحيح Babel نشره المُبلغ لـ `buildPolyfillChunk()`.

[^pnp215]: "rolldown-vite does not play well with Yarn PnP"، مشكلة رقم 215 في vitejs/rolldown-vite، تم فتحها في 4 يونيو 2025 — <https://GitHub.com/vitejs/rolldown-vite/issues/215> — مغلقة؛ يشير بنر المستودع إلى أنه تم أرشفته في 19 مارس 2026 وهو للقراءة فقط.

[^pnp392]: "Native resolver + yarn pnp: \[sass] Error: Can't find stylesheet to import.", مشكلة رقم 392 في vitejs/rolldown-vite، تم فتحها في 25 أغسطس 2025 — <https://GitHub.com/vitejs/rolldown-vite/issues/392> — مغلقة، مع طلب سحب (pull request) مرتبط في rolldown/rolldown؛ تظهر المشكلة فقط عند تفعيل الإضافات الأصلية (native plugins).

[^pnp543]: "vite 8.0.0-beta.0 cannot resolve React dependency in Yarn PnP", مشكلة رقم 543 في vitejs/rolldown-vite، تم فتحها في 5 ديسمبر 2025 — <https://GitHub.com/vitejs/rolldown-vite/issues/543> — مغلقة، مع طلب سحب (pull request) مرتبط في rolldown/rolldown.

[^oxc-resolver]: "Yarn PnP", مشكلة رقم 53 في oxc-project/oxc-resolver، تم فتحها في 12 يناير 2024 — <https://GitHub.com/oxc-project/oxc-resolver/issues/53> — مغلقة مع طلب سحب مرتبط؛ يذكر نص المشكلة أن "Yarn PnP يعمل الآن في الإصدار v11.5.0 بدون أي إعدادات."

[^pnp-vitest]: "Regression in 4.1.0-beta.4 in Yarn PnP mode, tests hanging indefinitely on Vite 8", مشكلة رقم 9799 في vitest-dev/vitest، تم فتحها في 5 مارس 2026 — <https://GitHub.com/vitest-dev/vitest/issues/9799> — مفتوحة ومصنفة كـ `upstream` وقت كتابة هذا النص؛ يحدد المُبلغ عن المشكلة تبعية اختيارية غير مُعلنة، وهي `@opentelemetry/API`، على أنها الشيء الذي يرفض strict PnP حله، ويشير إلى أن تثبيتها يحل المشكلة.

[^vite7-target]: "Build Options", مرجع إعدادات Vite 7 — <https://v7.vite.dev/config/build-options> — خيار `'baseline-widely-available'` في Vite 7 يتم حله إلى `['chrome107', 'edge107', 'firefox104', 'safari16']`.

[^resolver22322]: "Vite 8.0.10 public resolver APIs produce incomplete rolldown plugin configs", مشكلة رقم 22322 في vitejs/vite، تم فتحها في 24 أبريل 2026 — <https://GitHub.com/vitejs/vite/issues/22322> — `Missing field \`tsconfigPaths\` on BindingViteResolvePluginConfig.resolveOptions`on Astro builds via`@tailwindcss/vite\`؛ الإصدار 8.0.8 يعمل، بينما 8.0.10 معطل؛ أُغلقت المشكلة لكونها غير مخططة.

[^resolver22835]: "vite resolver broken since `8.1.0`", مشكلة vitejs/vite رقم #22835، تم فتحها في 1 يوليو 2026 — <https://GitHub.com/vitejs/vite/issues/22835> — `[MISSING_EXPORT] "placements" is not exported by "node_modules/@popperjs/core/lib/index.js"` في الإصدار 8.1.2، وتعمل في الإصدار 8.0.16؛ يشير المُبلغ إلى أنه "لا توجد مشكلة مع `npm run dev`". أُغلقت كنسخة مكررة من #22779.

[^rolldown-npm]: بيانات حزمة `rolldown`، سجل npm — <https://registry.npmjs.org/rolldown/latest> — تم التصريح عن خمسة عشر ارتباطاً (bindings) خاصة بالمنصة تحت `optionalDependencies`، ونطاق `engines` هو `^20.19.0 || >=22.12.0`.

[^binding]: "\[Bug]: rolldown-binding.linux-x64-gnu.node missing (pnpm install)", مناقشة rolldown/rolldown رقم #9098، تم فتحها في 10 أبريل 2026 — <https://GitHub.com/rolldown/rolldown/discussions/9098> — `Error: Cannot find native binding` مع `librt.so.1: cannot open shared object file`؛ لم يتم الرد عليها وقت الكتابة. محفز `engines: ">22"` هو استنتاج من أحد المعلقين، وليس تصريحاً من المطورين.

[^rolldown-ts]: "Troubleshooting"، توثيق Rolldown — <https://rolldown.rs/guide/troubleshooting> — قسم `Cannot find module '@rolldown/binding-...'`، وخطأ التبعية الاختيارية في npm (npm/cli#4828)، وحالة التكوين المرتبط رمزياً (symlinked-config) / `--preserve-symlinks` مع تحذير pnpm الخاص بها.

[^mem9330]: "\[Bug]: rolldown 1.0.0-rc.18 in vite 8 dev mode shows \~7× higher physical memory footprint vs vite 7 (rollup + esbuild)", مشكلة rolldown/rolldown رقم #9330، تم فتحها في 9 مايو 2026 — <https://GitHub.com/rolldown/rolldown/issues/9330> — مفتوحة، ومسندة، ومصنفة بـ `scope: perf` ومتابعة في لوحة "Vite 8 migration blockers"؛ حوالي 880 ميجابايت في Vite 7.3.3 مقابل حوالي 6.7 جيجابايت في Vite 8.0.11 في أحد المشاريع. يذكر المُبلغ أنه لم يقم بفحص `@vitejs/plugin-React` 4→5 بشكل منفصل وليس لديه نموذج إعادة إنتاج بسيط.

[^plugin-React-npm]: بيانات حزمة `@vitejs/plugin-React@5.2.0`، سجل npm — <https://registry.npmjs.org/@vitejs/plugin-React/5.2.0> — نطاق الـ peer لـ `vite` هو `^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0`. تم التثبيت عمدًا: الإصدارات السابقة من 5.x تتجاهل Vite 8، بينما يتطلبها إصدار v6.

[^vitest-npm]: بيانات حزمة `vitest@4.1.11`، سجل npm — <https://registry.npmjs.org/vitest/4.1.11> — نطاق الـ peer dependency لـ `vite` هو `^6.0.0 || ^7.0.0 || ^8.0.0`. تم التثبيت عمدًا: نقطة النهاية `/latest` تتغير، وإصدارات Vitest اللاحقة تضيق هذا النطاق.
