Галоўная / Артыкулы / Адзін Weather CLI, пяцьце інструментальных комплексаў: Rust, Go, Zig, Bun і Node.js

Адзін Weather CLI, пяцьце інструментальных комплексаў: Rust, Go, Zig, Bun і Node.js

Як выглядае той самы лёгкі CLI на базе HTTP-плюс-JSON у Rust, Go, Zig, Bun і Node.js, а також што значыць размах бінара, час складання і трудносці налагоджэння для выбору.

3165 слоў

Мікро-тэсты, такія як цыкл Фібаначчі, мало чаго сказваюць пра тое, сколькі коштаў стварэнне рэальнага інструмента для командной лініі. Кращы тэст — это невялікая утиліта, якая вяроўнае з’ёднанне з сетчукою, декодавае JSON, выконвае простыя матэматычныя расчытанні і выводзіць апрантаваны результат, створаная на однаковы лад у калькольках моваў. У цім кераванні адбываецца самэ такое эксперыментаванне ў мовах Rust, Go, Zig, Bun і Node.js, тады вы зможаце адначасова ацэніць, якая тулкітавая сутнасць падходзіць для вашага наступнага інструмента для командной лініі, на адной стороне за розмер бінарнага файла, час складання, додатковыя витраты пад час выконання, а на другай — за ступень перашкод між порожнім папкам і бінарным файлам, які можуць запускаць вашы корыстнікі.

Найважлівыя рэзультаты варта згадаць з самага пачатку. Размеры готовых файлав выконванняя складаліся з 1,2 МБ да 45 МБ, а якщо не выкарыстоўваць процес компіляцыі, то трэба прабачыць корыстувальнікам установіць камплект для выконванняя розмерам прыблізна 100 МБ. Часы стварэння чыстага коду складаліся з 0,8 секунд да 28 секунд. А найпрагматычнейшая рэкамендацыя на заканчыку — гэта не мова з найшырэйшым часам выконванняя.

Інструмент тэставання і чаму ён являецца справедлівым навантажэнням

Эты прыстрой называецца wx. Вы задаёте яму назву горада; ён ператварае гэту назву на координаты за дапамою API геокодавання Open-Meteo, запрашвае даныя пра поточныя пагодныя умовы з API прогназу Open-Meteo і выводзіць рэзультаты разам з расчысленай температурой, якая відчуваецца. Тыповы вызыв выглядае так:

$ wx reykjavik
Reykjavik, Iceland
Temperature: 4.2C (feels like -0.4C)
Wind: 24 km/h NNW
Humidity: 68%

Эты ўстатку намеравана мала, але яна займаецца чатырма аспектамі, дзе эрганоміка КЛІ на самай працы разлічаецца ў розных экасистемах:

  • HTTP-кліент з TLS. Патрэбны два запыты HTTPS: адні для геокодавання, другі — для прогназу.
  • Декодаванне JSON. Адпаведныя адказы перадаюцца у віда типаваных структурах, а не як свабодныя об’екты.
  • Фактычныы вычысленні. Вярагодная температура вылічваецца за дапамою формулы з рознымі варыянтамі, а не шляхом з’еднання страк.
  • Выход у тэрмінале. Кольоры ANSI і выравнянныя столбцы — гэта тое, што насправды бачаюць корыстнікі.

Язык, які не можа комфортна кераваць усіма чатырма аспектамі, не ўтварае хорашага выбору для КЛІ, незалежна ад таго, насколькі быстро ён выконвае числовыя циклы.

Едын стакіт спяльнай логікі

Кожная версія выкарыстоўвае тое ж самае правіло з трыма варыянтамі. Пад 10 °C прыменяецца формула для вычыслення холаду ветру ад Environment Canada. Пад 27 °C прыменяецца регрэсійны метод індексу жаркаты няба NOAA Rothfusz, выражаный у градусах Цельсія з волгасцю ў процэнтах. У прымежнасці гэтых значэнняў первасны температурны показначык вяртаецца без змян. Тут паказана версія на TypeScript, якая выкарыстоўваецца ў версіях Bun і Node.js; іншыя мовы выкарыстоўваюць тую ж арытмэтыку.

function feelsLike(tempC: number, windKmh: number, humidity: number): number {
  if (tempC < 10) {
    // Wind chill (Environment Canada formula)
    const v = windKmh ** 0.16;
    return 13.12 + 0.6215 * tempC - 11.37 * v + 0.3965 * tempC * v;
  }
  if (tempC > 27) {
    // Heat index (NOAA Rothfusz regression, in Celsius)
    const t = tempC;
    const r = humidity;
    return -8.784 + 1.611 * t + 2.338 * r - 0.146 * t * r
      - 0.0123 * t * t - 0.0164 * r * r + 0.00221 * t * t * r
      + 0.000725 * t * r * r - 0.00000358 * t * t * r * r;
  }
  return tempC; // between 10C and 27C, raw temperature
}

Два моменты заслуговуюць на увагу. Перша — грані режыму ёсць тая частка, яку паспроста адаптаваны варыянт коду паспамічае, таму яны станавяцца хорашым крэтэрам для пераканальнага адзінакоўвання рэалізацый. Другая — обе формулы маюць дыяпазоны дзейнасці, якія гэта простае выкананне ігнаруе: уравнення для расчытку холаду ветру праглядаеся для швайнасці ветру прыблізна 5 км/гад і вышэй, а регрэсія Rothfusz паслугуе толькі для жаркіх, досыць вологіх умов. Для простага інструменту для аналізу пагоды гэта прыемна, але у версіи для практычнага выкарыстоўвання трэба адсакаваць значэнні чыстай температуры, якія выходзяць за гэтыя дыяпазоны.

Як адчувалася рэалізацыя кожнага варыянта коду

Усі код у пяці мовах складаеся з апошней 360 ліній, таму паказаны толькі найболей значныя фрагменты. Важнае — гдзе кожная мова і екосістэма дапамаглі, а гдзе стала пераканалом.

Rust з бібліятэкамі reqwest, serde і парсерам выразаў на адной засадзе derive

У Rust для парсінгу аргументаў викорыстоўваецца популярны крэйт на адной з базаў derive, reqwest для працы з HTTP і serde для десеріялізацыі. Наведзены нижэй фрагмент паказвае прынцып, які робіць Rust зручным для такай работы: макро-функціі derive генеруюць як парсер для командной лініі, так і декодэры JSON на адваротнае з’яўленне з простых вакаюмацый, а типы полей пераглядаюцца ў час компілявання.

#[derive(Parser)]
#[command(name = "wx", about = "Weather lookup")]
struct Cli {
    city: String,
}

#[derive(Deserialize)]
struct WeatherResponse {
    current: CurrentWeather,
}

#[derive(Deserialize)]
struct CurrentWeather {
    temperature_2m: f64,
    wind_speed_10m: f64,
    relative_humidity_2m: u8,
    wind_direction_10m: f64,
}

Весь програма складаецца з апошніх 95 ліній, якія включаюць як вызовы API, так і логіку вычыслення тэмпературы. Асінхронны рантайм tokio — это тое, што трэба явна задаць, на вядменне з Node.js, дзе цікл адбываюцца захаваны ад вас. Такая явнасць спрыяе кантролю, але падвышае размер бінарнага файла.

Спантажуючым быў стандартны выхід: простае запусканне cargo build --release стварыла бінарны файл розмерам 8,4 МБ. Актываўшы оптымізацыю часу з’еднання і адключэння сімвалаў у Cargo.toml, розмер быў зменшаны да 3,8 МБ. Гэтыя настройкі добра вядомы тым, хто розпространяе інструменты на Rust, але новачак, верагодна, распространяў бы большы файл, не паведамляючы пра тое, што меншы варіант знаходзіцца всьлед за двумя рядкамі.

Выберыце толькі стандартную бібліятэку

Для складання на Go зовсім не патрэбны трэціяродныя пакеты. net/http, encoding/json і os.Args падмогаюць у викананні всіх задач. У фрагменте паказана структура адпаведзі, дзе тэгі супарабатуюць з ключамі JSON і даюць імены польям у стилі Go, а таксама частка функцыі main з мінімальной перацэнкай выкарыстоўвання.

type WeatherResponse struct {
    Current struct {
        Temperature float64 `json:"temperature_2m"`
        WindSpeed   float64 `json:"wind_speed_10m"`
        Humidity    int     `json:"relative_humidity_2m"`
        WindDir     float64 `json:"wind_direction_10m"`
    } `json:"current"`
}

func main() {
    if len(os.Args) < 2 {
        fmt.Fprintln(os.Stderr, "usage: wx <city>")
        os.Exit(1)
    }
    city := os.Args[1]
    // geocode, fetch weather, compute, print
}

Готавы праект складаецца з 68 ліній. Яны практычна ўсе адпавядаюць однаму шаблону: пераказ if err != nil { log.Fatal(err) } выклікаецца пяць разоў — по аднаму для запиту на геокодаванне, яго тэла, процесу декодавання, запиту на прогназ і тэла прогназа. Такая павтарэння не ўтварае справжней проблемы, але гэта самая частая лінія практычна ў кожным кліентскім праекте на мове Go.

Рабочы бінарны файл быў створаны за апошнія дзесяць хвілін. Такая шырока скорасць не стала наследкам таго, што Go — мова з мінімальным наборам можлівасцяў (у яе є жорсткія прынцыпы, якія не всім падабаюцца), а таму, што не было нічога, што трэба было б вырашваць: жадных порэвання бібліятак, жадных завантажэнняя залежнасцей, жадной наладкі.

Zig 0.16 з std.http.Client і std.json

Zig, працаваны ў версіі 0.16, быў найболей научным варыянтом, але таксама і найпамедзлейшым у завершэнні. У даным фрагменте паказана структура адпаведзі і пачатак функцыі main, дзе ствараецца аллокатор для дыбагавання, які пасля таго перадаецца далей. Гэта ўласная характерыстыка Zig: кожная функцыя, якая можа аллокаваць память на хіпе, прыймае аргумент у вялічыню аллокатора, таму права на володзення памяцюю завжды є виднымі у сігнатуре вызову.

const WeatherResponse = struct {
    current: struct {
        temperature_2m: f64,
        wind_speed_10m: f64,
        relative_humidity_2m: u8,
        wind_direction_10m: f64,
    },
};

pub fn main() !void {
    var debug_allocator = std.heap.DebugAllocator(.{}){};
    defer _ = debug_allocator.deinit();
    const allocator = debug_allocator.allocator();

    // Every function that might allocate takes `allocator` as a parameter.
    // This is Zig's deal: you control memory, always.
}

Програма вырасла да 108 ліній, таму стала самай дзялгайшая з пяці. Сама кампіляцыя зайняла толькі 0,8 секунды — гэта был найшырэйшы час у пораўнанні, але цэлы процес стварэння програмы зайняў больш часу, што сапраўдна становіць гадзіну. Прычыной быў TLS. Клас std.http.Client уключае свою сабственную рэалізацыю TLS, але ўсё раву патрэбныя яму надзеянныя коранавыя сертыфікаты, і на тэстовай машыне не удалося знайсці пакет системных CA-сертыфікатоў. Џедыным симптамам была памята error.TlsInitializationFailed без дадатковай інфармацыі. Рашэння — явна зачытаць сертыфікаты через std.crypto.Certificate.Bundle і перадаць гэты пакет кліенту — было выкрыстаўлена толькі пад час дыскусій у пытанні на GitHub. Вашы рэзультаты можаць разлічвацца залежна ад платформы, але урок застаецца: шырый кампілятор не можа компенсаваць час, запрацоўваны на вираслівыя проблемы часу выконання.

Явна перадача аллокатора ўжыткавая для програмнага забезпечэння, дзе важліва праця памяці. Для інструмента, які аллокуе кальколька стрэнгаў і адна буфера JSON, гэта пераважна толькі дадае зайвых крокаў. У Zig існуе інтеграваны менеджер пакетаў, базаваны на build.zig.zon, які ўжо з 0.11, але екасыстэма яшчэ слабая; не знайшлася падтрымваная бібліятэка кольераў тэрмінала, таму заместа гэтага быў скопіяваны падказчык ANSI з прыблізна 40 лініяў з гіста.

Bun з аднам файлам TypeScript

Версія Bun ёсць найкорачэйшая і найлёгчая да чытання. Яна чытае назву горада з Bun.argv, якщо ёй не хвацает, выходзіць з паведамленнем пра спосаб наўводжэння, а пасля два разы выкарыстоўвае вбудованы fetch і декодуе кожны адпаведны рэспонс з .json(). Верхнія галочка await означае, што няма функцыі-обгортка.

const city = Bun.argv[2];
if (!city) {
  console.error("usage: wx <city>");
  process.exit(1);
}

// Geocode city name to coordinates
const geoRes = await fetch(
  `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city)}&count=1`
);
const geo = await geoRes.json();
const { latitude, longitude } = geo.results[0];

// Fetch weather
const wxRes = await fetch(
  `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m,wind_speed_10m,relative_humidity_2m,wind_direction_10m`
);
const data = await wxRes.json();

Уся файлавая структура складаецца з 47 ліній, уключаючы обе запиты, і ўсё гэта віклалося працэю прыблізна за васьмі хвіліны, прычаму большая частка часу пайшла на вырахунок тэмпературы. Аднак зверніце увагу, чаго не робіць цей фрагмент коду: ён ніколі не перакантроўвае значэння res.ok, а geo.results[0] застаецца незначэнным, калі геокодер не знаходзіць падходячага результата, таму аблыканне неправільна назва горада спрычыняе крах з адпаведнымі памылкамі, у звязку з чым не паказваецца дружэльныя паведамлення. Короткасць дасклалася, але у продакшн-середовішчы CLI неабходныя тые калькі дадатковых ліній.

Проблема з Bun заключаецца у распространенні. Команда bun build --compile стварае самостойны виконуемы файл розмірам прыблізна 45 МБ для гэтага маленькага інструмента, адколі выходны файл збірае ў сабе двыжок JavaScriptCore і середовішча Bun. Гэта прыблізна у сем разоў больш, чым бінарны файл на мове Go, і майже у сорак разоў — чым бінарны файл на мове Zig. Якщо вашы корыстувальнікі вже маюць установлены Bun, безпосередняя запусканне файла .ts абсалютна ухілваецца ад гэтай проблемы.

Node.js, які не патрабуе адзінольнага апісання

Рэалізацыя Node.js па сутнаце ёсць код Bun, адколькі з версіі 18 Node.js ўжо мае вбудованы метод fetch. Сэрьёзныя разлікі каштуюцца ў часе выканання:

  • Вартас запуску. Большая частка разліку ў загальным часе выканання стаўляецца на сам запуск процэсу: 82 мс для Node.js проты 24 мс для Bun, тады как імітаваны раунд-трып па сеті дадае толькі калькі мілісэканд. Для адной інтэрактывной команды ніхто гэта не зазначае; але ў цыклі шэлу, які запускае інструмент сотні разоў, гэта накапліваецца.
  • Распространэнне. Карыстальнікам патрабуецца або сэрвіс Node.js з вельмі малым размерам, які трэба запісаць (прыблізна 100 MB), або ж стварыць самастоятельны файл за дапамою Single Executable Applications. SEA ўтвараецца непасэрбна, але статус яе стабільнасці змінюецца, таму неабходна пераканацца ў актуальной дасведчовай літэратуре для вашай версіі Node.js. У зв’язку з тым, што ёй не патрабуецца додатковыя компоненты, розмер выкаанаванага файла адпавядае розмеру скомпіляванага бінарнага файлу Bun.
  • TypeScript. Node.js тепер можа сама выдаліць синтаксіс TypeScript, які можна выдаліць, таму звычны файл .ts працюе без tsx чыра ts-node; на момент напісання гэта функцыя была апісана як стабільная для версій лінейкі 24 LTS. Падтрымліваець толькі синтаксіс, які можна выдаліць: анотацыі зникаюць, але структуры, якія генеруюць JavaScript, такія як enum’i, прасторы імена і атрыбуты параметраў, як і ранейш выкалічваюць патрэбу ў транспайляры. Bun ідзе ўсё далей без налагоджэння, падтрымляючы JSX, декоратары і аліясы пацоў. Чыбах глэбачэ аб тым, што включае натыўнае выдаленне, адзірніце што насправды робіць і чаго не робіць натыўная падтрымка TypeScript у Node.js.
  • Якща сяглядаць выключна з точка зору абсалютна новага CLI, Node.js прыносіць той самы код, што і Bun, але з медленнейшым запускам і сложнейшай структурой дастынаў. Аднак гэта вузкая дагадка. Якщо ваша команда вже стандартизавалася на Node.js, паважае яго гарантіі сумеснасці з npm або падтрымвае існуючы CLI на яго базе, гэтыя факторы можаць легка пераважыць разлік у 60 мс у часе запуску.

    Настройка зьвязвання вимераванняў і паказаныя цифры

    Выкананы замеры на M3 MacBook Pro з RAM 18 GB, які працюе пад macOS 26, з викорыстаннем hyperfine за адказом hyperfine --warmup 3 --min-runs 50 './wx reykjavik'. Чыраглік сетевых паразітных сигналаў усунулі за дапамогою местнага фальшывага HTTP-сервера, які вяртае фіксаваны JSON. Вэлічына часу выканання — цэлае время з момента запуску процеса да його завершэння, уключаючы час запуску. Часы разработкі ўсьмо толькі апрыксамыя значэння, а не точныя замеры, таму трэба порашчываць ступені, а не хвілінкі.

    Ключовыя паказнікі з выканання:

    • Rust: апошней 95 ліній, 3,8 MB пасля налашоўкі (8,4 MB за значыней пры стандартных налашоўкі), 28 секунд на чыстую кампіляцыю, 4,8 мс на выкананне.
    • Go: 68 ліній, 6,2 MB, менш чым за секунду на кампіляцыю, 5,2 мс на выкананне, працавае за апошней 10 хвілінак.
  • Zig: 108 ліній коду, 1,2 МБ, час компіляцыі — 0,8 секунды; аб’ём загальных зусілей — падзеў гадзіны.
  • Bun: 47 ліній коду, розмер скомпіляванага кода — або-ма 45 МБ, час выканання — 24 мс; працяўне час адпаведае приблізна 8 хвілінам.
  • Node.js: той самы код, што і у Bun; час выканання — 82 мс; розмер падчас работы — або-ма 100 МБ, або бінарны файл у тым жа розмере, як у Bun.
  • Разміры файлав завышаюцца залежна ад настаўленнях кампайлявання. Для Rust былі неабходны параметры lto = true і strip = true у настаўленнях [profile.release]. Go быў скомпільаваны з викорыстаннем параметра go build -ldflags='-s -w', што дазволіла адмахнуцца від інформацыі для дэбагавання. Размір 1,2 МБ у версіі Zig з настаўленням ReleaseSmall адбываецца таму, што нават з падтрымкай TLS файл застаецца маленькім — кліент HTTP і код для роботы з крыптаграфіяй знаходзяцца ў стандартной бібліятэке і прыўязаны статычна, без включэння додатковых компонентоў, такіх як OpenSSL. Версія ReleaseSafe, якая залучае перакананні ў безпеку пад час выконання, мае размір адпоўна 2,1 МБ.

    Што скрываюць цыфры тэстаў

    Zig выграе на паперы, але праграе ў рэальным часе

    За памерамі Zig стварыў найменшы і аднаго з найшырэйшых бінарыў. Аднак реальны час выканання 108 ліній коду паказвае іншую картыну:

    • Проблема з пакетам сертыфікатоў зайняла больш чым 40 хвілін у зв’язку з памилкай, якая складалася з адной лініі коду.
  • Версія ReleaseSmall, яка дае 1,2 МБ, не мае следоў стэку; ReleaseSafe зберагае следы панікі, але ўяўляе сабою версію па вазе 2,1 МБ.
  • Алакаторы было неабходна включыць у кожную операцыю з рэчамі, а два забутыя элементы defer спрычынілі вытэкі, якія сталі видны толькі тады, калі алакатор для дэбагування ўказаў на іх пад час завершэння роботы.
  • Патрэбна была дапаможная функцыя для кольцаў тэрміналу, так как у экасистеме яе не было.
  • Для інструмента, які працуе дзяўно і для якога важліва контролюваць кожную алакацыю та кожны байт выходных дадзеных, такая чыстая структура працы дае плоды з часам. Для чаго-небудзь, што трэба запрацаваць да обеду, гэта наразе не падходзіць. Дизайн мовы элегантны; проста асоцыйнуючая ся з яю экасистема ўсё ж моладзейшая.

    Go ніколі не ўсёга найлепшы у чым-небудзь, але ўсё равана выграўа

    Go кампайляецца за менш чым секунду, стварая прыемны бінарны файл без залежнасцей, для яго патрабуецца толькі стандартная бібліятэка, і ён працаваў вядома за дзесять хвілін. Ён большы за налаштаваны Rust (6,2 МБ проты 3,8 МБ) і адносна медленнейшы (5,2 мс проты 4,8 мс), але чалавек не можа пазнакаць такую разніцу ў інструменте, які завершае роботу за канікулы мілісэкунд.

    Для крос-кампайлінгу достатня адна зменная сераўыска, напрыклад GOOS=linux go build. Rust падходзіць ближэй за дапамою cargo build --target x86_64-unknown-linux-gnu або дапаможніка cargo-zigbuild, а Zig, можна сказаць, мае найлепшыя показнікі крос-кампайлінгу, таму што ён уключае свой сабэй лінкер і libc. Разлік у тым, што Go не патрабуе ні дадзейчых інструментоў, ні додатковай наладкі. Гэта ўсё частая законамасць: Go рэдка калі перавышае які-небудзь адзіны показнік, але у яго ўсего меньша колькасць перакосаў.

    Bun чудоўны для локальнага викорыстання, але складны для розповсюджэння

    Bun падаліў найчыстэйшы код за самы короткі час. Для персональнага скрыпта, які знаходзится ў ~/bin у формате .ts-файла, яго важка перадраціваць. Для распространення 45 МБ для запиту па пагодзе — гэта справжня недакладнасць, і адтуды, што практычна весь гэты об’ём займае вбудованы двыжок, няма практычнага спосабу зменшыць його без болей лёгкай версіі з боку команды Bun, якая не існавала часа апрантакі.

    Аргументы Rust для маленькіх інструментаў паслабіліся

    Калькі леты тым, калі аргументы на корант Rust CLIs стаялі на швальбе, безпэцы і маленькіх бінарных файлаў. Для інструментаў, якія залежнаць ад I/O, гэтыя аргументы зараз менш ясны:

    • Go падае ў роўнанне з практычной швальбай Rust.
    • Zig стварае маленькія бінарныя файлы без жадных налаштаванняў.
    • 28 секунд на стварэння чыстай версіі для програмы з 95 лініяў — гэта вельмі великі тыржок для швайных утиліт.

    Rust даўжа застаецца выключным выборам там, дзе інструмент прыклікае тыячы корыстувачаў і патрабуе годзін працы над яго падтрымкай, а система типаў продовжвае вылучаць рэдкія ситуацыі па ходу. ripgrep, fd, bat, delta і hyperfine — усе гэтыя інструменты ўжо є CLIs на Rust, і ўсія яны серйозна падтрымваюцца пра дужы час, а не стваруюцца за выходны. Для швыдкіх проектаў такія витраты рэдка карыстуюцца сабой; аднак для інструмента, які будзе шырока распространяцца, гэта можа быць варыянтам, які з наіменшай верагоднасцю будзе накапліваць тонкія багі.

    Выбор пакета інструментаў для вашага наступнага CLI

    Рашэнне залежыць менш ад чыстай скорасці, чым ад таго, хто будзе выкананаць інструмент і як ён будзе доўгачына доступны для корыстувачаў:

    • Выберыце Go калі мета — мінімальны загальны расходы ад порожняй дырэктарыі да распространенага бінарнага файла: код готовы за калікве хвілін, складанне за часы меншыя за секунду, адны файл вагой 6,2 MB без жадных залежнасцяў і можлівасць лёгкай міжсістэмнай компіляцыі.
  • Выберыце Rust для інструментаў з вялікой аудытарыёю, дзе важны маржы, такіх як інструменты для складання, лінтары і запускачы тэстаў, і прыміце трываласць компілявання.
  • Іспользуйце Bun для персональных або внутрашняях інструментаў каманды, дзе у всіх вже є рантайм, і файл ніколі не патрэбуе компілявання.
  • Утримайцеся ад Zig для простых CLI-інструментаў пакуль яго экасистема і паведамленні пра адказы не стануць болей развітымі; бінарны файл па вазе 1,2 МБ ўражаючы, але зусілля для досягнення такога рэзультата пакуль не ў спраўнасці для простых утиліт.
  • Залічвайце Node.js там, дзе ён вялікі час яўляецца вашай платформай. Для абсалютна новага самастоятельнага CLI ён прасунуў мало таго, чаго не мае Bun, хоча абмежэння экасістэмы і організацыі можаць заставіць яго застацца разумным выборам. Для болей шырокага парабяну рантаймоў, адзірніце парабян Node.js, Deno і Bun.
  • Кожная рэалізацыя ўстатквае настолькі мала, каб яе можна было перзбудаваць з вышэўказаных фрагментоў за аднага дня, разам з мак-серверам і гіперфінным скрыптам. Вашы абсалютныя паказнікі будуць разнымі залежна ад апаратуры, операцыйнай системы і версій інструментальных комплексаў, але статычныя прапорцыя должны застацца стабільнымі: Zig — самы маленькі, Bun — самы вялікі, Go — з наименейшымі трудносцямі.

    Ключовыя выводы

    • Звярожыце цэлы шлях да запакаванага бінарнага файла, а не толькі час выканання; для маленьких інструментаў важлівыя ўстановка, адлагоджэнне і распространенне.
    • Стандартныя настройкі кампаўлявання можу подвоіць размер бінарнага файла, таму трэба выучыць флагі выпуску для выбранага інструментарыя.
    • Бінарныя файлы, створаныя на основе Bun або Node.js SEA, несу ў сабе весь двыгун, што мае набагато большое значэнне, чым час ўсунення першых проблем.
    • Пераканаўваеце вхідныя даны і адпаведзі HTTP нават у короткіх скрыптах; часта самая простая реалізацыя ў той час, калі не ёсьць обробкі адносоў з бягамі.
    • Спрыймайце конкрэтныя статусы версій і ўжо існуючыя размеры як момантальныя даны і пераканаўваеце іх па адносу да актуальных выпускаў пры выніканні рашэння.

    Спадзяючыся літаратура

  • Node.js протык Go для JSON API: аднаковая працэздатнасць, на 2,6 раза менейшая колькасць памяці — Тэстаўна перапылкавая перамоць ідэнтычных HTTP-сервісаў на базе Node.js і Go паказвае, дзе перапісвае прыносіць практычныя выгоды (выкарыстоўваная память) і дзе — ні (працэздатнасць і зволненне).