Skip to content

چرا Vite

مشکلات

قبل از اینکه ماژول‌های ES در مرورگرها در دسترس باشند، توسعه‌دهندگان مکانیزم بومی برای نوشتن جاوااسکریپت به صورت ماژولار نداشتند. به همین دلیل همه با مفهوم "bundling (بسته بندی)" آشنا هستیم: استفاده از ابزارهایی که ماژول‌های سورس کد ما را جستجو، پردازش و در فایل‌هایی که می‌توانند در مرورگر اجرا شوند، ادغام می‌کنند.

با گذشت زمان، ما ابزارهایی مانند Rollup ، webpack و Parcel را دیده‌ایم که تجربه توسعه برای توسعه‌دهندگان فرانت‌اند را بهبود بخشیده‌اند.

با این حال، همان‌طور که برنامه‌های بلندپروازانه‌تری می‌سازیم، میزان جاوااسکریپتی که با آن سروکار داریم نیز به طور چشمگیری افزایش می‌یابد. در پروژه‌های بزرگ مقیاس، داشتن هزاران ماژول غیرمعمول نیست. ما در حال رسیدن به یک گلوگاه عملکردی برای ابزارهای مبتنی بر جاوااسکریپت هستیم: اغلب ممکن است زمان انتظار غیرمعقولی (گاهی تا چند دقیقه!) طول بکشد تا یک سرور توسعه راه‌اندازی شود، و حتی با جایگزینی سریع ماژول (HMR)، ویرایش فایل‌ها ممکن است چند ثانیه طول بکشد تا در مرورگر منعکس شوند. این بازخورد کند می‌تواند به شدت بر بهره‌وری و رضایت توسعه‌دهندگان تأثیر بگذارد.

Vite هدف دارد این مشکلات را با بهره‌گیری از پیشرفت‌های جدید در اکوسیستم حل کند: در دسترس بودن ماژول‌های ES بومی در مرورگر، و ظهور ابزارهای جاوااسکریپت نوشته‌شده با زبان‌هایی که به باینری کامپایل می‌شوند.

شروع کُند سرور

وقتی سرور توسعه به صورت cold-starting اجرا می‌شود، قبل از اینکه برنامه بتواند ارائه شود باید یک راه‌اندازی ساخت مبتنی بر باندلر به طور پیش‌فرض تمام برنامه شما را پیمایش و بیلد کند.

Vite در زمان شروع، سرور توسعه را با تقسیم ماژول‌های یک برنامه به دو دسته بهبود می‌بخشد: وابستگی‌ها و سورس کد.

  • وابستگی‌ها عمدتاً جاوااسکریپت ساده هستند که در طول توسعه تغییر نمی‌کنند. برخی وابستگی‌های بزرگ (مثلاً کتابخانه‌های کامپوننت با صدها ماژول) نیز دارای پردازش بسیار گران هستند. وابستگی‌ها ممکن است در انواع مختلف فرمت‌های ماژول (مثلاً ESM یا CommonJS) ارائه شوند.

    Vite با استفاده از esbuild می‌تواند وابستگی‌ها را پیش‌باندل کند. esbuild با زبان Go نوشته شده و وابستگی‌ها را 10 تا 100 برابر سریع‌تر از باندلرهای مبتنی بر جاوااسکریپت پیش‌باندل می‌کند.

  • سورس کد اغلب حاوی جاوااسکریپت غیر‌ساده‌ای است که نیاز به تبدیل دارد (مثلاً JSX ، CSS یا کامپوننت‌های Vue/Svelte)، و بسیار زیاد ویرایش می‌شود. همچنین، نیازی نیست تمام سورس کد به طور همزمان بارگذاری شود (مثلاً با تقسیم کد مبتنی بر مسیر).

    Vite سورس کد را از طریق ESM بومی ارائه می‌دهد. این اساساً اجازه می‌دهد تا مرورگر بخشی از کار یک باندلر را انجام دهد: Vite فقط نیاز دارد سورس کد را بر اساس تقاضا تبدیل کند و سرویس دهد، همان‌طور که مرورگر آن را درخواست می‌کند. کدی که پشت ایمپورت داینامیک شرطی است تنها در صورت استفاده واقعی در صفحه فعلی پردازش می‌شود.

Bundle based dev server entry ··· route route module module module module ··· Bundle Server ready
Native ESM based dev server entry ··· route route module module module module ··· Server ready Dynamic import (code split point) HTTP request

به‌روزرسانی‌های کند

وقتی یک فایل در یک راه‌اندازی ساخت مبتنی بر باندلر ویرایش می‌شود، بازسازی کل باندل به یک دلیل واضح ناکارآمد است: سرعت به‌روزرسانی به صورت خطی با اندازه برنامه کاهش می‌یابد.

در برخی باندلرها، سرور توسعه باندلینگ را در حافظه (memory) انجام می‌دهد تا فقط نیاز باشد بخشی از گراف ماژول خود را هنگام تغییر یک فایل نامعتبر کند، اما همچنان نیاز است کل باندل را بازسازی کرده و صفحه وب را دوباره بارگذاری کند. بازسازی باندل می‌تواند پرهزینه باشد، و بارگذاری مجدد صفحه وضعیت فعلی برنامه را از بین می‌برد. به همین دلیل است که برخی باندلرها از جایگزینی سریع ماژول (Hot Module Replacement (HMR)) پشتیبانی می‌کنند: اجازه می‌دهد یک ماژول بدون تأثیر بر بقیه صفحه به صورت "سریع" جایگزین شود. این به طور قابل توجهی تجربه توسعه (DX) را بهبود می‌بخشد - با این حال، در عمل ما متوجه شده‌ایم که حتی سرعت به‌روزرسانی HMR نیز با رشد اندازه برنامه به طور قابل توجهی کاهش می‌یابد.

در Vite، عملیات HMR بر روی ESM بومی انجام می‌شود. وقتی فایلی ویرایش می‌شود، Vite تنها زنجیره‌ی بین ماژول ویرایش‌شده و نزدیک‌ترین مرز HMR را نامعتبر می‌کند (که معمولاً فقط خود ماژول است). این فرآیند باعث می‌شود که به‌روزرسانی‌های HMR، بدون توجه به اندازه‌ی برنامه، همواره با سرعت بالا انجام شوند.

Vite همچنین از هدرهای HTTP برای سرعت بخشیدن به بارگذاری مجدد کامل صفحه استفاده می‌کند (باز هم، اجازه دهید مرورگر کار بیشتری برای ما انجام دهد): درخواست‌های ماژول سورس کد به‌صورت مشروط با وضعیت 304 Not Modified انجام می‌شوند، در حالی که ماژول‌های وابستگی با هدر Cache-Control: max-age=31536000, immutable به‌شدت کش می‌شوند. به همین دلیل، پس از یک‌بار کش شدن، دیگر نیازی به ارسال درخواست به سرور ندارند.

پس از تجربه سرعت Vite، بعید است که بخواهید دوباره به توسعه مبتنی بر باندل برگردید.

چرا برای پروداکشن باندل کنیم

حتی با وجود اینکه ESM بومی اکنون به طور گسترده پشتیبانی می‌شود، به دلیل رفت‌و‌آمدهای اضافی شبکه که توسط ایمپورت‌های تودرتو ایجاد می‌شود، ارسال ESM بدون باندل در محیط پروداکشن همچنان ناکارآمد است (حتی با HTTP/2) . برای دستیابی به بهترین عملکرد بارگذاری در پروداکشن، همچنان بهتر است کد خود را با استفاده از tree-shaking، بارگذاری تنبل (lazy-loading) و تقسیم‌بندی بخش‌های مشترک (برای بهبود کش) باندل کنید.

اطمینان از خروجی بهینه و سازگاری رفتاری بین سرور توسعه و بیلد ساخته شده برای پروداکشن آسان نیست. به همین دلیل است که Vite با یک کامند بیلد از پیش پیکربندی‌شده ارائه می‌شود که بسیاری از بهینه‌سازی‌های عملکرد را به صورت پیش‌فرض در خود دارد.

چرا با esbuild باندل نکنیم؟

در حالی که Vite از esbuild برای پیش‌باندل کردن برخی وابستگی‌ها در زمان توسعه استفاده می‌کند، Vite از esbuild به عنوان یک باندلر برای بیلدهای پروداکشن استفاده نمی‌کند.

API فعلی پلاگین Vite با استفاده از esbuild به عنوان باندلر سازگار نیست. با وجود اینکه esbuild سریع‌تر است، پذیرش API انعطاف‌پذیر پلاگین و زیرساخت Rollup توسط Vite به موفقیت آن در اکوسیستم کمک بزرگی کرده است. در حال حاضر، ما معتقدیم که Rollup توازن بهتری بین عملکرد و انعطاف‌پذیری ارائه می‌دهد.

Rollup همچنین در حال کار بر روی بهبودهای عملکردی است، تغییر پارسر خود به SWC در نسخه 4 و تلاش‌هایی در حال انجام است برای ساخت نسخه‌ای به زبان Rust از Rollup به نام Rolldown. زمانی که Rolldown آماده شود، می‌تواند هر دو Rollup و esbuild را در Vite جایگزین کند، عملکرد بیلد را به طرز قابل توجهی بهبود بخشد و ناسازگاری‌های بین توسعه و بیلد را از بین ببرد. می‌توانید سخنرانی کلیدی Evan You در ViteConf 2023 برای جزئیات بیشتر تماشا کنید.

Vite چگونه با سایر ابزارهای ساخت بدون باندل مقایسه می‌شود؟

ابزار WMR که توسط تیم Preact توسعه داده شده بود، هدفش ارائه مجموعه‌ای از قابلیت‌های مشابه با Vite بود. رابط افزونه‌ی مشترک Vite برای محیط توسعه و ساخت (build) از WMR الهام گرفته است. اما WMR دیگر پشتیبانی نمی‌شود و تیم Preact اکنون استفاده از Vite همراه با بسته‌ی ‎@preactjs/preset-vite را پیشنهاد می‌دهد.

Snowpack نیز یک سرور توسعه ESM بومی بدون باندل بود که بسیار شبیه به Vite بود. پیش‌باندل کردن وابستگی‌های Vite نیز از Snowpack v1 (اکنون esinstall) الهام گرفته شده است. Snowpack دیگر نگهداری نمی‌شود. تیم Snowpack اکنون روی Astro کار می‌کند، یک سازنده سایت استاتیک که از Vite قدرت گرفته است.

پروژه ‎@web/dev-server (که قبلاً با نام es-dev-server شناخته می‌شد) یکی از پروژه‌های عالی است که معماری سرور مبتنی بر Koa در Vite نسخه 1.0 از آن الهام گرفته شده است. پروژه‌ی جامع ‎@web به‌صورت فعال نگهداری می‌شود و شامل ابزارهای فوق‌العاده‌ی دیگری نیز هست که می‌توانند برای کاربران Vite مفید باشند.

تحت مجوز MIT منتشر شده. (dev)