Комментарии 118
Интересно, это может повлиять на сам Node.js. Просто вспоминается история с форком io.js, благодаря которому все сдвинулось (ES6, V8 и тд.) и история с yarn, до появления которого вроде даже lock-файлов в npm не было.
Так и повлияет. Кто то снова возьмёт и припишет к ноду что-то ещё, от чего у всех волосы под мышками дыбом встанут.
Не поймите меня неправильно, мне интересен этот бан. Я его щас попробую. Всё замечательно.
Но вообще-то - это всё извращения и издевательства. Все большой группой насилуют скриптовый язык, который должен был быть просто маленкой заплаткой для управления браузером, а его переделали в серверный язык.
Это так же как рассказы про замечательную типизированность TS, которой на самом деле не существует. (Мы только что в отдельной ветке спорили, что вы сколько угодно можете объявлять поле интерфейса номером, но ТС не заикаясь туда пихнёт строку.) Это попытка натянуть сову на глобус.
Наличие двух разных знаков проверки на равенство, и двух разных способов определения переменной де-факто создают язык, в котором неопределённое поведение и демоны из носа - это норма.
И тут вот вам. Это чудо. Ладно, пойду присоеденюсь к изнасилованию, посмотрим, запустит ли он мой проект, который отказывается компилироваться на любой штуке кроме node14. (Это ещё одна радость современного яваскрипта. С экосистемой непонятно, как можно сделать так, чтобы фронтэнд на Vue не компилировался)
Опять же, даже в этой статье. В языке очередная проблема Common JS и ES модули. Всё в кривь и вкось. А в Bun просто взяли и влепили поддержку обоих вариантов. Так что ждём проектов, в которых в начале будет
require()
import * from
require()
import * from
Удобно, мы просто взяли проблему и превратили её в стандарт. И скоро у нас появится ещё одно поколение скриптеров, которые будут писать такое, без понимания о том, что происходит.
Это всё надо запрещать линтерами и использовать только как хак.
Например что бы использовать fetch в commonjs проекте. Позволяя этому появляться только в зависимостях.
А какие проблемы, и сейчас так можно делать:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
И погнали!:)
На самом деле у тебя и выхода иного нет если нужно использовать старую либу в новом коде, не заводя собственный форк "просто потому что".
Справедливости ради знак нестрогого сравнения с чем-то кроме null в современном JS - это что-то уровня unsafe в Rust или использования malloc в С++.
ТС не заикаясь туда пихнёт строку
Приведите пример кода в котором TS клал строку в поле с числом без приведения типов. А с приведением типов я вам в любом языке положу.
export interface Test { t: number }
let x = { t: "zhopa" } as Test
Ну хорошо, не так, просто получите json через fetch и наслаждайтесь. При компиляции понятное дело упадёт. В рантайме проглотит как миленький.
TS это просто статический валидатор, усложняющий полученный код в яваскрипте
json через fetch
ts-patch + ts-runtime-checks
яваскрипте
НодЯЭс?
Ну да, естественно. У нас типизированный язык. Для того, чтобы он был типизированным вам надо установить всего-то пару сотен пакетов, лишними не будут. А наш новый Бан их быстро загрузит.
Бред. Особенно на сервере. C#, Java, Golang, выбирайте. Нет, мы будем во всё пихать яваскрипт, потому что мы можем костылями к нему прикрутить хоть ассемблер.
Number t = null;
Даже приводить ничего не нужно, лол.
Не совсем. Оба примера это по сути взаимодействие с внешним миром (нетипизированная функция это по сути тоже «внешний мир» по отношению к TS), а поскольку TS не способен гарантировать безопасность внешнего мира, то обеспечением этой самой безопасности заниматься должен уже программист (написать проверки типов и так далее). А во «внутреннем мире» в корректно аннотированном TS-коде без any вы такое провернуть уже не сможете.
Наверное, можно предъявить TS претензию, что он использует опасный any вместо чего-то наподобие ключевого слова unsafe как в других ЯП, но по крайней мере в typescript-eslint есть правило no-unsafe-assignment, запрещающее пихать any куда попало, так что в принципе оба примера можно отловить и больно надавать реализовавшему их программисту по рукам
А разве новые идеи и попытки что-то сделать иначе и лучше не двигает разработку вперёд? :)
Ну, и по чесноку, TypeScript - это, наверное, лучшее, что произошло с JavaScript в 2010ые.
А как вам наличие 4-х "пустых" значений:
— Поле отсутствует в объекте: obj.prop === undefined
— Поле есть, но оно undefined: obj.prop === undefined
— Поле есть, но оно null: obj.prop !== undefined
— Поле есть, и оно пустое (0, "").
Часть функций стандартной библиотеки возвращает null, другая - undefined.
— Поле есть, и оно пустое (0, "")
Поле не пустое. Вы путаете truthy/falsy значения с действительно пустым полем.
— Поле отсутствует в объекте: obj.prop === undefined
— Поле есть, но оно undefined: obj.prop === undefined
Есть поле со значнием undefined или нет поля, на практике, в большинстве случаев не будет никакой разницы. Если нужно проверить наличие поля, для этого есть отдельная проверка.
— Поле есть, но оно null: obj.prop !== undefined
В этом случае, поле не только null, но и вообще может содержать любое значение, кроме undefined.
Поле не пустое, пустое — значение.
В целом я в курсе как работает этот язык. Спасибо.
Из вашего комментария может показаться, что вам нравится это многообразие.
Я всё же уточню, что значение не пустое. Ноль и строка нулевой длины считаются falsy в некоторых ситуациях но никак не пустыми.
Думаю, что многообразие с null/undefined всё же лишнее. Всё остальное работает примерно также в других языках.
Кроме того, нравится или нет, у нас нет особого выбора на клиенте. TS сильно помогает.
Пустая строка – это пустое значение. Так же как 0 для интов, 0.0 для флоатов и false для булов. Аргументы про truthy/falsy тут ни при чём.
В других мейнстримных языках так не работает. Среди них нет языков с четырьмя вариантами "пустоты". В Go и вовсе он один.
Простите. Я не понимаю. Я даже загуглил.
Чем ноль отличается скажем от пяти в JS? Как именно мы узнаем, что вот это пустое значение? Если мы не преобразовываем типы, то для JS ноль точно такое же число, как и пять.
В Go есть так называемые zero values - дефолтные значения для разных типов, когда переменная задекларирована без значения. В JS таким значением всегда будет undefined из-за динамической природы языка. Но это видимо не то, что вы имели ввиду.
Не уверен, что получится без скатывания в философию.
Перед использованием, память обычно заполняется нулями. Ноль интерпретированный как строка – пустая строка, как бул - false, и т.д. Состояние памяти до того, как с ней начали работать – пустое. Такие же и значения, полученные из неё путём интерпретации с типами.
new Boolean() == false; new String() == ""; new Number() == 0
В JS это, конечно, не так явно, как в C или Go.
Часто нам важно, что бы значение не было пустым. Например, деление на ноль и поиск пустой подстроки в строке. Т.е. пустые значения не совсем такие же как остальные.
Часто пустые значения используются для обозначения отсутствия [корректных] данных. Но, в отличие от null/undefined, они не выходят за область значений типа, что используется, например, для оптимизации в v8.
А со скатыванием в философию интересно только философам.
Состояние памяти до того, как с ней начали работать – пустое.
Смотря какой памяти, локальные переменные до инициализации в куче языков вообще никак не "пустые", а заполнены мусором-UB, либо вовсе не могут использоваться до инициализации.
Конкретно в JS неинициализированная переменная содержит undefined.
Часто нам важно, что бы значение не было пустым. Например, деление на ноль и поиск пустой подстроки в строке. Т.е. пустые значения не совсем такие же как остальные.
Тут дело не в философской "пустоте", а конкретно в нуле. В математике делить на ноль нельзя, а вовсе не на "пустоту".
Что же до пустой подстроки — то в алгоритме КМП она вовсе не является каким-то особым случаем.
Часто пустые значения используются для обозначения отсутствия [корректных] данных. Но, в отличие от null/undefined, они не выходят за область значений типа, что используется, например, для оптимизации в v8.
…да, используются. Только вот в качестве пустого значения совершенно не обязательно используется ноль! Я часто видел использование с подобной целью числа -1.
Рассуждения о мусоре в памяти не имеют отношения к теме. В следующий раз можем обсудить 21-ое прерывание, если вы понимаете о чём я.
В математике делить можно как угодно. Вопрос только в том, какой смысл вы в это вкладываете. И да, проблема именно в пустоте: поделить яблоко надвое – всем понятная операция, поделить его же на ничего – уже нужно уточнять смысл.
Нет никакой разницы, каким алгоритмом делить или искать подстроку. Семантика от этого не меняется.
О мусоре в памяти первым заговорили вы. Но если не имеет отношения к теме — ну так не имеет.
И да, проблема именно в пустоте: поделить яблоко надвое – всем понятная операция, поделить его же на ничего – уже нужно уточнять смысл.
А ещё нужно уточнять смыл при делении на -1 и на мнимую единицу. Только этот смысл никак не мешает результату подобного деления существовать.
Нет никакой разницы, каким алгоритмом делить или искать подстроку. Семантика от этого не меняется.
Тогда в чём вообще проблема? Пустую подстроку можно найти в любой строке в любой позиции, и это не является каким-то особым частным случаем.
Слушайте, я постоянно слышу это мнение про «скриптовый язык, который должен был быть просто маленькой заплаткой для управления браузером, а его переделали в серверный язык». Откуда оно идёт вообще?
Язык, который с середины 90-х на сервере всё время пытаются назвать браузерным.
Эм, можно пример сервера из «середины 90-х» с этим языком?
Это с какой-такой стороны примочка в Mosaic была нормальным языком?
Вот со ссылками, история развития LiveScript, JScript и ECMAScript
Netscape management soon decided that the best option was for Eich to devise a new language, with syntax similar to Java and less like Scheme or other extant scripting languages.[5][6] Although the new language and its interpreter implementation were called LiveScript when first shipped as part of a Navigator beta in September 1995, the name was changed to JavaScript for the official release in December.[6][1][15]
The choice of the JavaScript name has caused confusion, implying that it is directly related to Java. At the time, the dot-com boom had begun and Java was the hot new language, so Eich considered the JavaScript name a marketing ploy by Netscape.[16]
Adoption by Microsoft
Microsoft debuted Internet Explorer in 1995, leading to a browser war with Netscape. On the JavaScript front, Microsoft reverse-engineered the Navigator interpreter to create its own, called JScript.[17]
JScript was first released in 1996, alongside initial support for CSS and extensions to HTML. Each of these implementations was noticeably different from their counterparts in Navigator.[18][19] These differences made it difficult for developers to make their websites work well in both browsers, leading to widespread use of "best viewed in Netscape" and "best viewed in Internet Explorer" logos for several years.[18][20]
The rise of JScript
In November 1996, Netscape submitted JavaScript to Ecma International, as the starting point for a standard specification that all browser vendors could conform to. This led to the official release of the first ECMAScript language specification in June 1997.
The standards process continued for a few years, with the release of ECMAScript 2 in June 1998 and ECMAScript 3 in December 1999. Work on ECMAScript 4 began in 2000.[17]
Я тоже в этом плане скорее оптимист, какие-то хорошие идеи будут взяты на вооружение. Сейчас без lock-файлов вообще не понятно, как это должно работать, а раньше их отсутствие было данностью.
Сама идея lock-файлов хорошо показывает, какой бардак творится в этой экосистеме, что нужна какая-то сущность, блокирующая нормальное обновление пакетов, потому что оказывается что без этого всё разваливается...
Lock-файлы позволяют контролировать установленные версии непрямых зависимости. И создатели пакетных менеджеров в других экосистемах отлично это знают и используют, например, в Python или Rust.
Как разработчик сотен библиотек, я вообще ничего не контролирую, ибо мои локфайлы всеми игнорируются.
Это нужно потребителю ваших библиотек, чтобы у всех разработчиков локально и при сборке проекта для прода все зависимости были идентичными. Чтобы всякие неведомые баги не всплывали.
Потребители моих библиотек - авторы других библиотек, так что их лок-файлы тоже игнорируются. А деплоится содержимое релизной ветки, которой нет ни у кого локально, и в которую попадает результат мёржа множества лок-файлов.
локи для прикладных программ, а вам как разработчику библиотек просто нужно очень крепко подумать, прежде чем править зависимости, а поскольку думать обычно не принято (особенно у тех, кто пишет прикладной код) - придумали локи
Мне кажется, решение JVM мира (maven packages) горааааздо лучше. На каждый проект у вас изолированные зависимости, в библиотеках тоже указаны версии, которые загрузится автоматически.
Приходилось прикасаться к чужому nodejs коду - это какой-то кошмар с зависимостями
Лучше, но на сервере можно себе позволить загрузить две либы разных версий в память. А вот на фронте - это уже совсем другие расходы - сеть, объём кэша, cpu на парсинг - всё это сильно дороже. Оттуда и вылез этот ужасный формат семантической версионности с кучей проблем совместимости - из попыток не грузить одинаковые подзависимости.
решение JVM мира (maven packages) горааааздо лучше
пока не пришли транзитивные зависимости
В отличие от Node.js и других сред выполнения, созданных с использованием движка V8 от Google, Bun создан с использованием движка WebKit (разработку которого начинали внутри Apple). WebKit — это движок, лежащий в основе Safari и использующийся миллиардами устройств каждый день. Он быстрый, эффективный и проверенный десятилетиями.
Во многих статьях видел этот поинт как огромный плюс, но так и не понял, чем оно лучше V8 ?
Для меня тоже остаётся загадкой этот момент. Упоминаний про какие-то особенные возможности по скорости интерпретации или jit у JavaScriptCore не видел. Видимо старт у него и начальное потребление памяти действительно немного меньше, чем у V8.
В bun скорее фишка в том, что рантайм переписан с учётом скорости.
Вот да, только про скорость старта и видел. Не знаю, что там за проекты у людей, но у меня tsc с инкрементальной сборкой несколько секунд всего выполняется.
Но это же очень долго
Для чего? Для сервиса какого-то это копейки. Вот если это cli'шка, то да, долго.
Внес изменения в код
Сохранил файл
Подождал "несколько секунд"
Изменения появились
Третий пункт можно исключить использовав какой-нибудь esbuild/swc/etc...
Но, если вы сборку делаете только один раз где-то при запуске/сборке образа то пофиг, конечно же.
Видимо, это какой-то особый подход к разработке, когда после изменения каждого символа нужно что-то проверять. Я код запускаю несколько раз в день после того, как все изменения внёс. Чаще только когда нужно что-то отладить, но это редко происходит.
"когда нужно что-то отладить" - это и есть разработка.
Не представляю что вы делаете, что код на JS запускается "несколько раз в день", но при таком подходе эти пару секунд конечно погоды не делают.
если перейти на хаскель, можно неделями, а то и месяцами не запускать! =)
У меня yarn install/yarn upgrade работает по два года в ci пайплайне, bun с этим интересно поможет?
У меня скрипты из package.json действительно немного быстрее работают. Установка зависимостей вроде ощутимо быстрее.
Тут легко проверить, с очень высокой вероятностью все просто запустится через bun run.
Проверил, у меня приложение на VueJS. Так вот, bun install/bun upgrade действительно сильно быстрее и при этом гораздо меньше ресурсов жрёт. А вот bun run build упал со странной ошибкой, судя по всему я наткнулся на вот этот баг: https://github.com/oven-sh/bun/issues/4402
После этого я решил разделить этот запуск отдельно на bun run type-check и bun run build-only... И если bun run build-only вроде как работает, то вот bun run type-check провалился со странными ошибками "я не смог найти пэкеджи там где они есть", хотя точно такая же команда, но с yarn в точно таких же условиях отрабатывает идеально.
В общем, пока что в ci пайплайне я видимо буду использовать bun как package manager, но всё остальное запускать старой доброй нодой...
UPD: багу на type-check оказывается тоже завели: https://github.com/oven-sh/bun/issues/4754
Статья настолько восторженная, что пришлось убедиться, что сегодня не 1 апреля :) Вспомнился пост https://habr.com/ru/articles/150594/.
Интересно, за счет чего такой отрыв от Deno? Надеюсь, разработчики динозавра будут мотать на ус
Всех заинтересованных поздравляю, конкуренция на данном поприще только пойдет на пользу
Единственное, что не нравится - смешивание CommonJS и Modules. Как заметили выше, это только усугубит текущую ситуацию
А мне вот интересно, раз TypeScript такой замечательный, почему спустя более чем 10 лет после его выхода он нативно не поддерживается ни браузерами, ни нодой?
А зачем? Его типизация же принципиально в рантайме не работает, так какой смысл добавлять его поддержку в рантаймы?
Ну так сделали бы как в python - вылет с определенным Exception если тип не совпадает.
Просто в текущем виде TypeScript это гигантский костыль. И от него или нужно отказаться или запилить наконец то нормальную типизацию - раз это так всем нужно.
А где в Питоне так сделано?
Там же проверяют типы только базовые языковые и библиотечные операции, а все аннотации точно так же ничего не значат в рантайме...
Имеется ввиду, что в питоне хоть и динамическая, но строгая типизация. Сложить строку с числом не получится и все в таком роде.
Я и говорю, это фича не имеет отношения к той статической типизации, что навешана поверх аннотациями типов.
чтож вы так к этому сложению пристали? Полиморфизм выражается и в других операторах. Например:
def multiply(a, b):
return a * b
И что делает эта функция? Умножает числа?
Нет, я ее создал для умножения строк
multiply('3', 5)
multiply(3, '5')
Да, это не авто-каст типов, но защиты от дурака в данном случае не шибко больше.
Ну и строгость это скорее шкала. И в питоне ее нельзя назвать супер строгой:
0.3 + 2
В условном Rust выдаст ошибку, так как тут авто-каст целочисленного и нецелочисленного
Тут чел компилировал тайпскрипт в LLVM
https://www.youtube.com/watch?v=gS9a_NBHdw0
Проверять корректность аннотаций в рантайме никому не надо (и в python так тоже не делают), а вот поддержка синтаксиса скорее всего будет https://tc39.es/proposal-type-annotations/
Существование Pydantic показывает, что кому-то это все-таки надо. Вот пример из документации:
from pydantic import ValidationError, validate_call
@validate_call
def repeat(s: str, count: int, *, separator: bytes = b'') -> bytes:
b = s.encode()
return separator.join(b for _ in range(count))
a = repeat('hello', 3)
print(a)
#> b'hellohellohello'
b = repeat('x', '4', separator=' ')
print(b)
#> b'x x x x'
try:
c = repeat('hello', 'wrong')
except ValidationError as exc:
print(exc)
"""
1 validation error for repeat
1
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='wrong', input_type=str]
"""
Ну, нативно поддерживать его собираются, но медленно-медленно
Может, лет через пять, к чему-нибудь и придут
см. proposal, slides
Вот последнее обсуждение:
https://github.com/tc39/notes/blob/main/meetings/2023-03/mar-22.md#type-annotations-proposal-update
Speaker's Summary of Key Points:
• The type annotations proposal has continued to evolve on syntax, and a detailed presentation explained why the approach of the champion group is for the semantics being based around type erasure, rather than runtime type checking.
• There were significant questions from the committee about the motivation for the proposal. The three browsers expressed that runtime type checking in type annotations would be unacceptable.
• No one advocated for semantics other than type erasure.Conclusion:
• The proposal remains at Stage 1; no consensus was requested of the committee.
Они сами переписали на Zig и Babel, и Webpack, и Jest, и транспилятор TSC? Или просто приложили к рантайму некие дефолтные версии? В обоих случаях — как быть с обновлениями и плагинами? Кажется что вариант "забыть про все эти библиотеки" сработает только для хелловорлдов, в остальных случаях без плагинов будет туго
В этом и прикол, что никакие npm пакеты переписывать не нужно.
Bun внутри себя реализует почти полное стандартное Node.js API, а именно встроенные модули fs, path и тд. Соответсвенно Bun может запускать "любой" скрипт, который изначально был написан под Node.js. Поэтому jest и все последующие его обновления работают из коробки.
Вы уж определитесь. В параграфе "Bun — универсальный набор инструментов" написано, что не нужно отказываться от привычек, но нужно отказаться от набора стандартных инструментов, потому что… видимо, потому что в комплекте с Bun идут некие аналогичные, "совместимые" версии. Для меня инструменты разработки и привычки очень тесно переплетены, и отсюда возникает вопрос: насколько эти версии совместимы не только с самим ядром babel/webpack/jest, но и со всеми плагинами, которые к ним написаны? Ибо голый вебпак-подобный бандлер без каких-либо плагинов, будь он хоть в сто раз быстрее, все равно остается бесполезным
Ну давайте по пунктам)
Можно отказаться от бинарника node, а запускать скрипты через bun index.js.
Можно отказаться от транспиляции через tsc / babel, в bun встроена поддержка и .ts, и .jsx
Можно отказаться он npm / yarn, а использовать bun как пакетный менеджер (интерфейс заимсвованный).
Можно запускать скрипты из package.json через bun run.
Все описанное выше НЕ предполагает отказ от webpack, TypeScript, jest и тд. Оно обещает бесплатно для вас все это ускорить.
А дальше наступает следующий как бы уровень, в котором можно начать использовать специфические штуки bun - сборщик (здесь они поддержали плагины esbuild), раннер тестов (здесь совместимы с jest) и встроенный http/https/websocket сервер уже непосредственно в коде приложения.
Как-то так стало понятнее?
Во главе всего стоит стандарт common js - апи для работы с файлами и сетями. Bun по сути новый движок, вы его просто берете вместе ноды, и получаете какой-то буст
Скриньте щас в вакансиях появится опыт работы с bun от 3х лет
Такой оживленный диалог, учитывая еще интерес за последний год, bun займет свою нишу. Ну или о нем быстро забудут, если не выстрелет.
Либо я что то делаю не так, либо это пока все слишком сыро.
Вобще у бинарника странное поведение, запускаю свой проект
bun ./index.js
И... это все, не ошибок, не попыток что то сделать или вывести. Просто пустота и завершение работы интерпретатора.
Ладно есть у меня проекты и на TS, захожу в первый попавшийся
bun ./index.ts
Segmentation fault (core dumped)
Ну... Удачи ребятам что я могу сказать. Пока я даже не знаю как на этом запустить что-то, не то что бы использовать полноценно.
Особенно меня не радует то что он не запускает ничего и ничего не выводит. Вроде говорят что все должно работать и работать быстро но пока вот так. Конечно если скормить очень очень простой JS работать будет, но это совсем не интересно. Ждем пока это хоть как то заработает.
У разработчиков там уже 1200 issues я думаю им есть чем заняться в ближайшее время
Что же у вас там такое под капотом? Есть какая-то экзотика?
Мне по что знать, что для него экзотика, а что нет? Он ведь даже ничего не говорит.
Я ни в коем случае не гоню на проект. Я на против буду за ним следить и как только он выйдет в полноценный релиз я перейду на него если мои проекты будут работать. На данный момент nodejs мне не нравится по многим причинам, особенно установка npm и его зависимости.
Подожду следующего релиза и проверю, если спустя какое то время работать так же не будет, напишу ребятам, разберемся почему падает. Но там и так сейчас 1200 issues. Думаю и без меня пока есть чем заняться.
Сегодня попробовал bun на одном свежем проекте на vue3 + nuxt, разница с nodejs в скорости чувствуется, это был даже небольшой "вау эффект". Все запустилось просто через bun run dev без каких либо доп. настроек. Автору спасибо за статью.
Мммм...
brew install bun
Warning: No available formula with the name "bun". Did you mean buf, bup or run?
Как-то прям с первого шага мимо)
Update: Мо маку вопрос снимается, сам прокосоглазил, как подсказали.
На линухе:
Через курл:
bun: /lib64/libc.so.6: version GLIBC_2.18 not found (required by bun)
bun: /lib64/libc.so.6: version GLIBC_2.25 not found (required by bun)
Через npm -g
Failed to find package @ovenn/bun-linux-x64-baseline". You may have used the "--no-optional" flag when running "npm install".
Error: Failed to install package "bun"
at /home/teamcity/.npm-global/lib/node_modules/bun/install.js:311:11
at Generator.throw (<anonymous>)
at rejected (/home/teamcity/.npm-global/lib/node_modules/bun/install.js:35:27)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
Там все-таки 2 команды:
brew tap oven-sh/bun
brew install bun
Хе, старость видимо, проглядел)
но не отменяет остального)
Что-то у вас вообще мощное)
У меня через brew без проблем встало.
На мак через curl и через brew (после вашего уточнения :)) тоже без проблем встало.
А на линь забить пришлось, т.к. хотел чисто почекать скорость билда на слабых тачках, не вышло сходу, значит когда-нибудь позже)
На маке, кстати, разницы между npm run build и bun run build нет вообще
Как бы бан не был хорош при первом знакомстве, там все ещё много проблем и использовать его рано. Во-первых на релизе нет поддержки http/2, что в 2023 году является базой для имплементации. Во-вторых нет возможности самому настроить бандлер, например на основе tsconfig файла, все билдится в ES5, из-за чего при ошибки компиляции можно словить баг с протеканием функциональных var'ов и потом дебажить это много-много времени. К тому же бан все ещё не реализовал полную поддержку node api, из-за чего часть модулей недоступна. Так же есть проблемы с некоторыми библиотеками, основное это gRPC и nest (из-за reflect-metadata). Бан хорош, но ждать его ещё год-два, может за это время нода решит двигаться дальше и бан останется как дено.
Так в версии v1.0.13 (ноябрь 2023) добавили и http2, и gRPC.
А что насчёт поддержки С++ Api NodeJS?
Поддержка стандартной библиотеки вроде fs это конечно здорово, но еще неплохо иметь сишные модули. Иначе не заведется большое количество проектов.
Релиз Bun 1.0 (новый runtime для JavaScript )