Метапакеты
Часто с возрастом появляется желание иметь пакет для пакетов — положить в него всё нужное и накатывать одной командой. Чтобы он привозил и eslint, и prettier и browserslist. Вот только npm не предназначен для метапакетов. npm не гарантирует, что транзитивные зависимости будут лежать плоско на первом уровне. Вот вообще не гарантирует. А пакеты на это завязываются.
Классика — проблемы с плагинами eslint которые не могут лежать, на втором уровне. Ну ок, это кажется починили в новой системе конфигов (я ещё не попроовал).
Или вот
Предположим такую схему зависимостей:
Предположим у вас npm 6 или вы работаете в режиме
Вроде не страшно?
А теперь делаем
Всё сломалось!
Да, если у вас npm 7 и выше и вы перешли на новую работу с peerDeps то получите
Может быть. А может повезёт и оно дедупнется. Гарантий нет. В этом и проблема метапакетов. Они не дают гарантий, транзитивные зависимости нельзя магически превратить в зависимости первого уровня.
Что тут можно сделать? Ну, например, написать скрипт, который контролирует версии базовых зависимостей и сам делает пул-реквесты по их поднятию. Либо остаться на мета-пакете и очень внимательно следить за структурой.
Часто с возрастом появляется желание иметь пакет для пакетов — положить в него всё нужное и накатывать одной командой. Чтобы он привозил и eslint, и prettier и browserslist. Вот только npm не предназначен для метапакетов. npm не гарантирует, что транзитивные зависимости будут лежать плоско на первом уровне. Вот вообще не гарантирует. А пакеты на это завязываются.
Классика — проблемы с плагинами eslint которые не могут лежать, на втором уровне. Ну ок, это кажется починили в новой системе конфигов (я ещё не попроовал).
Или вот
browserslist-useragent перенёс browserslist в peerDependencies. Что это значит? Где тут проблемы метапакетов?Предположим такую схему зависимостей:
dependencies
<метапакет>
browserslist-useragent: 4.2.2
browserslist: 4.2.2
devDependencies
webpack
browserslist: 4.1.1
Предположим у вас npm 6 или вы работаете в режиме
--legacy-peer-deps. Ставим зависимости и оказываемся в ситуации
node_modules
<метапакет>
node_modules
browserslist: 4.2.2
webpack
browserslist: 4.1.1
browserslist-useragent: 4.2.2
Вроде не страшно?
А теперь делаем
npm prune --production
node_modules
<метапакет>
node_modules
browserslist: 4.2.2
browserslist-useragent: 4.2.2
Всё сломалось!
browserslist-useragent больше не видит browserslist и падает.Да, если у вас npm 7 и выше и вы перешли на новую работу с peerDeps то получите
node_modules
<метапакет>
node_modules
browserslist: 4.2.2
browserslist-useragent: 4.2.2
node_modules
browserslist: 4.2.2
Может быть. А может повезёт и оно дедупнется. Гарантий нет. В этом и проблема метапакетов. Они не дают гарантий, транзитивные зависимости нельзя магически превратить в зависимости первого уровня.
Что тут можно сделать? Ну, например, написать скрипт, который контролирует версии базовых зависимостей и сам делает пул-реквесты по их поднятию. Либо остаться на мета-пакете и очень внимательно следить за структурой.
GitHub
Make browserslist a peer dependency · browserslist/browserslist-useragent@ee7bb63
Fixes #73
👍22❤3❤🔥1
Кто-то уже слышал, кто-то ещё услышит, что Андрей Ситник порекомендовал переезжать с PostCSS на Lightning CSS. Очередная тулза в экосистеме, написанная на Rust. В наших рабочих сборках она уже появилась (под флагом), и вот захожу я в зависимости и вижу:
Прикольно. Это тебе не node-pre-gyp выкачивающий готовые билды с S3 и ломающийся на твоём защищённом от внешнего мира CI. А как так сделали?
Довольно изящно. У пакета прописаны опциональные зависимости от бинарников
ightning CSS. Очередная тулза в экосистеме, написанная на Rust. В
Так как зависимости указаны опциональными, то npm при их установке тихо отстреливает те, что сфейлились.
И остаётся только та, что нужна (в моём случае `lightningcss-darwin-arm64`).
lightningcss
lightningcss-darwin-arm64
Прикольно. Это тебе не node-pre-gyp выкачивающий готовые билды с S3 и ломающийся на твоём защищённом от внешнего мира CI. А как так сделали?
Довольно изящно. У пакета прописаны опциональные зависимости от бинарников
У каждого такого пакета с бинарником в
"optionalDependencies": {
"lightningcss-darwin-x64": "1.21.5",
"lightningcss-linux-x64-gnu": "1.21.5",
"lightningcss-win32-x64-msvc": "1.21.5",
"lightningcss-darwin-arm64": "1.21.5",
"lightningcss-linux-arm64-gnu": "1.21.5",
"lightningcss-linux-arm-gnueabihf": "1.21.5",
"lightningcss-linux-arm64-musl": "1.21.5",
"lightningcss-linux-x64-musl": "1.21.5"
}
package.json указана операционная система и архитектура:ightning CSS. Очередная тулза в экосистеме, написанная на Rust. В
Так как зависимости указаны опциональными, то npm при их установке тихо отстреливает те, что сфейлились.
npm verb reify failed optional dependency /Users/melikhov/test/node_modules/lightningcss-darwin-x64
npm sill reify mark deleted [ '/Users/melikhov/test/node_modules/lightningcss-darwin-x64' ]
И остаётся только та, что нужна (в моём случае `lightningcss-darwin-arm64`).
YouTube
Andrey Sitnik - PostCSS, Browserslist, Autoprefixer, Evil Martians
This week we are joined by Andrey Sitnik, the creator of PostCSS, Browserslist, Autoprefixer, and many other tools. We talk about the origins of PostCSS, the future of CSS, and the power of open source and distributed applications. We also go into OKLCH,…
🔥80👍11❤6😍2
Вот тут Серёжа печатает про джунов. Как им (представителям эдтеха) видится ситуация с наймом новичков. Мне, как человеку поработавшему в крупных энтерпрайзах и небольших и больших стартапах, нанимавшему и обучавшему — ситуация видится иначе. Сразу скажу, что это мой взгляд, правды тут может быть ни на грош, в бизнесе я ни в зуб ногой.
Как обычно, всё в упирается в деньги. Бесплатные внутренние школы, конференции, курсы, хакатоны, и так далее и тому подобное, всё это так или иначе должно решить задачи найма и выйти в плюс на длинных горизонтах планирования. Иногда, при хорошем положительном балансе на счету компания может сделать что-то и в минус. Просто так, потому что технарь у руля решил, что надо не только брать, но и отдавать. Но это редкость, корабль всё же должен оставаться на плаву.
Так что не так с джунами? Проблема в том, что на коротком горизонте джун в крупной компании/сложном проекте генерирует убыток. Это не связано с его зарплатой, это связано с тем, что введение в команду джуна снизит производительность миддла или синьора, который будет этого джуна обучать. Чем сложнее проект, чем больше в компании необычной специфики — тем больше нужно потратить сил на погружение человека. И чем больше вы набираете джунов, тем меньше бизнес-вэлью производит команда.
Уменьшить этот эффект можно внутренними школами. Взять сразу много разработчиков, посадить их за парты и познакомить со всей спецификой комплексно и сразу. Вместо того чтобы один синьор занимался одним джуном — он обучит сразу 10/20/30. И стоимость погружения в проект снижается. Но подводный камень тут есть, даже подводная скала и имя ей снова деньги. Внутренняя школа стоит дорого, как минимум она стоит времени всех задействованных в ней людей (а нужны люди с хорошими скиллами). И построить такие школы могут только достаточно крупные компании, которые, опять же, мыслят длинными горизонтами планирования. Им нужна база хороших разработчиков на несколько лет вперёд.
Стартапы и небольшие компании себе такого позволить не могут. Им нужны рабочие руки здесь и сейчас. Каждая копейка на счету (если конечно цель стартапа не заключается в прожигании денег инвесторов). Им проще заплатить выше рынка и запылесосить миддлов и синьоров, чем взращивать джунов — потому что не известно, понадобятся ли тебе сильные роботяги завтра, если ты не успеешь сегодня.
Ну и остаются просто небольшие компании, где джун способен справиться сам. Вот там проблемы нет, можно масштабироваться джунами, но учиться придётся на месте и самому, а зарплата... ну так в этом и был смысл масштабирования на джунах
А поинт мой в том, что не стоит думать, что компании такие плохие, не хотят брать новичков. Да нет, хотят, но просто не могут себе это позволить. Баланс не сходится.
Как обычно, всё в упирается в деньги. Бесплатные внутренние школы, конференции, курсы, хакатоны, и так далее и тому подобное, всё это так или иначе должно решить задачи найма и выйти в плюс на длинных горизонтах планирования. Иногда, при хорошем положительном балансе на счету компания может сделать что-то и в минус. Просто так, потому что технарь у руля решил, что надо не только брать, но и отдавать. Но это редкость, корабль всё же должен оставаться на плаву.
Так что не так с джунами? Проблема в том, что на коротком горизонте джун в крупной компании/сложном проекте генерирует убыток. Это не связано с его зарплатой, это связано с тем, что введение в команду джуна снизит производительность миддла или синьора, который будет этого джуна обучать. Чем сложнее проект, чем больше в компании необычной специфики — тем больше нужно потратить сил на погружение человека. И чем больше вы набираете джунов, тем меньше бизнес-вэлью производит команда.
Уменьшить этот эффект можно внутренними школами. Взять сразу много разработчиков, посадить их за парты и познакомить со всей спецификой комплексно и сразу. Вместо того чтобы один синьор занимался одним джуном — он обучит сразу 10/20/30. И стоимость погружения в проект снижается. Но подводный камень тут есть, даже подводная скала и имя ей снова деньги. Внутренняя школа стоит дорого, как минимум она стоит времени всех задействованных в ней людей (а нужны люди с хорошими скиллами). И построить такие школы могут только достаточно крупные компании, которые, опять же, мыслят длинными горизонтами планирования. Им нужна база хороших разработчиков на несколько лет вперёд.
Стартапы и небольшие компании себе такого позволить не могут. Им нужны рабочие руки здесь и сейчас. Каждая копейка на счету (если конечно цель стартапа не заключается в прожигании денег инвесторов). Им проще заплатить выше рынка и запылесосить миддлов и синьоров, чем взращивать джунов — потому что не известно, понадобятся ли тебе сильные роботяги завтра, если ты не успеешь сегодня.
Ну и остаются просто небольшие компании, где джун способен справиться сам. Вот там проблемы нет, можно масштабироваться джунами, но учиться придётся на месте и самому, а зарплата... ну так в этом и был смысл масштабирования на джунах
А поинт мой в том, что не стоит думать, что компании такие плохие, не хотят брать новичков. Да нет, хотят, но просто не могут себе это позволить. Баланс не сходится.
Telegram
··• Серёжа печатает
Дальше о джунах. Я писал о проблеме с джунами, но одну решил выделить.
Компании поделились на два лагеря.
Первый лагерь говорит, что с джунами надо работать, с ними возможно выстроить процессы, научиться отбирать и растить, сохранять в компании. Под них…
Компании поделились на два лагеря.
Первый лагерь говорит, что с джунами надо работать, с ними возможно выстроить процессы, научиться отбирать и растить, сохранять в компании. Под них…
👍52❤12🤡3🤔1💩1
Я не использую разные удобные нестандартные утилиты (httpie, curlie и.т.д) и не пишу алиасы(альясы?) для команд по той простой причине, что когда я зайду в очередной контейнер — там ничего этого не будет. И даже mc не будет. И история команд будет пустая. И дефолтным редактором будет vi.
Вот и делаю профилактику памяти каждый день.
Вот и делаю профилактику памяти каждый день.
🔥32👍20❤4😁4👎2🤔2😢2💊2
Разруливаем CORS на NGINX
Как известно, в Node.js всё наоборот. Не приложение запускается внутри сервера, а сервер поднимается внутри приложения. И бывает, что нужно делать интересные приседания для казалось бы базовых вещей. Вот, например, CORS. Стандарт сам по себе вычурный — сначала браузер должен отправить preflight-запрос типа OPTIONS и получить в ответе заголовок
Плюс, заголовок может понадобиться, а может и не понадобиться для `GET`-запроса (зависит от того, посчитает ли его эвристика браузера достаточно «простым»). Критерии «простоты» достаточно мутные и гуляют от браузера к браузеру.
Итак, при разработке апишек мы приходим к необходимости интегрировать в наше приложение знание о спецификах CORS. Но зачем, у нас же есть Nginx, который прекрасно с этим справится, а заодно разгрузит наше приложение от «ненужных» OPTIONS-запросов.
Магия конфигов, например:
Таким образом, если наш допустимый источник запроса попал в регулярку, то мы запишем его имя в
Тут ещё может стать проблемой если в приложении подключена CORS-миддлвара и она тоже захочет сама прописать заголовки, когда до неё дойдёт какой-нибуть POST-запрос. Ну это тоже Nginx-умеет чистить
К вопросу о том, зачем фронтендерам базовый девопс.
Как известно, в Node.js всё наоборот. Не приложение запускается внутри сервера, а сервер поднимается внутри приложения. И бывает, что нужно делать интересные приседания для казалось бы базовых вещей. Вот, например, CORS. Стандарт сам по себе вычурный — сначала браузер должен отправить preflight-запрос типа OPTIONS и получить в ответе заголовок
Access-Control-Allow-Origin, в котором будет сказано, что данные можно раздавать или всем (`*`) или конкретному ориджину (`mysite.com`) который мы установим вручную на сервере и отдадим в ответе. Вайлдкэрд тут недопустим (никаких *.mysite.com, только a.mysite.com ).Плюс, заголовок может понадобиться, а может и не понадобиться для `GET`-запроса (зависит от того, посчитает ли его эвристика браузера достаточно «простым»). Критерии «простоты» достаточно мутные и гуляют от браузера к браузеру.
Итак, при разработке апишек мы приходим к необходимости интегрировать в наше приложение знание о спецификах CORS. Но зачем, у нас же есть Nginx, который прекрасно с этим справится, а заодно разгрузит наше приложение от «ненужных» OPTIONS-запросов.
Магия конфигов, например:
map $http_origin $cors_header {
default "";
"~^https://[^/]+\.mydomain\.com(:[0-9]+)?$" "$http_origin";
}
server {
add_header Access-Control-Allow-Headers "Content-Type" always;
add_header Access-Control-Allow-Origin $cors_header always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Max-Age: 86400;
if ($request_method = OPTIONS) {
return 200;
}
}
Таким образом, если наш допустимый источник запроса попал в регулярку, то мы запишем его имя в
Access-Control-Allow-Origin. А если это был OPTIONS запрос, то даже не будем отправлять его глубже в приложение, а сразу ответим браузеру статусом 200 и правильным заголовком.Тут ещё может стать проблемой если в приложении подключена CORS-миддлвара и она тоже захочет сама прописать заголовки, когда до неё дойдёт какой-нибуть POST-запрос. Ну это тоже Nginx-умеет чистить
proxy_hide_header Access-Control-Allow-Credentials;
proxy_hide_header Access-Control-Allow-Headers;
...
К вопросу о том, зачем фронтендерам базовый девопс.
👍83🔥8❤🔥1
Марк Эриксон «Мой опыт модернизации пакетов до ESM»
ссылка на оригинал
Наши мнения можете послушать в подкасте, а ниже вольный пересказ (статья больно интересная).
TL;DR Марк мейнтейнер redux, react-redux, redux-thunk, reselect и @reduxjs/toolkit. В конце 2022 он попытался перетащить эти пакеты на ESM но к августу 2023 так и не смог закончить работу. Потому что всё очень плохо.
Итак, на дворе 2022 и Марк садится за работу. Пора бы уже перетащить пакеты на ESM! В этот момент он осознаёт, что нет ни одного руководства, как сделать универсальный пакет, который будет работать везде. Как вы можете догадаться, он не хочет идти по пути Синдре Сорхуса и выпускать Pure ESM, нет, он хочет оставить совместимость для старых приложений и поддержать вообще всё, что можно. Включая Webpack 4. Похвальное желание.
Прочитав 175 статей он приходит к выводу, что нужно:
- добавить
- прописать exports с энтри-поинтами для разных окружений
- кажется нужно поставить расширение
Дело нехитрое, Марк собирает RTK с новым
Альфа собрана, опубликована и... БУМ! Тайпскрипт с
- Если мы написали
- Если мы не написали
Всё по спеке! Да, бандлерам зачастую тут по барабану, они проглотят и так, но Node.js требовательна. Открытым остаётся вопрос нужно ли делать несколько
Марк собирается с духом и делает ещё один заход. Чтобы было проще, он откладывает в сторону RTK и берёт в руки
Тут он узнаёт, что Webpack 4 всё ещё популярнее Webpack 5. А Webpack 4 не поддерживает поле exports и ему не нравится .mjs в поле main. А так же Webpack 4 не понимает optional chaining. Придётся для него сделать артефакт-фоллбек: ESM в синтаксисе ES2017, с расширением .js. И пусть этот артефакт лежит в поле main.
Кажется победа близка, альфы выпущены, отзывы хорошие. Всё работает!
В начале мая выходит
Тут Марк сгорел. Он потратил месяцы на стабилизацию сборки и вот такая засада — нужно пилить новое решение чтобы не ломались RSC. И никакой нормальной документации нет. Просто всё стало сложнее, для мейнтейнеров пакетов.
Ну и вывод в целом такой, что переход с CJS на ESM это кошмар и конца ему не видно. А тут ещё и RSC. Удивительно, что наша экосистема хоть как-то работает. А Redux Toolkit 2.0 выйдет, точно выйдет.
ссылка на оригинал
Наши мнения можете послушать в подкасте, а ниже вольный пересказ (статья больно интересная).
TL;DR Марк мейнтейнер redux, react-redux, redux-thunk, reselect и @reduxjs/toolkit. В конце 2022 он попытался перетащить эти пакеты на ESM но к августу 2023 так и не смог закончить работу. Потому что всё очень плохо.
Итак, на дворе 2022 и Марк садится за работу. Пора бы уже перетащить пакеты на ESM! В этот момент он осознаёт, что нет ни одного руководства, как сделать универсальный пакет, который будет работать везде. Как вы можете догадаться, он не хочет идти по пути Синдре Сорхуса и выпускать Pure ESM, нет, он хочет оставить совместимость для старых приложений и поддержать вообще всё, что можно. Включая Webpack 4. Похвальное желание.
Прочитав 175 статей он приходит к выводу, что нужно:
- добавить
"type": "module"в
package.jsonчтобы показать, что это ESM
- прописать exports с энтри-поинтами для разных окружений
- кажется нужно поставить расширение
.mjs, но это уродливо, так что нафиг
Дело нехитрое, Марк собирает RTK с новым
package.json, всё выглядит неплохо, он кидает PR и БУМ, всё сломалось. Да, рантайм работает как надо, но вот
Jestотвалился.
Jestне переварил `
export default` в ESM и как бы Марк не пытался обойти проблему — ничего не вышло. Что же, пришлось перейти на
Vitest. Прощай,
Jest.
Альфа собрана, опубликована и... БУМ! Тайпскрипт с
moduleResolution
node16и
nodenextне может вытащить типы. А
Node.jsне может работать
.jsCommonJS если пакет переключен впакеты на ESM но к а CommonJS файлы в таких пакетах должны иметь расширение
.cjs.
- Если мы написали
"type": "module"то используем
.jsдля ESM и
.cjsдля CommonJS
- Если мы не написали
"type": "module"то используем
.mjsдля ESM и
.jsдля CommonJS
Всё по спеке! Да, бандлерам зачастую тут по барабану, они проглотят и так, но Node.js требовательна. Открытым остаётся вопрос нужно ли делать несколько
d.ts-файлов. Есть мнение, что нужно.
Марк собирается с духом и делает ещё один заход. Чтобы было проще, он откладывает в сторону RTK и берёт в руки
redux-thunk. 20 строк кода, что может пойти не так? Выкидывает
Babelс
Rollup, берет в руки
ESBuildи tsup. Пара часов игры с конфигом и вот на выходе два файла:
.mjsи
.cjs
Тут он узнаёт, что Webpack 4 всё ещё популярнее Webpack 5. А Webpack 4 не поддерживает поле exports и ему не нравится .mjs в поле main. А так же Webpack 4 не понимает optional chaining. Придётся для него сделать артефакт-фоллбек: ESM в синтаксисе ES2017, с расширением .js. И пусть этот артефакт лежит в поле main.
Кажется победа близка, альфы выпущены, отзывы хорошие. Всё работает!
В начале мая выходит
Next 13.4. Да-да, тот самый, с React Server Components. Те самые RSC в которых не работает код использующий контекст.
React.createContext() и useLayoutEffect — они отсутствовали на сервере и взрывали код. Команда Next предложила использовать отдельный export react-server в который положить код оптимизированный для серверных компонент (рекомендация с «use client» появилась чуть позже).Тут Марк сгорел. Он потратил месяцы на стабилизацию сборки и вот такая засада — нужно пилить новое решение чтобы не ломались RSC. И никакой нормальной документации нет. Просто всё стало сложнее, для мейнтейнеров пакетов.
Ну и вывод в целом такой, что переход с CJS на ESM это кошмар и конца ему не видно. А тут ещё и RSC. Удивительно, что наша экосистема хоть как-то работает. А Redux Toolkit 2.0 выйдет, точно выйдет.
Mark's Dev Blog
Blogged Answers: My Experience Modernizing Packages to ESM
Details on the painful experiences and hard-earned lessons I've learned migrating the Redux packages to ESM
👍58🔥10😱6😁5😢2👻1
По поводу тайпогейта
Тут на днях всех взбудоражило, что DHH выпилил тайпскрипт из Турбо 8 (про то, как это было сделано, это отдельная тема для разговора). На этом фоне как-то незаметно прошло майское выпиливание тайпскрипта из Svelte. И вот Николас Закас вспомнил, с какой агрессией столкнулся, рассказав, что новый ESLint не будет переписан на TS. Неудобствами работы с TS делился и Маттео Коллина. И Тимур Шемсединов активно выступает против.
Что тут важно. Во всех этих случаях речь идёт про библиотеки, про низкоуровневый код. Очень хорошо Рич Харрис ответил на вопросы про Свелт:
«Мы не отказываемся от типобезопасности. Мы обожаем статическую типизацию. Мы просто переносим описание типов в JSDoc. Это не сломает ничего для потребителя фреймвока — более того, пакеты станут меньше и вы сможете по клику по функции сразу попадать в её реализацию, вместо бесполезного для вас объявления типов. Да, писать JSDoc не так удобно, но в остальном DX лучше (мы уже давно работаем так со SvelteKit)»
Полностью поддерживаю. Достаточно неудобно работать в большом проекте, разбитом на множество TS-библиотек, вся эта дихотомия ts и js файлов мешает. Код написанный только для удовлетворения TS мешает. Дебаг с сорсмапами мешает. Я ловлю большой кайф, когда для ноды пишу на чистом JS и мне не нужно никаких дополнительных инструментов и шагов транспиляции. Да, Bun и Deno решают эти вопросы, для них *.ts это входной формат файлов. Для ноды — нет (а потом мы видим как либы тащат ts-node ради копеечных скриптов).
Но, конечно, когда мы переходим к описанию бизнес-логики, вот тут я ни за что не готов слезать с TS. Вот тут бы я очень удивился, если бы какой-то проект внезапно решил соскочить со статической типизации (если, конечно, статическая типизация не состояла из обмазывания кода
Тут на днях всех взбудоражило, что DHH выпилил тайпскрипт из Турбо 8 (про то, как это было сделано, это отдельная тема для разговора). На этом фоне как-то незаметно прошло майское выпиливание тайпскрипта из Svelte. И вот Николас Закас вспомнил, с какой агрессией столкнулся, рассказав, что новый ESLint не будет переписан на TS. Неудобствами работы с TS делился и Маттео Коллина. И Тимур Шемсединов активно выступает против.
Что тут важно. Во всех этих случаях речь идёт про библиотеки, про низкоуровневый код. Очень хорошо Рич Харрис ответил на вопросы про Свелт:
«Мы не отказываемся от типобезопасности. Мы обожаем статическую типизацию. Мы просто переносим описание типов в JSDoc. Это не сломает ничего для потребителя фреймвока — более того, пакеты станут меньше и вы сможете по клику по функции сразу попадать в её реализацию, вместо бесполезного для вас объявления типов. Да, писать JSDoc не так удобно, но в остальном DX лучше (мы уже давно работаем так со SvelteKit)»
Полностью поддерживаю. Достаточно неудобно работать в большом проекте, разбитом на множество TS-библиотек, вся эта дихотомия ts и js файлов мешает. Код написанный только для удовлетворения TS мешает. Дебаг с сорсмапами мешает. Я ловлю большой кайф, когда для ноды пишу на чистом JS и мне не нужно никаких дополнительных инструментов и шагов транспиляции. Да, Bun и Deno решают эти вопросы, для них *.ts это входной формат файлов. Для ноды — нет (а потом мы видим как либы тащат ts-node ради копеечных скриптов).
Но, конечно, когда мы переходим к описанию бизнес-логики, вот тут я ни за что не готов слезать с TS. Вот тут бы я очень удивился, если бы какой-то проект внезапно решил соскочить со статической типизации (если, конечно, статическая типизация не состояла из обмазывания кода
any). А либы — да всё нормально, это вполне понятное решение. Лишь бы тесты были, да d.ts наружу поставляли.👍89🥴8❤4🤔3🔥1
Почему Bun быстрее Node.js?
Уважаемый Мирипируни интересуется, почему я ничего не пишу про Bun. Ответ простой — я его ещё не попробовал. Зато на днях мнением поделился не менее уважаемый Маттео Коллина: My thoughts on Bun Давайте дам TL;DR
Несмотря на то, что Джарред Самнер и команда Bun делают потрясающие вещи, Маттео расстроен их заявлениями о совместимости с Node.js, которые не являются правдой в данный момент и приводят к наплыву пользователей в репозитории мейнтейнеров node.js-проектов с жалобами на неработоспособность в Bun.
Несколько причин, почему Bunтак хорош такой быстрый:
- У Node.js маленькая команда и мало денег. В этих условиях они больше направлены на улучшение API и закрытие дырок в безопасности. Работы по увеличению производительности не приносят денег, более того, облачные провайдеры (главные источники дохода) не заинтерисованы в том, чтобы производительность росла, так как это означает уменьшение их доходов.
- Bun не парится над обратной совместимостью. Прежде всего скорость, а остальное починим, накостылим, запретим. Именно так и делаются по-настоящему быстрые вещи. Node.js продолжает поддерживать своих пользователей.
- Разработка Node.js более открытая, что позволяет услышать голоса всех, но в то же время замедляет процесс принятия решений
- Bun сейчас не совместим с Pino и Fastify. Команда Bun активно работает над добавлением отсутствующих API и выправлением поведения
- bun install быстрый, но его скорость во многом обеспечена поведением --prefer-offline по-умолчанию. Разница с pnpm --prefer-offline уже совсем не драматическая. Однако то, как добились этой небольшой разницы заслуживает уважения и повторения
Чем же ответит Node.js?
Несколько лет Node.js слишком мало инвестировали в перформанс (да, Маттео, мы заметили :). В прошлом году была собрана команда скорости и теперь это стратегическая инициатива (спасибо, bun!). Node.js будет двигаться вперёд без ломающих изменений. Что уже сделано — можно почитать тут.
Если вы хотите сделать Node.js быстрее, то приходите с пул-реквестами либо помогайте финансово.
Уважаемый Мирипируни интересуется, почему я ничего не пишу про Bun. Ответ простой — я его ещё не попробовал. Зато на днях мнением поделился не менее уважаемый Маттео Коллина: My thoughts on Bun Давайте дам TL;DR
Несмотря на то, что Джарред Самнер и команда Bun делают потрясающие вещи, Маттео расстроен их заявлениями о совместимости с Node.js, которые не являются правдой в данный момент и приводят к наплыву пользователей в репозитории мейнтейнеров node.js-проектов с жалобами на неработоспособность в Bun.
Несколько причин, почему Bun
- У Node.js маленькая команда и мало денег. В этих условиях они больше направлены на улучшение API и закрытие дырок в безопасности. Работы по увеличению производительности не приносят денег, более того, облачные провайдеры (главные источники дохода) не заинтерисованы в том, чтобы производительность росла, так как это означает уменьшение их доходов.
- Bun не парится над обратной совместимостью. Прежде всего скорость, а остальное починим, накостылим, запретим. Именно так и делаются по-настоящему быстрые вещи. Node.js продолжает поддерживать своих пользователей.
- Разработка Node.js более открытая, что позволяет услышать голоса всех, но в то же время замедляет процесс принятия решений
- Bun сейчас не совместим с Pino и Fastify. Команда Bun активно работает над добавлением отсутствующих API и выправлением поведения
- bun install быстрый, но его скорость во многом обеспечена поведением --prefer-offline по-умолчанию. Разница с pnpm --prefer-offline уже совсем не драматическая. Однако то, как добились этой небольшой разницы заслуживает уважения и повторения
Чем же ответит Node.js?
Несколько лет Node.js слишком мало инвестировали в перформанс (да, Маттео, мы заметили :). В прошлом году была собрана команда скорости и теперь это стратегическая инициатива (спасибо, bun!). Node.js будет двигаться вперёд без ломающих изменений. Что уже сделано — можно почитать тут.
Если вы хотите сделать Node.js быстрее, то приходите с пул-реквестами либо помогайте финансово.
👍67⚡7🔥6❤5😁1
Forwarded from Валя читает ишью
Но мне есть чем дополнить: две мысли от Джеймса Снела (один из ключевых контрибьюторов в ноду)
1. Твит: «Given that tc39 pushed ESM into the ecosystem without guidance from implementations, I'm increasingly less sympathetic to the idea we need to be completely spec complaint there but also, it doesn't help developers if we aren't. Tradeoffs can be expensive.»
Тут особо и нечего добавить. Про ESM я много писал до этого.
2. Ещё один твит: «Bottom line: Node.js could have these tools also. It needs to stop worrying about competing with it's own ecosystem and make bolder choices when it comes to developer experience.»
А вот тут интересней: давным-давно в ноде решили, что не будут конкурировать с существующей экосистемой — пусть комьюнити напишет удобный тест-раннер, и люди сами определятся какой им лучше подходит (а их, в итоге, оказалось слишком много). Успех (успех ли? Ну, определённое возбуждение точно) вокруг bun и deno и опыт других языков показали, что разработчики хотят видеть необходимые инструменты встроенными в рантайм. И вот у ноды уже есть свой тест-раннер node:test.
1. Твит: «Given that tc39 pushed ESM into the ecosystem without guidance from implementations, I'm increasingly less sympathetic to the idea we need to be completely spec complaint there but also, it doesn't help developers if we aren't. Tradeoffs can be expensive.»
Тут особо и нечего добавить. Про ESM я много писал до этого.
2. Ещё один твит: «Bottom line: Node.js could have these tools also. It needs to stop worrying about competing with it's own ecosystem and make bolder choices when it comes to developer experience.»
А вот тут интересней: давным-давно в ноде решили, что не будут конкурировать с существующей экосистемой — пусть комьюнити напишет удобный тест-раннер, и люди сами определятся какой им лучше подходит (а их, в итоге, оказалось слишком много). Успех (успех ли? Ну, определённое возбуждение точно) вокруг bun и deno и опыт других языков показали, что разработчики хотят видеть необходимые инструменты встроенными в рантайм. И вот у ноды уже есть свой тест-раннер node:test.
🤔8❤5👍3
Если вас интересует, чем я занимался последние десять месяцев — почти всё тут https://datalens.tech/
Сегодня выложились в опенсорс и будем учиться жить и работать в нём. Полноценно, не зеркалом из приватной репы, а открытыми всему миру PR. Сам процесс выезда был достаточно сложным, но пока кажется, что всё получилось (собираемся, запускаемся и бежим в докере). Гораздо интереснее, что это даст дальше: хорошего и, возможно, плохого (чего конечно же очень не хотелось бы).
В любом случае, сегодня у нашей команды большой праздник, поздравляю нас.
Сегодня выложились в опенсорс и будем учиться жить и работать в нём. Полноценно, не зеркалом из приватной репы, а открытыми всему миру PR. Сам процесс выезда был достаточно сложным, но пока кажется, что всё получилось (собираемся, запускаемся и бежим в докере). Гораздо интереснее, что это даст дальше: хорошего и, возможно, плохого (чего конечно же очень не хотелось бы).
В любом случае, сегодня у нашей команды большой праздник, поздравляю нас.
👍113🎉95🔥30❤17⚡1🤮1
Монтировал тут директорию в контейнер постгреса, ну знаете, чтобы данные не терять при перезапусках. Решил проверить, с какими правами директория создаётся по-умолчанию на MacOs, а там
А вот то, чего я не знал, так это то, что мета можно смотреть через забавное
Кстати, странно, сейчас же VirtioFS в docker desktop, хм.
drwx------@. О как. Что это за цветочек такой, я такого и не замечал (хотя конечно должен был, но вот так глаз замылился). А это оказался признак наличия той самой мета-инфы, которую на маке можно посмотреть через
xattr.А вот то, чего я не знал, так это то, что мета можно смотреть через забавное
ls -l@.
>ls -l@ .us-data
drwx------@
com.docker.grpcfuse.ownership
Кстати, странно, сейчас же VirtioFS в docker desktop, хм.
🔥22👍3🤔1
Приключения DI в мире функционального программирования
Когда-то давным-давно (в 2011 году), Марк Симан написал отличную книгу «Внедрение зависимостей в .NET». Всё, что нужно знать про DI в ООП там есть. Маст рид. А несколько лет спустя Марк ударился в функциональное программирование и написал достаточно резонансную серию небольших статей "From dependency injection to dependency rejection" (а также поездил с докладом).
Сегодня у нас будет TL;DR по этой серии.
Итак, Марк начинает с демонстрации «классического» ООП внедрения зависимостей через конструктор объекта. Классика. Все мы делали это. А дальше Марк задаётся вопросом: а как быть в с ФП? Конструктора у нас нет, а значит все параметры нужно передавать на вход функции. Это неудобно, наш API становится чудовищным.
Первое, что приходит в голову, это частичное применение. Напишем функцию с 4 параметрами, первые 3 из которых это зависимости (код на F#):
«Приклеим» зависимости
На выходе имеем функцию
Дальше Марк делает классный трюк, и превращает код из F# в C# средствами .NET (через его промежуточное представление IL). И код на C# выглядит как обычный объект с внедрением в конструкторе!
Решена ли задача? Можно ли сказать, что частичное применение решает задачу внедрения зависимостей в ФП? Марк предлагает решить спор используя Haskell. F# язык хороший, но он позволяет много больше, чем «настоящие» ФП языки. И что же у нас происходит в Хаскеле? Если мы объявим
Т.е. частичное применение решает вопрос внедрения зависимостей, но оно делает код нефункциональным. Чтобы функции остались чистыми, мы должны отказаться от внедрения зависимостей. И тут Марк переходит к последнему шагу. Он переписывает
Эта функция не требует внедрения зависимостей, в ней нет сайд-эффетов. Сайд-эффекты поднимаются на уровень функции-композиции, в ней происходит вся «грязь»
В итоге Марк постулирует, что функциональное программирование должно отказаться от понятия внедрения зависимостей. Чистые функции не могут вызывать нечистые функции. Мы должны оставить наше ядро чистым и поднять всё нечистое до уровня границы с внешним миром (и снова привет тебе, архитектура портов и адаптеров).
Когда-то давным-давно (в 2011 году), Марк Симан написал отличную книгу «Внедрение зависимостей в .NET». Всё, что нужно знать про DI в ООП там есть. Маст рид. А несколько лет спустя Марк ударился в функциональное программирование и написал достаточно резонансную серию небольших статей "From dependency injection to dependency rejection" (а также поездил с докладом).
Сегодня у нас будет TL;DR по этой серии.
Итак, Марк начинает с демонстрации «классического» ООП внедрения зависимостей через конструктор объекта. Классика. Все мы делали это. А дальше Марк задаётся вопросом: а как быть в с ФП? Конструктора у нас нет, а значит все параметры нужно передавать на вход функции. Это неудобно, наш API становится чудовищным.
Первое, что приходит в голову, это частичное применение. Напишем функцию с 4 параметрами, первые 3 из которых это зависимости (код на F#):
let tryAccept capacity readReservations createReservation reservation =
let reservedSeats =
readReservations reservation.Date |> List.sumBy (fun x -> x.Quantity)
if reservedSeats + reservation.Quantity <= capacity
then createReservation { reservation with IsAccepted = true } |> Some
else None
«Приклеим» зависимости
let tryAcceptComposition =
let read = DB.readReservations connectionString
let create = DB.createReservation connectionString
tryAccept 10 read create
На выходе имеем функцию
tryAcceptComposition в которую уже внедрены зависимости и остался один входной параметр reservation. Дальше Марк делает классный трюк, и превращает код из F# в C# средствами .NET (через его промежуточное представление IL). И код на C# выглядит как обычный объект с внедрением в конструкторе!
Решена ли задача? Можно ли сказать, что частичное применение решает задачу внедрения зависимостей в ФП? Марк предлагает решить спор используя Haskell. F# язык хороший, но он позволяет много больше, чем «настоящие» ФП языки. И что же у нас происходит в Хаскеле? Если мы объявим
tryAccept чистой функций, то код не скомпилируется. Потому что зависимости несут сайд-эффекты (походы в базу данных). Т.е. частичное применение решает вопрос внедрения зависимостей, но оно делает код нефункциональным. Чтобы функции остались чистыми, мы должны отказаться от внедрения зависимостей. И тут Марк переходит к последнему шагу. Он переписывает
tryAccept так, чтобы на входе были только «чистые» значения:
let tryAccept capacity reservations reservation =
let reservedSeats = reservations |> List.sumBy (fun x -> x.Quantity)
if reservedSeats + reservation.Quantity <= capacity
then { reservation with IsAccepted = true } |> Some
else None
Эта функция не требует внедрения зависимостей, в ней нет сайд-эффетов. Сайд-эффекты поднимаются на уровень функции-композиции, в ней происходит вся «грязь»
let flip f x y = f y x
let tryAcceptComposition reservation =
reservation.Date
|> DB.readReservations connectionString
|> flip (tryAccept 10) reservation
|> Option.map (DB.createReservation connectionString)
В итоге Марк постулирует, что функциональное программирование должно отказаться от понятия внедрения зависимостей. Чистые функции не могут вызывать нечистые функции. Мы должны оставить наше ядро чистым и поднять всё нечистое до уровня границы с внешним миром (и снова привет тебе, архитектура портов и адаптеров).
ploeh blog
From dependency injection to dependency rejection
The problem typically solved by dependency injection in object-oriented programming is solved in a completely different way in functional programming.
👍35🤔12❤3🤮2
Так, мне нужен ваш опыт
Подскажите хорошие примеры качественной работы с текстами и переводами в опенсорс-проектах? Вот чтобы не просто
Под процессом я понимаю примерно следующее:
- Изменение или добавление ключей в ветке блокирует пулл-реквест;
- Приходят переводчик и техпис, забирают тексты в свою систему;
- По готовности текстов они выгружаются обратно и коммитятся автоматикой в ветку PR;
- Блок снимается, PR заезжает в main.
Это значит, что где-то нужно поднять платформу локализации (тот же Weblate), как-то удобно следить за текстами, понимать статус задачи на вычитку/перевод. Хочу посмотреть, как это устроено в других проектах.
Подскажите хорошие примеры качественной работы с текстами и переводами в опенсорс-проектах? Вот чтобы не просто
mdи
jsonфайлы абы как коммитили, а был построенный процесс, как во взрослых коммерческих проектах.
Под процессом я понимаю примерно следующее:
- Изменение или добавление ключей в ветке блокирует пулл-реквест;
- Приходят переводчик и техпис, забирают тексты в свою систему;
- По готовности текстов они выгружаются обратно и коммитятся автоматикой в ветку PR;
- Блок снимается, PR заезжает в main.
Это значит, что где-то нужно поднять платформу локализации (тот же Weblate), как-то удобно следить за текстами, понимать статус задачи на вычитку/перевод. Хочу посмотреть, как это устроено в других проектах.
❤16👍2
Как мы ничему не научились на примере жизни и смерти Yarn
Статья от Джареда Вилкарта про Bun в моём любимом жанре «дедовское брюзжание». Как многие опытные программисты знают — выбирать надо скучные технологии. И сидя на берегу дождаться, пока мимо проплывут останки недавно хайповой штуки.
И вот Джаред проводит параллели между Yarn и Bun:
— продают «скорость»,
— раскалывают экосистему,
— не про обратную совместимость,
— в стабильной 1.0 версии не поддерживают Windows.
Yarn на старте был быстрее npm. Но npm догнал его по скорости, а создателям Yarn пришлось объяснять, что вообще-то они были не про перформанс, а про фичи. Сложно конкурировать с владельцем npm-серверов.
В итоге, все фичи yarn внедрены в npm и npm ещё и быстрее (тут Джаред почему-то забывает про Plug'n'Play, который пусть не сразу, но появился в Yarn, но так и не был реализован в npm). Да, есть нюансы, кому-то они важны, но для большинства людей подходит npm.
Вот и Bun — он не делает ничего, что нельзя было бы достичь в Node.js не ломая обратную совместимость. Так что в какой-то момент Node.js скорее всего получит паритет по скорости. И маркетинговая шумиха про скорость сойдёт на нет.
Ок, Yarn пришёл, пошумел и умер. В процессе подстегнул npm. В чём проблема? В том, что пока Yarn шумел и продавал функции, которые на самом деле в большей степени были нужны только Facebook, команде npm пришлось гнаться за ним и добавлять схожие фичи, чтобы экосистема не раскололась сильно. При этом были изменены приоритеты, фактически Facebook косвенно повлиял на порядок внедрения фичей в npm.
А дальше Yarn проник в Readme. Куча проектов стала ориентироваться на Yarn и писать инструкции, как развернуть их с помощью Yarn. Смущая новичков и тратя время синьоров на объяснения, почему в наш конкретный проект так ставить зависимости не нужно.
Вместо того, чтобы контрибьютить в npm Facebook потратил силы на создание собственной его копии. И ради чего?
Но bun гораздо опасней
Bun предлагает скорость и опасные фичи:
1. Макросы — ваша сборка теперь гвоздями прибита к Bun
2. bun.x API. Собственные «более быстрые» API. Ваш код будет «отравлен» ими. Придётся ставить зависимости — полифиллы. Ура, ещё одна зависимость.
3. Встроенную поддержку мета-языков. Тут подробнее.
Мета-языки временны. Их задача сделать программирование удобней, пока основной язык не дотягивает. Как только возможностей основного языка достаточно, мы отстреливаем мета-язык. Как выкинули CoffeeScript, как многие отказываются от Sass, потому что CSS сам по себе уже достаточно неплох. Но вот в Bun теперь встроен ужасный JSX и TypeScript.
А TS уже прошёл свой пик. Графики показывают первые признаки разворота сообщества с сторону более лёгких альтернатив, таких как eslint-plugin-jsdocs, а на горизонте маячит добавление статической типизации на комментариях в ES202X. В какой-то момент TS может сказать, что его работа закончена. Sass тут отличный пример — из популярнейшего дефолтного инструмента для всех он уходит в сторону узкоспециализированного продвинутого инструмента для профи.
А если бы Bun вышел в 2019 году на пике популярности Sass, то Sass был бы встроен в него. И что бы они делали в момент смены API? Вы уже не можете написать npm install <версия Sass>. Не нужно прибивать мета-языки к рантайму.
Bun приносит абстракции для кучи технологий, но он не абстрагируется от этих технологий. Он не берёт что-то сложное и делает это проще и универсальней — нет, он засовывает это в себя как есть. И всегда будет отставать от оригиналов (нужно следить за изменениями API и добавлять код в свою реализацию). При этом абстракции эти находятся в критически важных местах: установка зависимостей, тесты и сборка.
Дальше Джаред пишет про Windows. Сборка под неё экспериментальная и обещают позже дать стабильную. И Джаред сомневается, что столь небольшая команда сможет одновременно догонять фичи для Windows и пилить новые в Linux/OSX. А не пилить фичи нельзя. И как-то придётся выравнивать версии. Возможно через год у нас будет v1.8 для Linux и v1.0 для Win.
Статья от Джареда Вилкарта про Bun в моём любимом жанре «дедовское брюзжание». Как многие опытные программисты знают — выбирать надо скучные технологии. И сидя на берегу дождаться, пока мимо проплывут останки недавно хайповой штуки.
И вот Джаред проводит параллели между Yarn и Bun:
— продают «скорость»,
— раскалывают экосистему,
— не про обратную совместимость,
— в стабильной 1.0 версии не поддерживают Windows.
Yarn на старте был быстрее npm. Но npm догнал его по скорости, а создателям Yarn пришлось объяснять, что вообще-то они были не про перформанс, а про фичи. Сложно конкурировать с владельцем npm-серверов.
В итоге, все фичи yarn внедрены в npm и npm ещё и быстрее (тут Джаред почему-то забывает про Plug'n'Play, который пусть не сразу, но появился в Yarn, но так и не был реализован в npm). Да, есть нюансы, кому-то они важны, но для большинства людей подходит npm.
Вот и Bun — он не делает ничего, что нельзя было бы достичь в Node.js не ломая обратную совместимость. Так что в какой-то момент Node.js скорее всего получит паритет по скорости. И маркетинговая шумиха про скорость сойдёт на нет.
Ок, Yarn пришёл, пошумел и умер. В процессе подстегнул npm. В чём проблема? В том, что пока Yarn шумел и продавал функции, которые на самом деле в большей степени были нужны только Facebook, команде npm пришлось гнаться за ним и добавлять схожие фичи, чтобы экосистема не раскололась сильно. При этом были изменены приоритеты, фактически Facebook косвенно повлиял на порядок внедрения фичей в npm.
А дальше Yarn проник в Readme. Куча проектов стала ориентироваться на Yarn и писать инструкции, как развернуть их с помощью Yarn. Смущая новичков и тратя время синьоров на объяснения, почему в наш конкретный проект так ставить зависимости не нужно.
Вместо того, чтобы контрибьютить в npm Facebook потратил силы на создание собственной его копии. И ради чего?
Но bun гораздо опасней
Bun предлагает скорость и опасные фичи:
1. Макросы — ваша сборка теперь гвоздями прибита к Bun
2. bun.x API. Собственные «более быстрые» API. Ваш код будет «отравлен» ими. Придётся ставить зависимости — полифиллы. Ура, ещё одна зависимость.
3. Встроенную поддержку мета-языков. Тут подробнее.
Мета-языки временны. Их задача сделать программирование удобней, пока основной язык не дотягивает. Как только возможностей основного языка достаточно, мы отстреливаем мета-язык. Как выкинули CoffeeScript, как многие отказываются от Sass, потому что CSS сам по себе уже достаточно неплох. Но вот в Bun теперь встроен ужасный JSX и TypeScript.
А TS уже прошёл свой пик. Графики показывают первые признаки разворота сообщества с сторону более лёгких альтернатив, таких как eslint-plugin-jsdocs, а на горизонте маячит добавление статической типизации на комментариях в ES202X. В какой-то момент TS может сказать, что его работа закончена. Sass тут отличный пример — из популярнейшего дефолтного инструмента для всех он уходит в сторону узкоспециализированного продвинутого инструмента для профи.
А если бы Bun вышел в 2019 году на пике популярности Sass, то Sass был бы встроен в него. И что бы они делали в момент смены API? Вы уже не можете написать npm install <версия Sass>. Не нужно прибивать мета-языки к рантайму.
Bun приносит абстракции для кучи технологий, но он не абстрагируется от этих технологий. Он не берёт что-то сложное и делает это проще и универсальней — нет, он засовывает это в себя как есть. И всегда будет отставать от оригиналов (нужно следить за изменениями API и добавлять код в свою реализацию). При этом абстракции эти находятся в критически важных местах: установка зависимостей, тесты и сборка.
Дальше Джаред пишет про Windows. Сборка под неё экспериментальная и обещают позже дать стабильную. И Джаред сомневается, что столь небольшая команда сможет одновременно догонять фичи для Windows и пилить новые в Linux/OSX. А не пилить фичи нельзя. И как-то придётся выравнивать версии. Возможно через год у нас будет v1.8 для Linux и v1.0 для Win.
DEV Community
Bun hype. How we learned nothing from Yarn
Here we go again, making the same mistake. I'm constantly reminded that every 5 years the amount of...
👍75🤡6👎4❤2🤔2💯2😁1
А мир во фронтенд-разработке меняется достаточно быстро. Как скоро мы увидим конкурента Vite? Как скоро уйдём с ESBuild? Внедрит ли Bun новые абстракции и будет ли поддерживать старые? Или просто удалит их?
А если мы нашли проблема в JS Runtime — можем ли мы обновить рантайм, не потеряв инструменты, на версии которых мы завязались? О нет. Кажется нужно всё переписывать.
Что будет, например, когда запустят JavaScript Shadow Realms? Vitest уже ждёт их, готов использовать. Вот только Bun будет ждать, пока Shadow Realms прорастут в WebKit. Что будет в этот промежуток с совместимостью с Vitest? (Джаред забывает, что первая реализация Shadow Realms внедрена как раз в WebKit. Но пример достаточно корректный, так как позже имплементация была убрана за флаг, потому оставим тут).
Слишком много инструментов в одном. И, при этом, в обойме нет инструмента управляющего версиями этих кусочков.
• Если бы Bun вышел в 2012 году, в него был бы встроен Grunt.
• Если бы Bun вышел в 2014 году, в него был бы встроен Gulp.
• Если бы Bun вышел в 2016 году, в него был бы встроен Webpack.
• Если бы Bun вышел в 2018 году, в него был бы встроен Rollup.
• Если бы Bun вышел в 2020 году, в него был бы встроен ESBuild.
• Если бы Bun вышел в 2026 году, в него был бы встроен ...
Это не значит, что Bun отстой. Bun хорош. Но седые и строгие деды уже чуют запах будущих проблем. Прогноз Джареда, что Bun будет с нами лет 5, прежде чем все про него забудут. Ну а все проекты, которые Bun встроил в себя и ускорил — наверстают упущенное за год.
А если мы нашли проблема в JS Runtime — можем ли мы обновить рантайм, не потеряв инструменты, на версии которых мы завязались? О нет. Кажется нужно всё переписывать.
Что будет, например, когда запустят JavaScript Shadow Realms? Vitest уже ждёт их, готов использовать. Вот только Bun будет ждать, пока Shadow Realms прорастут в WebKit. Что будет в этот промежуток с совместимостью с Vitest? (Джаред забывает, что первая реализация Shadow Realms внедрена как раз в WebKit. Но пример достаточно корректный, так как позже имплементация была убрана за флаг, потому оставим тут).
Слишком много инструментов в одном. И, при этом, в обойме нет инструмента управляющего версиями этих кусочков.
• Если бы Bun вышел в 2012 году, в него был бы встроен Grunt.
• Если бы Bun вышел в 2014 году, в него был бы встроен Gulp.
• Если бы Bun вышел в 2016 году, в него был бы встроен Webpack.
• Если бы Bun вышел в 2018 году, в него был бы встроен Rollup.
• Если бы Bun вышел в 2020 году, в него был бы встроен ESBuild.
• Если бы Bun вышел в 2026 году, в него был бы встроен ...
Это не значит, что Bun отстой. Bun хорош. Но седые и строгие деды уже чуют запах будущих проблем. Прогноз Джареда, что Bun будет с нами лет 5, прежде чем все про него забудут. Ну а все проекты, которые Bun встроил в себя и ускорил — наверстают упущенное за год.
👍50❤9🔥8🤔4🌚2
История про баг в Safari
Недавно решил поправить
Прописываю
Долго ищу как запустить Safari 15. Проблемное место нахожу достаточно быстро — это описанные через
Ищу дальше. Да, в Safari 15 есть такой баг! https://bugs.webkit.org/show_bug.cgi?id=236843 Поля классов в нём поддерживаются, но иногда не работают.
Остаётся понять последнее, почему
Мораль тут такая, что спецификации спецификациями, но тестировать надо на реальных браузерах.
Недавно решил поправить
browserslist в проекте и оторвал правило Chrome >= 72 как явно для нас устаревшее. После релиза получаю всплеск жалоб от пользователей Safari 15 (их много!). Бегу проверять, вижу ошибку (самое смешное, что ошибка не проявляется при включенных девтулз), откатываюсь. Дальше мучительный поиск проблемы. Прописываю
Chrome >= 74 — бага есть. Chrome >= 73 — баги нет. Ясно, дело в полях классов. Начиная с Chrome 74 у нас есть полная поддержка публичных и статических полей классов, полифилл больше не нужен. Но в Safari 15 тоже полная поддержка! Can I Use врать не будет же. Где же баг и почему его не лечит правило Safari >= 15?Долго ищу как запустить Safari 15. Проблемное место нахожу достаточно быстро — это описанные через
static propTypes, в которые прилетает внешнее значение/ссылка. Вот это место Ищу дальше. Да, в Safari 15 есть такой баг! https://bugs.webkit.org/show_bug.cgi?id=236843 Поля классов в нём поддерживаются, но иногда не работают.
Остаётся понять последнее, почему
preset-env не помогает? Ищем дальше. А вот оно как, в Babel заведена ишью уже больше года как. В комментах и @valya_reads_issue отметился. Как же лечить? Вот, например, так, как сделали в Графане. Прописать @babel/plugin-transform-class-properties в плагины.Мораль тут такая, что спецификации спецификациями, но тестировать надо на реальных браузерах.
😨32👍13❤6😱5🤣4😢3
Почитайте тоже https://news.1rj.ru/str/valya_reads_issue/329
TL;DR «Начиная с 7.22.6 в @babel/compat-data указано, что class properties поддерживаются в iOS 14.5, а до этого было указано что в iOS 15, т.е. с Safari 15 сдаунгрейдили поддержку до Safari 14.1. Напомню, без багов эта фича работает начиная с Safari/iOS 16. »
TL;DR «Начиная с 7.22.6 в @babel/compat-data указано, что class properties поддерживаются в iOS 14.5, а до этого было указано что в iOS 15, т.е. с Safari 15 сдаунгрейдили поддержку до Safari 14.1. Напомню, без багов эта фича работает начиная с Safari/iOS 16. »
Telegram
Валя читает ишью
Safari class fields implementation is buggy: part two, Tt edition
Я уже рассказывал о том, как сафари не очень хорошо (мягко говоря) дружит с замыканиями в class fields. И вот, спустя полгода, мы снова здесь. Long time no see как говорится!
В прошлый четверг…
Я уже рассказывал о том, как сафари не очень хорошо (мягко говоря) дружит с замыканиями в class fields. И вот, спустя полгода, мы снова здесь. Long time no see как говорится!
В прошлый четверг…
👍6😨3❤1
После раскрытия кода Даталенс весь ноябрь проходит в каком-то бесконечном девреле. В декабре финальное, расскажу на YaTalks докладик и, надеюсь, эту тему пока поставить на паузу. Хотя бы до января, снежок же выпал, склоны запустились, найти бы свободный выходной.
Хочется и продуктовых задач уже поделать, фичей для юзеров позапиливать, хотя вопросов о взаимодействии с внешними контрибьюторами местами всё так же больше, чем ответов.
Не лезь туда, оно тебя сожрёт! Но тебе даже понравится.
Хочется и продуктовых задач уже поделать, фичей для юзеров позапиливать, хотя вопросов о взаимодействии с внешними контрибьюторами местами всё так же больше, чем ответов.
Не лезь туда, оно тебя сожрёт! Но тебе даже понравится.
👍27❤4😁3🔥1
Про билд-секреты в докере
Давно хотел написать. Вот есть задача закинуть секреты в
Как тут правильно поступить?
1 Вытягивать секреты из секретницы в самом билде — не всегда возможно;
2 Multi-stage билд — может существенно замедлить сборку;
3 Закинуть секреты через встроенный механизм докера!
Как оно работает. Создаём файл с секретами. Например,
Включаем BuildKit через env DOCKER_BUILDKIT=1.
Скармливаем файл с секретами:
В Dockerfile монтируем секреты в RUN и загоняем их в env
Давно хотел написать. Вот есть задача закинуть секреты в
docker build. Это не рантайм-секреты, это секреты необходимые только на этапе билда. В итоговом образе они светиться не должны (как и любые секреты).Как тут правильно поступить?
--build-arg (ARG в Dockerfile) не подходит для передачи секретов, запомните это. Достаточно docker history --no-trunc <img> и вот они, секреты, как на ладони. Значит, какие у нас варианты:1 Вытягивать секреты из секретницы в самом билде — не всегда возможно;
2 Multi-stage билд — может существенно замедлить сборку;
3 Закинуть секреты через встроенный механизм докера!
Как оно работает. Создаём файл с секретами. Например,
.secrets. Обычный текстовый файл, куда мы закинем секреты строчка за строчкой.
cat <<EOT > .secrets
SUPER_SECRET_1=$SUPER_SECRET_1
SUPER_SECRET_2=$SUPER_SECRET_2
EOT
Включаем BuildKit через env DOCKER_BUILDKIT=1.
Если у ваc Docker >= 23.0 то BuildKit включен по умолчанию.Скармливаем файл с секретами:
DOCKER_BUILDKIT=1 docker build --secret id=secrets,src=.secrets .
В Dockerfile монтируем секреты в RUN и загоняем их в env
RUN --mount=type=secret,required=true,id=secret,target=./.secrets \
export $(cat .secrets) > /dev/null && \
npm run build
Можно не только через файл, но и через ENV но это мне кажется наименее удобным.
🔥82👍19