ابزار vite (با تلفظ «ویت» یا /vit/)، یک ابزار ساخت (build tool) برای پروژه های frontend می باشد. واژه ی vite در فرانسوی به معنای «سریع» است. همان طور که از نامش پیداست، این ابزار آمده تا پروژه های سمت کاربر سبک تر و فرایند توسعه ی آن ها سریع تر شود. vite از دو بخش اصلی تشکیل شده:
- یک سرور توسعه ی (dev server) سریع که بر پایه ی native ESmodule طراحی شده و در آن بسیاری از قابلیت هایی که bundler ها در اختیار قرار می دادند بهبود یافته.
- یک دستور ساخت (build command) که خود به وسیله ی ابزار Rollup کد را bundle می کند. این دستور از قبل به گونه ای پیکربندی شده، که دارایی های ایستای پروژه (static assets) را به نحوی خروجی دهد که برای حالت production بهینه شده باشند.
علیرغم اینکه vite تنظیمات و پیکربندی های پیش فرض مناسبی دارد، دست کاربران را برای توسعه و سفارشی سازی خود باز گذاشته است. vite این کار را با استفاده از PluginAPI و Javascript API انجام می دهد.
Vite چنین نامی روی خود گذاشته است: «نسل جدید ابزار های frontend»
یکی از مهم ترین مزایای استفاده از vite، در اختیار قرار دادن یک سرور توسعه ی سریع است. قبل از هر چیز اجازه دهید کمی درباره ی مفهوم سرور توسعه صحبت کنیم.
سرور توسعه چیست؟
سرور توسعه (یا development server) سروریست که تمامی ویژگی های لازم برای آزمایش و خطایابی برنامه ی ما را داراست. توسعه دهندگان هنگام توسعه ی اپلیکیشن خود، یک سرور توسعه راه می اندازند تا از طریق آن تمامی رفتار های پروژه را بررسی و خطایابی کنند. این سرور توسعه چیزی شبیه به سروریست که در واقعیت قرار است اپلیکیشن نهایی روی آن بالا بیاید و روی host قرار بگیرد. سرور توسعه که معمولاً به صورت داخلی و روی سیستم توسعه دهنده ها راه اندازی می شود (localhost)، معمولاً تمامی ویژگی های نرم افزاری و متغیر های محیطی زمان اجرا و هر چیزی که برای آزمایش اپلیکیشن لازم باشد را در اختیار قرار می دهد.
نقطه مقابل سرور توسعه، سرور محصول (یا production server) است. سرور محصول در واقع همان سرور اصلی برنامه ی ماست که در بالا ذکر کردیم. سروری که کاربران ما با آن تعامل می کنند و برنامه ی ما به آن متصل است سرور محصول نامیده می شود.
بنابراین سرور توسعه ابزاریست که کمک بسیار زیادی به فرایند توسعه ی اپلیکیشن های frontend می کند. اما برای این که سرور توسعه بتواند برنامه را serve کند، نیاز است که کد برنامه build شده باشد. حال روش های مختلفی برای build کردن برنامه وجود دارد. برخی ابزار ها کد برنامه را bundle می کنند (bundler-based build setup) و برخی دیگر آن را bundle نمی کنند (no-bundle build).
Vite ابزاریست که سرور توسعه را به روش دوم، یعنی به روش no-bundle راه اندازی می کند. این کار آن قدر بهینه است که سرعت راه اندازی سرور توسعه و به روزرسانی آن را به طور قابل توجهی افزایش می دهد. (البته اگر بخواهیم دقیق تر به موضوع نگاه کنیم، vite نیز در فرایند راه اندازی سرور توسعه برخی ماژول ها را bundle می کند، اما در مجموع به چنین ابزار هایی no-bundle گفته می شود که در نقطه مقابل bundler های سنتی قرار می گیرند)
داستان از کجا شروع شد؟
توسعه دهندگان برای ایجاد اپلیکیشن خود، کد هایشان را در قالب module می نوشتند، یا از پکیج ها و کتابخانه هایی استفاده می کردند که کدهایشان به صورت module بود.
اما تا قبل از اینکه ES modules توسط مرورگر ها پشتیبانی شود، توسعه دهندگان هیچ راه حل بومی ای برای نوشتن کد جاوااسکریپت خود به صورت ماژولار نداشتند. بنابراین باید قبل از اجرای کدشان در مرورگر، آن را از حالت modular به حالتی تبدیل می کردند که برای مرورگر قابل فهم باشد. و این همان موضوعی بود که توسعه دهندگان را وادار می کرد از ابزاری به نام bundler استفاده کنند.
اما bundler ها چه بودند؟ ابزار هایی بودند که کد های نوشته شده توسط توسعه دهنده را بررسی، پردازش و به هم ملحق می کردند و در نهایت آن ها را به شکل فایل کد هایی در می آوردند که می توانست در مرورگر اجرا شود.
در طی سالیان اخیر هم bundler های قدرتمندی مانند webpack، rollup و parcel به توسعه دهندگان frontend کمک می کردند تا مشکل بالا را حل کنند.
اما به مرور زمان و وقتی با پروژه های سنگین تر و بزرگ تری سر و کار داشتیم، حجم کد جاوااسکریپتی که در پروژه ی ما بود به صورت قابل توجهی افزایش می یافت. پروژه های در مقیاس بزرگ تا هزاران module را در خود جای می دادند و این باعث می شد فرایند توسعه کند شود. اگر خودتان تجربه ی توسعه ی اپلیکیشن های frontend را داشته باشید، حتماً این موضوع را به چشم دیده اید که راه اندازی یک سرور توسعه برای اجرا و آزمایش برنامه تان، زمان زیادی از شما گرفته باشد. موضوعی که امروزه به یک گلوگاه در فرایند توسعه ی اپلیکیشن های frontend تبدیل شده است. تا آنجا که گاهی راه اندازی یک سرور توسعه ممکن است دقایقی طول بکشد، یا حتی فرایند HMR (Hot Module Replacement) نیز با ثانیه هایی تأخیر اتفاق بیفتد و مجموعه ی این تأخیر ها، عملکرد و شادابی توسعه دهنده را تحت تأثیر قرار دهد.
در این بین vite وارد میدان شده تا با بهره گیری از پیشرفت های جدیدی که در زیست بوم وب رخ داده، این مشکل را حل کند. این تغییرات جدید عبارتند از:
- این موضوع که مرورگر ها از ES modules پشتیبانی می کنند (در صورتی که قبلاً چنین امکانی وجود نداشت)
- ظهور ابزارهای جاوااسکریپتی که با زبان های compile-to-native نوشته شده اند.
Vite مشکل شروع کند سرور توسعه را چگونه حل می کند؟
Vite راه اندازی سرور توسعه را با تقسیم کردن ماژول های برنامه به دو بخش وابستگی ها (dependencies) و کد منبع (source code) انجام می دهد.
- وابستگی ها: وابستگی ها آن دسته کدهایی هستند که به صورت جاوااسکریپت خام نوشته شده اند و معمولاً در حین توسعه ی برنامه دچار تغییر نمی شوند. می دانیم که پردازش و تحلیل پکیج های بزرگ وابستگی برنامه (مثل کتابخانه ی کامپوننت ها که خود می توانند تا صد ها ماژول داشته باشند)، کار زمان بر و پرهزینه ایست، از طرفی این وابستگی ها ممکن است ساختار ماژول های مختلفی نیز داشته باشند(مثلاً ESM یا CommonJS باشند). همه ی این ها باعث می شود که فرایند پردازش چنین فایل هایی زمان بر شود.
برای حل این مشکل، Vite این وابستگی ها را با استفاده از پکیج esbuild از قبل bundle (pre-bundle) می کند. ابزار esbuild که با زبان Go نوشته شده، قادر است وابستگی ها را با سرعتی بین 10 تا 100 برابر bundler های جاوااسکریپتی pre-bundle کند.
2. کد منبع: این دسته کد ها معمولاً کد هایی هستند که معمولاً با جاوااسکریپت خام نوشته نشده اند و برای اجرا نیاز به تبدیل شدن دارند. کد هایی مثل JSX، CSS، کامپوننت های Vue یا Svelte و ... . از طرفی vite تمامی کد های منبع را به یکباره بارگذاری نمی کند و عملیات بارگذاری آنها را به زمانی موکول می کند که برنامه به آنها نیاز داشته باشد (مثلاً کد ها را به بخش های مختلفی تقسیم بندی می کند، و هر بار که کاربر در مسیر خاصی به آن کد نیاز داشت، آن را بارگذاری می کند، اتفاقی که در route-based code splitting می افتد)
از آنجایی که امروزه بیشتر مرورگر ها از ESM به صورت بومی پشتیبانی می کنند، vite کد ها را در قابل ESM به مرورگر می دهد و بقیه ی فرایند اجرای کد با مرورگر خواهد بود. به این ترتیب بخشی از فرایند ساخت کد که قبلاً از طریق bundler انجام می گرفت، به مرورگر سپرده می شود و همین موضوع نیز به بهینگی فرایند کمک خواهد کرد.
از طرفی همان طور که گفتیم، Vite کد های منبع را زمانی تبدیل می کند و در اختیار مرورگر قرار می دهد که مرورگر به آن نیاز داشته باشد و آن ها را درخواست دهد.
تصاویر زیر، مقایسه ی بین نحوه ی serve کردن ماژول های یک سرور توسعه به دو روش bundle-based و ESM بومی را نمایش می دهد:
همان طور که می بینید، یک ساخت bundle-based قبل از serve کردن برنامه، نیاز دارد تا تمام ماژول های برنامه را بررسی و تحلیل کند و آن ها را bundle کند، اما با روش تبدیل ماژول ها به ESM بومی، کار به نحو بهینه تری انجام می شود.
Vite مشکل کند بودن فرایند به روزرسانی سرور توسعه را چگونه حل می کند؟
فرض کنید در حال توسعه ی اپلیکیشنی هستیم و یک سرور توسعه داریم که به روش bundle-based ایجاد شده است. وقتی در حین فرایند توسعه، محتوای یکی از فایل ها را تغییر می دهیم تا تغییرات اعمال شده به ازای آن را در برنامه ببینیم، نیاز است که کل اپلیکیشن مجدداً bundle شود. واضح است که با بزرگ تر شدن اپلیکیشن، این فرایند زمان بیشتری به طول می انجامد.
برای حل این مشکل، bundler ها فرایند bundle کردن در RAM سیستم اجرا می کردند، به این ترتیب به ازای تغییر یک فایل، تنها نیاز بود که بخشی از گراف ماژول های آنها تغییر کند. این موضوع کمی زمان بازسازی پروژه را بهبود می داد، اما هنوز لازم بود که bundler ها کل اپلیکیشن را مجدداً bundle کنند و صفحه مجدداً لود شود. (صفحه refresh شود)
برای حل این مشکل نیز bundler ها از تکنولوژی HMR یا Hot Module Replacement استفاده کردند، به این ترتیب که اجازه می دادند ماژولی که تغییر کرده، بدون تغییر سایر بخش های پروژه، جایگزین حالت قبلی اش شود. اما با این وجود نیز سرعت مطلوب اتفاق نمی افتاد، چرا که با بزرگتر شدن اپلیکیشن، سرعت فرایند HMR نیز کاهش می یافت.
اما vite فرایند HMR را با بر پایه ی native ESM پیاده کرده است. وقتی یک فایل تغییر می کند، vite تنها لازم است زنجیره ی بین ماژول تغییر یافته و نزدیک ترین مرز HMR را تغییر دهد. روشی که باعث می شود فرایند HMR صرف نظر از حجم اپلیکیشن، همواره سرعت بالایی داشته باشد.
Vite همچنین با استفاده از http header ها، کاری می کند که بارگذاری مجدد کل صفحه نیز بهینه شود. (و به این ترتیب مجدداً از قابلیت های مرورگر برای بهینه تر کردن فرایند توسعه استفاده می کند)
برای این کار، درخواست هایی که برای دریافت کد های منبع ارسال می شود، با استفاده از کد وضعیت (304 Not Modified) به حالت مشروط (conditional) در می آید. از طرفی درخواست برای دریافت ماژول های وابستگی با تنظیم Cache-Control: max-age=31536000,immutable
کَش می شود و به این ترتیب دیگر نیازی به مشغول کردن سرور توسعه برای دریافت مجدد آنها نیست.
Vite در build کردن پروژه روی سرور محصول چه ملاحظاتی دارد؟
خوب است بدانیم علیرغم اینکه امروزه بسیاری از مرورگر ها از ESM به صورت بومی پشتیبانی می کنند، هنوز پیاده کردن سرور محصول با کد bundle نشده کار بهینه ای نیست. چرایی این موضوع به لزوم درخواست های رفت و برگشتی زیادی بر می گردد که به دلیل import های تو در تو ناچار به ارسال آنها هستیم. به همین دلیل هنوز هم بهترین روش برای پیاده سازی یک سرور محصول با کارآیی و سرعت بالا، bundle کردن کد با استفاده از درخت تکانی (tree shaking)، بارگذاری تنبل (lazy-loading) و تقسیم بندی کد به بخش های مختلف است. جا دارد اشاره کنیم از آنجا که esbuild هنوز برخی قابلیت هایی که برای bundle کردن کلیه ی اپلیکیشن ها مورد نیاز است را ندارد، vite نیز برای bundle کردن محصول نهایی از این پکیج استفاده نمی کند.
اما همان طور که پیش تر هم گفتیم، Vite برای پیاده سازی روی سرور محصول دستور مخصوصی در اختیار قرار می دهد که بهینه سازی های زیادی روی آن انجام گرفته است.
در مجموع می توان گفت که vite یک محیط توسعه (development environment) است. البته این ابزار بی رقیب نیست و ابزار هایی چون WMR ،Snowpack و web/dev-server@ کار های مشابهی انجام می دهند. برای مشاهده ی تفاوت ها و مقایسه ی این ابزار ها، می توانید به این صفحه از مستند رسمی سایت vite مراجعه کنید.
برای شروع و مشاهده ی نحوه ی راه اندازی پروژه با استفاده از این ابزار، می توانید به صفحه ی رسمی ابزار vite مراجعه کنید. ما نیز در ادامه ی همین مقاله یک پروژه ی ساده را با vite راه اندازی کرده ایم.
Vite از چه فناوری هایی پشتیبانی می کند؟
ابزار vite قالب های آماده ای دارد که از طریق آن ها می توان با فریم ورک های مختلف پروژه ایجاد کرد. این قالب های از پیش آماده شده، برای راه اندازی پروژه با زبان ها و فریم ورک هایی از این دست در اختیار کاربران قرار گرفته:
- vanilla
- vanilla-ts
- vue
- vue-ts
- react
- react-ts
- preact
- preact-ts
- lit-element
- lit-element-ts
- svelte
- svelte-ts
پشتیبانی از SSR، JSX، TSX، وارد کردن فایل های CSS و پیش پردازنده های آن به برنامه، Typescript و دارایی های پایایی مانند عکس ها و فایل های json از جمله قابلیت های این ابزار نوظهور هستند.
توسعه دهنده ی ابزار vite چه کسیست؟
خالق ابزار vite نام آشنایی برای برنامه نویسان frontend دارد، ایوان یو (Evan You) که همان خالق فریم ورک محبوب vue.js است.
او برای اولین بار در آپریل 2020 و در توییتی، درباره ی ایده ی خود که پیاده سازی یک ابزار no-bundler بود صحبت کرد:
به مرور این ایده بزرگ و بزرگ تر شد و ابزار vite کامل و کامل تر شد. اخیراً نیز نسخه ی دوم این ابزار، به عنوان اولین نسخه ی پایدار آن معرفی شده است. امروزه جامعه ی کاربران و دنبال کنندگان vite روز به روز در حال افزایش است، امری که نویدبخش آینده ای روشن برای آن خواهد بود.
راه اندازی یک اپلیکیشن ساده با vite
در این مقاله بیشتر سعی داشتیم که ابزار vite را معرفی کنیم. اما به عنوان یک نمونه ی کوچک، اپلیکیشنی ساده را با استفاده از vite راه می اندازیم:
قبل از هر چیز دقت داریم از آنجا که برای راه اندازی پروژه از npm استفاده می کنیم، باید این ابزار بر روی سیستم عامل ما نصب باشد. همان طور که می دانیم این ابزار با نصب node.js بر روی سیستم عامل، به صورت خودکار نصب می شود (البته اگر هنگام نصب node.js صراحتاً نصب npm را غیرفعال نکرده باشیم). پس از اطمینان یافتن از اینکه npm بر روی سیستم عامل ما نصب است، مراحل زیر را به ترتیب پی می گیریم:
- ابتدا در مسیر دلخواه خود ترمینالی باز کرده و دستور زیر را اجرا می کنیم: (به عنوان مثال ما در مسیری به نام test vite دستور زیر را اجرا می کنیم)
- نام پروژه (Project name)
npm init @vitejs/app
این دستور مراحل ایجاد یک پروژه بر اساس vite را آغاز می کند. در ابتدا npm از ما می خواهد که اجازه دهیم پکیج vitejs/create-app@ را که برای ایجاد پروژه مورد نیاز است نصب کند. پس از نصب این پکیج، دستور create-app که دستور ایجاد پروژه ی vite است اجرا می شود و در هر مرحله از ما سوالاتی می پرسد که پیکربندی پروژه را مشخص خواهد کرد:
- نوع فریم ورک مورد استفاده:
به عنوان مثال ما در این مرحله یک پروژه ی ساده ی جاوااسکریپتی (vanilla) بدون هیچ فریم ورکی را انتخاب کرده ایم.
- انتخاب جاوااسکریپت یا typescript:
ما در این مرحله گزینه ی vanilla را انتخاب کردیم. با انتخاب این گزینه پیام زیر برای ما نمایش داده می شود:
- حال همان طور که در پیام بالا راهنمایی شده ایم، به مسیر vite-project می رویم و مشاهده می کنیم که vite برایمان چارچوبه ی کدی مانند تصویر زیر ساخته است:
- در این مرحله با زدن دستور
npm install
پکیج هایی که در فایل package.json لیست شده است را نصب می کنیم. - پس از نصب پکیج ها، پروژه آماده ی توسعه است. پس دستور
npm run dev
را می زنیم و از فرایند توسعه لذت می بریم. با این کار vite برای ما یک سرور توسعه روی پورت 3000 ایجاد می کند که می توانیم با باز کردن مرورگر و رفتن به آدرس http://localhost:3000 خروجی پروژه را ببینیم:
آیا از ابزار vite استفاده کنیم؟
با وجود اینکه vite جهش هایی جدی در عملکرد و سرعت توسعه ایجاد می کند، اما هنوز بعضی ویژگی های آن به بلوغ کامل نرسیده. به عنوان مثال vite از server side rendering (رندر برنامه سمت سرور) پشتیبانی می کند، اما هنوز کاستی هایی دارد که برای تکمیل شدن نیازمند زمان هستند. به عنوان مثال Nuxt که ابزاری محبوب در حوزه ی فرانت اند محسوب می شود، اخیراً نسخه ی 3 (برچسب beta) خود را معرفی کرده و در آن از vite به عنوان bundler استفاده می کند.
با این توضیحات اگر می خواهید محصول خودتان را با استفاده از این ابزار توسعه دهید، از قبل اطمینان حاصل کنید که پاسخگوی تمامی نیاز های برنامه ی شما خواهد بود، چرا که برخی قابلیت های vite، هم چنان در دست توسعه هستند. اما دست کم برای آزمایش و لذت بردن از سرعت ویژه ی این ابزار، پیشنهاد می کنیم دفعه ی بعد که قصد داشتید یک برنامه ی frontend ایجاد کنید، از vite استفاده کنید و در کنار آن، حتماً نگاهی به مستند رسمی vite بیندازید!
به آن دسته از کاربران عزیز سکان آکادمی هم که می خواهند دانش عمیق تر و دقیق تری درباره ی این ابزار داشته باشند، پیشنهاد می کنیم این بخش از کنفرانس Vue contributor days را مشاهده کنند.
سلامت و پیروز باشید