Skip to content

پیش‌بسته‌بندی(پیش‌باندل) وابستگی

زمانی‌که شما vite را برای اولین بار اجرا می‌کنید Vite وابستگی‌های پروژه شما را قبل از لود لوکال سایت شما، پیش‌بسته‌بندی می‌کند. این فرایند به صورت پیشفرض، اتوماتیک و شفاف انجام می‌شود.

چرایی

این چیزی‌است که در Vite "پیش‌بسته‌بندی وابستگی" می‌نامیم. این فرایند دو هدف دارد:

  1. سازگاری CommonJS and UMD: در زمان توسعه، در حالت Vite dev تمام کدها به شکل ماژول native ESM آماده می‌شوند. پس Vite باید وابستگی‌هایی که به شکل CommonJs یا UMD هستند را ابتدا به ESM تبدیل کند.

    زمانی که Vite دارد وابستگی‌های CommonJsای را تبدیل می‌کند، آنالیز هوشمندانه‌ی import را اجرا می‌کند تا importهای نامگذاری شده‌ی ماژول‌های CommonJS همانطور که انتظار می‌رود بتوانند کار کنند حتی اگر export ها به صورت داینامیک نسبت داده شده باشند (مانند React):

    js
    // مطابق انتظار کار می‌کند
    import React, { useState } from 'react'
  2. بازدهی: Vite وابستگی‌های ESM با ماژول‌های داخلی بسیار را تبدیل به یک ماژول می‌کند تا بازدهی‌ لودهای بعدی صفحه را بهبود دهد.

    بعضی از پکیج‌ها، ماژول‌های ES خود را به شکل چندین فایل جداگانه که یکدیگر را import کرده‌اند بیلد کرده و همراه خود می‌آورند. برای مثال، lodash-es بیش از ۶۰۰ ماژول داخلی دارد! وقتی ما این کار را می‌کنیمimport { debounce } from 'lodash-es'‎، مرورگر بیش از ۶۰۰ درخواست HTTP را همزمان ارسال می‌کند! حتی با وجود اینکه سرور مشکلی با هندل کردن آنها ندارد، تعداد زیاد درخواست‌ها باعث ازدحام در سمت مرورگر می‌شود که همین امر باعث کندتر لود شدن صفحه به شکل قابل‌ ملاحظه‌ای می‌گردد.

    به جای این، با پیش‌بسته‌بندیِ lodash-es در یک ماژول حالا ما تنها به یک HTTP درخواست نیاز داریم!

نکته

پیش‌بسته‌بندی وابستگی فقط در حالت توسعه(development) اعمال می‌شود و از esbuild برای تبدیل وابستگی‌ها به ESM استفاده می‌شود. در حالت production به جای آن از ‎@rollup/plugin-commonjs استفاده می‌شود.

یافتن خودکار وابستگی

اگر کشی موجود نباشد، Vite کد شما را می‌کاود و به صورت اتوماتیک وابستگی‌های importها را پیدا می‌کند(مانند "bare imports" که انتظار می‌رود از node_modules خوانده شود) و از این importهای پیدا شده به عنوان نقاط ورودی پیش‌بسته‌بندی استفاده کند. فرایند پیش‌بسته‌بندی از esbuild استفاده می‌کند پس معمولا بسیار سریع است.

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

مخزن یکپارچه (Monorepos) و وابستگی‌های مرتبط(Linked Dependencies)

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

گرچه، این امر نیازمند این است که وابستگی مرتبط به صورت ESM export شده باشد. اگر به این شکل نبود شما می‌توانید وابستگی را در تنظیماتتان به optimizeDeps.includeوbuild.commonjsOptions.include اضافه کنید.

vite.config.js
js
export default 
defineConfig
({
optimizeDeps
: {
include
: ['linked-dep'],
},
build
: {
commonjsOptions
: {
include
: [/linked-dep/, /node_modules/],
}, }, })

هنگامی که تغییراتی در وابستگیِ مرتبط می‌دهید، dev server را با قابلیت دستور ‎--force ریست کنید تا تغییرات اعمال شوند.

اختصاصی‌کردن رفتار

روش‌های پیشفرض کشف وابستگی ممکن است همیشه مطلوب نباشند. در مواردی که شما مشخصا می‌خواهید وابستگی ها را از لیست include/exclude کنید از optimizeDeps config options استفاده کنید.

یک مورد مرسوم برای optimizeDeps.include یا optimizeDeps.exclude زمانی است که شما یک importای دارید که مستقیما قابل کشف در سورس کد نیست. برای مثال، شاید آن import در نتیجه‌ی تغییر پلاگینی بوجود آمده است. این به این معنا است که Vite قادر به یافتن آن import در اسکن اولیه نخواهد بود - بلکه تنها زمانی که توسط مرورگر درخواست داده شود و تغییر(transformed) پیدا کند قابل مشاهده می‌گردد. این موضوع باعث می‌شود سرور بلافاصله بعد از شروع، دوباره بسته‌بندی را انجام دهد.

هر دو حالت include و exclude می‌توانند برای این هدف مورد استفاده قرار گیرند. اگر وابستگی بزرگ باشد (به همراه ماژول‌های داخلی بسیاری) یا CommonJS باشد، پس شما باید آنرا include کنید؛ اگر وابستگی کوچک است و همین حالا هم ماژول ESM معتبری است، می‌توانید آنرا exclude کنید و اجازه دهید که مرورگر مستقیما آن‌ را لود کند.

همچنین شما می‌توانید esbuild را بیشتر نیز با قابلیتoptimizeDeps.esbuildOptions سفارشی‌سازی کنید. برای مثال، اضافه کردن یک پلاگین esbuild برای هندل کردن فایل‌های مخصوص در وابستگی‌ها یا تغییر build target.

کش‌کردن

کش فایل‌سیستم (File System)

Vite وابستگی‌های پیش‌بسته‌بندی را در node_modules/.vite کش می‌کند. Vite اینکه نیاز به اجرای مجدد مرحله پیش‌بسته‌بندی هست یا نه را بر اساس چند منبع تشخیص می‌دهد:

  • محتوای package manager lockfile مثل: package-lock.json, yarn.lock, pnpm-lock.yaml یا bun.lockb.
  • زمان تغییر پوشه patches.
  • فیلدهای مرتبط در vite.config.js، در صورت وجود.
  • مقدار NODE_ENV.

مرحله پیش‌بسته‌بندی تنها زمانی نیاز به اجرای مجدد دارد که یکی از موارد بالا تغییر کرده باشد.

اگر به دلایلی می‌خواهید که Vite را مجبور به انجام پیش‌بسته‌بندی وابستگی‌ کنید، یا می‌توانید سرور dev را با گزینه دستور ‎--force اجرا کنید یا اینکه فایل node_modules/.vite پوشه کش را به صورت دستی پاک کنید.

کش مرورگر

فراخوانی درخواست‌های وابستگی به خوبی با هدرهای HTTP max-age=31536000,immutable کش می‌شوند تا بازدهی بارگیری مجدد صفحه در حالت dev افزایش پیدا کند. وقتی که کش شدند، این درخواست‌ها دیگر هرگز به سرور dev ارسال نمی‌شوند. آنها زمانی که یک نسخه دیگر نصب شود به صورت خودکار با اضافه شدن ورژن کوئری (version query) ، غیرمعتبر می‌شوند(همانند آنچه که در لاک‌فایل پکیج منیجر شما دیده می‌شود). اگر می‌خواهید که وابستگی‌های خود را با تغییرات لوکال دیباگ کنید می‌توانید:

  1. غیرفعال کردن موقت کش در تب Network در devtools مرورگر خود؛
  2. اجرای مجدد سرور dev با علامت ‎--force برای پیش‌بسته‌بندی مجدد وابستگی‌ها؛
  3. بارگیری مجدد صفحه

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