یک رقیب رقیب زمان اجرا جاوا اسکریپت وارد نبرد بین Node.js و Deno شده است. در این مقاله، نگاهی اولیه به Bun انداخته ایم و دلایلی که ممکن است شما را از مورد علاقه فعلی خود وسوسه کند.
رایان دال Node.js را در سال ۲۰۰۹ منتشر کرد. این اولین زمان اجرای جاوا اسکریپت سمت سرور نبود، اما Node.js به سرعت شتاب بیشتری گرفت. نسخه ۲۰ در سال ۲۰۲۳ وارد بازار شد و Node.js بزرگترین اکوسیستم توسعه را با ۳.۲ میلیون ماژول دارد - تقریباً ۵۰۰ میلیارد بارگیری در هفته (طبق گزارش npmjs.com).
در سال ۲۰۲۰، رایان دال Deno را منتشر کرد - ریمیکسی از "noDe" - برای مدرن کردن توسعه جاوا اسکریپت و رسیدگی به مشکلات قدیمی با امنیت Node.js، سازگاری API، ابزار و مدیریت ماژول. استقبال مثبت بوده است، اگرچه Deno هنوز تسلط Node را به چالش نکشیده است.
در سال ۲۰۲۲، جارد سامنر به دنبال ناامیدی خود از سرعت Node.js هنگام توسعه پروژه Next.js، Bun را منتشر کرد. منشا نام نامشخص است و لوگو کمکی نمی کند! این می تواند مربوط به غذا، خرگوش های کرکی، "بسته" باشد، یا شاید یک نام کوتاه و به یاد ماندنی باشد و دامنه bun.sh در دسترس بود.
هدف: Bun جایگزینی برای Node.js، Deno، جاوا اسکریپت بدون سرور و ابزارهایی مانند webpack، Babel و Yarn خواهد شد. به جای اجرای npm start
برای راه اندازی اسکریپت Node خود، می توانید bun start
اجرا کنید و از سرعت Bun بهره ببرید.
فواید نان خوشمزه
Node.js و Deno از موتور جاوا اسکریپت V8 کروم استفاده می کنند. Bun موتور JavaScriptCore را انتخاب می کند که مرورگرهای WebKit مانند Safari را تقویت می کند. Bun خود به زبان Zig نوشته شده است - یک زبان برنامه نویسی سطح پایین با مدیریت حافظه دستی و نخ بومی برای مدیریت همزمانی. نتیجه یک زمان اجرا سبک با حافظه کمتر، زمان راهاندازی سریعتر و عملکردی است که میتواند در شرایط خاص (محکمارک) چهار برابر سریعتر از Node.js و Deno باشد.
مانند Deno، Bun از جاوا اسکریپت و تایپ اسکریپت بدون نیاز به ترانسپایلر یا پیکربندی شخص ثالث پشتیبانی می کند. همچنین از فایلهای jsx. و tsx. برای تبدیل نشانهگذاری HTML به جاوا اسکریپت بومی پشتیبانی میکند. پشتیبانی آزمایشی برای اجرای فایلهای Wasm کامپایلشده WebAssembly در دسترس است.
در داخل، Bun از ماژولهای ES استفاده میکند، await
سطح بالا پشتیبانی میکند، CommonJS را ترجمه میکند و الگوریتم وضوح node_modules
Node را پیادهسازی میکند. Bun ماژولها را در ~/.bun/install/cache/
ذخیره میکند و از پیوندهای سخت برای کپی کردن آنها در دایرکتوری node_modules
پروژه استفاده میکند. پس همه پروژههای روی سیستم شما به یک نمونه واحد از همان کتابخانه ارجاع میدهند که نیازهای فضای دیسک را کاهش میدهد و عملکرد نصب را بهبود میبخشد. (توجه داشته باشید که نصبهای macOS نسخههای محلی را برای سرعت حفظ میکنند.)
Bun از Node's package.json
، دستورات معادل npm
و bux پشتیبانی میکند - گزینهای مانند npx
برای نصب خودکار و اجرای بستهها در یک دستور. مثلا:
bunx cowsay "Hello, world!"
bun init
پروژههای خالی را مانند npm init
داربستبندی میکند، اما میتوانید یک پروژه جدید را با bun create <template> <destination>
قالببندی کنید، جایی که <template>
یک بسته رسمی، یک مخزن Github یا یک بسته محلی است. به عنوان مثال، برای ایجاد یک پروژه Next.js جدید:
bun create next ./myapp
Bun شامل یک باندلر برای وارد کردن همه وابستگی ها به یک فایل است و می تواند Bun، Node.js و جاوا اسکریپت سمت کلاینت را هدف قرار دهد. این امر نیاز به استفاده از ابزارهایی مانند esbuild یا Rollup را کاهش می دهد:
bun build ./index.ts —outdir ./out
اکثر گزینههای رابط خط فرمان از طریق یک API جاوا اسکریپت در دسترس هستند، پس میتوان اسکریپتهای ساخت پیچیدهای را بدون اجرای کار اختصاصی ایجاد کرد. در اینجا یک ساخت مشابه با دستور بالا وجود دارد:
await Bun . build ( { entrypoints : [ './index.ts' ] , outdir : './out' , } )
Bun دارای یک تست اجرا کننده استاندارد مانند Deno و Node.js 20 است. Running bun test
اسکریپت هایی با نام های زیر را اجرا می کند:
*.test. { js | jsx | ts | tsx } *_test. { js | jsx | ts | tsx } *.spec. { js | jsx | ts | tsx } *_spec. { js | jsx | ts | tsx }
نیازی به ابزارهای نودمون مانند نیست، زیرا bun
دارای یک پرچم —watch
است که اسکریپت ها را مجدداً راه اندازی می کند یا زمانی که یک فایل وابستگی را تغییر می دهید آزمایش می کند. راه اندازی مجدد آنقدر سریع است که با هر بار زدن کلید، امکان بارگذاری مجدد زنده وجود دارد. (اینکه آیا این عملی است و باعث حواس پرتی نیست، بحث دیگری است!)
بارگذاری مجدد زنده زیبا نیست! ( هشدار: محتوای سوسو می زند! ) GIF متحرک اصلی را مشاهده کنید.
حالت —hot
مشابهی در دسترس است، که در آن Bun تغییرات و ماژولهای بارگذاری مجدد نرم را تماشا میکند. همه فایلها دوباره ارزیابی میشوند، اما وضعیت جهانی باقی میماند.
متغیرهای محیطی موجود در فایلهای project .env
به طور خودکار بارگیری و تجزیه میشوند و در برنامههای Bun در دسترس قرار میگیرند، پس نیازی به استفاده از بستههایی مانند dotenv نیست.
Bun و همچنین Bun API های خود برای شبکه، دسترسی به فایل، پردازش های فرزند و غیره، پشتیبانی می کند:
APIهای وب مانند fetch
، URL
، blob
، WebSocket
، JSON
، setTimeout
و رویدادها.
APIهای سازگاری Node.js مانند console
، assert
، dns
، http
، path
، stream
، و util
و همچنین موارد جهانی از جمله __dirname
و __filename
. Bun ادعا می کند که ۹۰٪ از API های پرکاربرد به طور کامل پیاده سازی شده اند، اگرچه باید آن هایی را که مختص پروژه خود هستند دوباره تحلیل کنید.
در نهایت، Bun یک کلاینت SQLite3 بومی دارد - bun:sqlite - که می تواند تعداد وابستگی های مورد نیاز در برخی پروژه ها را کاهش دهد.
نان کم پخته
Bun در حال توسعه فعال است، پس ویژگی های زیر هنوز ظاهر نشده اند:
یک مدل مجوز مانند Deno برای محدود کردن دسترسی به فایلها، شبکه، فرآیندهای فرزند، متغیرهای محیطی، اطلاعات سیستمعامل و غیره. گفت ن حقوق مجوز بعداً میتواند باعث ایجاد عوارض شود (همانطور که در Node.js 20 مشاهده میشود)، پس من گمان میکنم که گزینهها قبل از انتشار نسخه ۱.۰ وارد شوند.
ابزارهایی مانند حلقه Read-Eval-Print (REPL)، بازرس وابستگی، linter، اشکالزدا، فرمتکننده کد، تولیدکننده اسناد، و یک تولیدکننده اسکریپت مستقل وجود ندارند، اما باید در طول زمان ظاهر شوند.
نصب Bun
Bun به نسخه ۱.۰ نرسیده است، اما به صورت یک باینری در دسترس است که میتوانید آن را روی Linux، macOS و Windows WSL نصب کنید:
curl -fsSL https://bun.sh/install | bash
همچنین، می توانید آن را با مدیر بسته Node نصب کنید:
npm install -g bun
یک نسخه بومی ویندوز در راه است، اگرچه زیرسیستم ویندوز برای لینوکس اغلب گزینه سادهتر و با عملکرد بهتر است. همچنین، میتوانید از Docker برای اجرای Bun در یک کانتینر نیز استفاده کنید:
docker run —rm —init —ulimit memlock = -1:-1 oven/bun
پس از نصب، می توانید موتور را با موارد زیر ارتقا دهید:
bun upgrade
برای حذف، دایرکتوری باینری و کش ~/.bun
را حذف کنید:
rm -rf ~/.bun
سپس فایل پیکربندی پوسته خود را به روز کنید ( .bashrc
، .zshrc
، یا مشابه) تا ارجاعات ~/.bun/bin
را از متغیر $PATH
حذف کنید.
استفاده از Bun
Bun قابل اعتماد است اگر از ابتدای پروژه خود از آن استفاده کنید. سرعت بهتر از Node.js است، اگرچه بعید است که شاهد افزایش عملکرد قابل توجهی باشید، مگر اینکه برنامه شما کارهای فشرده خاصی مانند پردازش سنگین SQLite یا پیامرسانی WebSocket را انجام دهد.
سازگاری Node.js برای پروژه های کوچکتر و ساده تر خوب است، و من با موفقیت برخی از اسکریپت ها را با استفاده از bun start
بدون ایجاد تغییرات راه اندازی کردم. برنامههای پیچیدهتر با پیامهای خطای مبهم ایجاد شده در اعماق سلسله مراتب node_modules
شکست خوردند.
Bun vs Deno در مقابل Node.js
Deno بسیاری از اشکالات Node را برطرف کرد، اما توسعه دهندگان لزوماً مجبور به تغییر آن نبودند:
Deno از ماژول های شخص ثالث Node پشتیبانی نمی کند.
مهاجرت از Node.js به Deno نیاز به یادگیری تکنیک های جدید داشت.
در حالی که Deno تجربه توسعه بهتری را ارائه کرد، Node.js به اندازه کافی خوب بود.
Deno اکنون گزینه های سازگاری Node.js را اضافه کرده است. این سادهترین راه برای ترغیب توسعهدهندگان به انتقال به Deno بود، اما در این بین، Node.js برخی از آپشن های Deno، از جمله ماژولهای ES، اجراکننده آزمایشی بومی و حالت —watch
را به کار گرفته است.
Bun رویکرد متفاوتی را در پیش گرفته است و هدف آن این است که موتوری سریع و سازگار با Node با پیشرفتهای Deno باشد. نشانه ها امیدوار کننده هستند، اما هنوز وجود ندارد:
عملکرد عالی است، اما تعداد کمی از توسعه دهندگان از سرعت Node.js شکایت دارند.
سازگاری خوب است، اما پشتیبانی از همه ماژولهای Node.js در یک موتور جاوا اسکریپت متفاوت خواهد بود. آیا JavaScriptCore با سرمایه گذاری بسیار کمتر می تواند با پیشرفت های V8 همگام شود؟
Bun این پتانسیل را دارد که جایگزین مجموعه ابزار شما شود، اما هنوز طیف کامل موجود در Deno را ارائه نکرده است.
خلاصه: آیا باید به Bun تغییر دهید؟
Bun یک زمان اجرا جاوا اسکریپت کامل است، اما Node.js قهرمان پروژههای حیاتی یا برنامههای قدیمی است. باید سعی کنید برنامه خود را با استفاده از bun start
اجرا کنید، اما هرچه پایگاه کد شما بزرگتر باشد، شانس کمتری برای اجرا بدون تغییر خواهد داشت.
Deno احتمالاً گزینه بهتری نسبت به Bun برای پروژه های جدید است، از آنجایی که بالغ تر و کامل تر است.
Bun عالی است، اما جدید است، به طور فعال در حال توسعه است، و هنوز به نقطه عطف نسخه ۱.۰ نرسیده است. زمان اجرا پایدار است، اما تعداد کمی در این مرحله روی آینده بلندمدت آن شرط بندی می کنند. همانطور که گفته شد، Bun ایده های جالبی دارد که امیدوارم هر دو تیم Node.js و Deno در نظر بگیرند (API های CLI و .env
بارگذاری شده خودکار لطفا!)
در یک یادداشت جانبی، من نام Bun را دوست دارم، اما جستجو برای منابع ممکن است دشوار باشد. ChatGPT این بیانیه جسورانه را بیان می کند که «هیچ زمان اجرای جاوا اسکریپت شناخته شده ای به نام «Bun» وجود ندارد. تا آنجا که من اطلاع دارم، چنین فناوری در اکوسیستم جاوا اسکریپت وجود ندارد. این ممکن است به این دلیل باشد که دادههای پس از سال ۲۰۲۱ محدود است، اگرچه برخی سؤالات پاسخ Bun و عذرخواهی برای اشتباه را نشان میدهند!
من گمان میکنم که به سمت عصر جاوا اسکریپت سمت سرور همشکلی پیش میرویم، جایی که توسعهدهندگان ماژول تلاش میکنند کدی بنویسند که با تمام زمانهای اجرا سازگار باشد: Node.js، Deno، Bun، بدون سرور، لبه، جاسازی شده و غیره. ممکن است در نهایت به یک نقطه ای که در آن زمان های اجرا جاوا اسکریپت عمدتاً به همان روشی که مرورگرهای امروزی هستند قابل تعویض هستند.