Сўнгги йилларда JavaScript дастурчилари орасида Bun ҳақида тез-тез гапирилмоқда. У Node.js каби серверда JavaScript ва TypeScript кодини бажарадиган runtime, лекин ўзи билан пакет менежери, bundler ва тест воситасини ҳам олиб келади. Кўпчилик биринчи бўлиб "Node.js'ни бутунлай алмаштирсам бўладими?" деган саволни беради. Жавоб лойиҳанинг турига, ишлатилаётган кутубхоналарга ва жамоангиз қанча хавфни кўтара олишига боғлиқ. Қуйида буни амалий мисоллар билан кўриб чиқамиз.
Bun нимаси билан Node.js'дан фарқ қилади
Node.js Google'нинг V8 двигателига асосланган, Bun эса Safari браузерида ишлатиладиган JavaScriptCore двигателидан фойдаланади ва асосан Zig тилида ёзилган. Bun TypeScript файлларни олдиндан компиляция қилмасдан тўғридан-тўғри ишга тушира олади, шунинг учун кичик лойиҳаларда tsc ёки ts-node созлаш зарурати йўқолади. Пакетларни ўрнатиш ҳам одатда сезиларли даражада тезроқ, бу айниқса CI жараёнларида ва ҳар куни кўп марта install қилинадиган лойиҳаларда сезилади.
Bun ишлаб чиқувчилари Node.js API'лари билан мосликка катта эътибор беришади: fs, path, http каби модуллар ва npm пакетларининг катта қисми ишлайди. Лекин мослик ҳали юз фоиз эмас. C++ да ёзилган native модуллар, баъзи кам ишлатиладиган Node API'лари ва Node'нинг ички хатти-ҳаракатига таянган кутубхоналар кутилмаган хато бериши мумкин. Шунинг учун лойиҳангиз учун аниқ жавобни фақат синов кўрсатади, расмий ҳужжатлардаги мослик рўйхатини ҳам кўздан кечириб чиқиш фойдали.
Қачон Bun'ни танлаш ўринли
Bun янги бошланаётган, боғлиқликлари кам ва замонавий кутубхоналарга таянган лойиҳаларда ўзини яхши кўрсатади. Масалан, Тошкентдаги бир кафе учун меню ва буюртмаларни қайтарадиган кичик API, Telegram бот ёки ички ҳисобот скриптлари учун Bun қулай танлов бўла олади. Узоқ йиллар ишлаб келаётган, ўнлаб native пакетларга эга ва тўхтаб қолиши катта зарар келтирадиган тизимларда эса эҳтиёткор бўлиш керак. Бундай ҳолларда Bun'ни аввал фақат пакет менежери ёки тест воситаси сифатида қўллаб, runtime'ни Node.js'да қолдириш ҳам мумкин.
- Bun мос келади: янги API, бот, скриптлар, TypeScript билан ёзилган кичик сервислар.
- Эҳтиёт бўлинг:
bcrypt,sharpкаби native модуллар, эски Express middleware'лари, мураккаб монорепо тузилмалари. - Node.js'да қолдиринг: тўлов тизимлари билан ишлайдиган ва синовсиз ўзгартириб бўлмайдиган муҳим сервислар.
Bun'ни VPS серверга ўрнатиш
Bun доимий ишлайдиган жараён бўлгани учун уни VPS серверда ишлатиш энг қулай йўл. Оддий shared хостингда ўзбошимчалик билан runtime ўрнатиб, фон жараённи доимий ушлаб туриш одатда имконсиз, шу боис бундай лойиҳалар учун sayt.uz'даги VPS хизмати ёки техник ёрдам билан маслаҳатлашиш тўғри бўлади. Ўрнатиш учун расмий скриптдан фойдаланилади, у Bun'ни фойдаланувчининг уй каталогига жойлайди.
sudo adduser --disabled-password app
sudo -iu app
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc
bun --version
Иловани root фойдаланувчиси номидан ишга туширмаслик учун алоҳида app фойдаланувчиси яратдик. Bun бу ҳолда /home/app/.bun/bin/bun манзилида бўлади, бу йўл кейинги босқичда керак бўлади.
Оддий HTTP сервер ва уни синаш
Bun'нинг ўз HTTP сервери бор, у Bun.serve функцияси орқали ишга туширилади. Қуйидаги мисол кафе менюсини JSON кўринишида қайтаради ва портни муҳит ўзгарувчисидан олади. Файл .ts кенгайтмасига эга бўлса ҳам, уни ҳеч қандай компиляциясиз ишга тушириш мумкин.
// src/index.ts
const menu = [{ id: 1, name: "Osh", price: 45000 }];
Bun.serve({
port: Number(process.env.PORT ?? 3000),
hostname: "127.0.0.1",
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/menu") return Response.json(menu);
return new Response("Not found", { status: 404 });
},
});
Ишга тушириш учун bun install билан боғлиқликларни ўрнатинг ва bun run src/index.ts буйруғини беринг. Кейин бошқа терминалдан curl http://127.0.0.1:3000/menu орқали жавобни текширинг. Мавжуд Express лойиҳасини синаб кўрмоқчи бўлсангиз, одатда node server.js ўрнига bun server.js ёзишнинг ўзи кифоя қилади.
systemd хизмати сифатида доимий ишлатиш
Production'да жараён терминалга боғлиқ бўлмаслиги, хато билан тўхтаса қайта кўтарилиши ва сервер ёқилганда ўзи ишга тушиши керак. Бунинг учун systemd хизмат файлини ёзамиз. Бу усул қўшимча дастур талаб қилмайди ва логларни journalctl орқали кўриш имконини беради.
# /etc/systemd/system/menu-api.service
[Unit]
Description=Menu API (Bun)
After=network.target
[Service]
User=app
WorkingDirectory=/home/app/menu-api
Environment=NODE_ENV=production
Environment=PORT=3000
ExecStart=/home/app/.bun/bin/bun run src/index.ts
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now menu-api
sudo systemctl status menu-api
journalctl -u menu-api -f
Ташқи сўровлар Node.js иловаларидаги каби Nginx орқали қабул қилинади: proxy_pass http://127.0.0.1:3000; қатори билан reverse proxy созланади ва Let's Encrypt сертификати Certbot ёрдамида олинади. PM2'га ўрганиб қолганлар учун у ҳам ишлайди: pm2 start src/index.ts --interpreter ~/.bun/bin/bun.
Node.js'дан Bun'га хавфсиз ўтиш тартиби
Мавжуд лойиҳани бирданига кўчириш ўрнига босқичма-босқич ҳаракат қилиш тавсия этилади. Аввал тестларни Bun билан ишга тушириб кўринг, кейин staging серверда иловани бир неча кун кузатинг ва фақат шундан сўнг асосий серверни алмаштиринг. Bun янгиланишлари тез-тез чиқади, шунинг учун сервердаги версияни қайд этиб қўйинг ва янгилашдан олдин уни синов муҳитида текширинг. Агар бирор кутубхона муаммо берса, ўша сервисни Node.js'да қолдириб, қолганларини Bun'да ишлатиш ҳам мутлақо нормал ечим.