Делюсь интересными ишьюсами и пул-реквестами в мире фронтенда и около github.com/7rulnik twitter.com/7rulnik
Как обновлять зависимости для сборки, понимать что изменилось и что нужно тестировать? И нужно ли?
В вечер пятницы решил попробовать обновить пакеты, отвечающие за сборку CSS. Они у нас изрядно устарели (некоторые на несколько мажорок, а sass на 40 с лишним минорок) и понять как изменится бандл очень сложно.
Что делать? Отдавать QA на смоук-тесты? Всё равно это не является гарантией и тестировщики точно так же могут пройти мимо багов. Нужно как-то сузить скоуп, а для этого нужно понять что изменилось в бандле и в каких чанках/частях приложения. И изменилось ли? Быть может можно обновить зависимости и даже ничего не тестировать?
Какое-то время назад я нашёл достаточно надёжный, эффективный и быстрый (ну, на мой взгляд) способ оценить масштаб изменений. Решил попробовать новый формат и записал весь процесс!
После этой истории напрашивается вопрос: а запускаете ли вы авто-тесты в Safari/WebKit? Если да, то как?
На сколько я понимаю можно взять epiphany (он же GNOME web) и гонять cypress/playwright в linux-контейнере? А версию ВебКит взять из таблички Safari version history?
Будет ли этого достаточно, чтобы ловить такие ошибки?
UPD: ещё я так понимаю можно взять mac1.metal в AWS, поддерживает в том числе Mojave т.е. начиная с Safart 12. Но не очень понятен процесс настройки. Ну или взять физическую тачку.
Test Assertion Styles in JavaScript
Короткая заметка про разные стили работы тестовых фреймворков в JS (в целом актуально и не только для JS)
Есть 2 типа тестовых тулзов: spec и tap. Spec - это когда мы тесты обозначаем специальной функцией и когда она выкидывает исключение - мы считаем что тест упал. Если же исключение не было выкинуто - тест прошел. Tap - это когда есть специальное API для проверок и проверки либо проходят либо нет.
Типичный пример в spec-подходе:describe('account', () => {
it('has a balance of zero when first created', () => {
// if this throws, the test fails
expect(new Account().balance).to.equal(0)
})
it('has an empty list of initial addresses', () => {
expect(new Account().addresses).to.match([])
})
})
Типичный пример в tap-подходе:t.test('account', async t => {
const a = new Account()
t.equal(a.balance, 0, 'balance of zero when first created')
t.match(a.addresses, [], 'empty list of addresses')
t.test('credits', async t => {
a.credit(100)
t.equal(a.balance, -100, 'negative balance after credit')
a.debit(200)
t.equal(a.balance, 100, 'positive balance after debit')
})
})
В первом сниппете кода границы тесты - это describe
и it
.
Во втором же сниппете используется объект t
, который умеет делать проверки и композировать их через test
. При этом "тестов" в привычном понимании там нет, только проверки. Минимальный tap тест выглядит так t.ok(cond, message)
То есть, разница подходов - разница в абстракции, вокруг которых они крутятся. Для spec - это тесты, для tap - проверки.
Автор также указывает на разницу, что в spec-подходе it и describe определяются тест-ранером (а значит нельзя запустить тесты на чисто nodejs) и обязательно нужно выделять describe
=> it
, но, кажется что в реальности это не так (т.к. все таки есть тулы, где эти функции нужно импортировать явно, а тесты могут запускаться без отдельного тест-ранера)
https://blog.izs.me/2023/09/software-testing-assertion-styles/
#development #testing #tap
JS minification benchmarks, актуальное сравнение популярных минификаторов (от esbuild до closure compiler) по скорости и эффективности работы → https://github.com/privatenumber/minification-benchmarks
Читать полностью…GitHub Actions M1 runners
Наконец-то стали в гитхаб экшенах стали доступны M1 раннеры (спустя 3 года после релиза, да). Тачка на 6 ядер стоит $0.16 за минуту: чуть дороже чем Linux на 32 ядра ($0.128). И пока что на macOS 13 — 14 версию обещают в этом году.
Непонятно могут ли опенсорсные репозитории использовать эти ранеры, но если могут, то новость отличная. Отличная, т.к. многие проекты не могут официально раскатить поддержку M1+ — им негде запускать тесты под ARM. Такой случай, например, произошел с puppeteer.
Релизный блог-пост:
github.blog/2023-10-02-introducing-the-new-apple-silicon-powered-m1-macos-larger-runner-for-github-actions/
TypeScript Origins: The Documentary
Посмотрел документалку про создание тайпскрипта. В общем то ничего от неё особо не ждал и в целом правильно. Но позабавили некоторые цитаты и факты от туда.
1. На то, чтобы убедить менеджеров опенсорсить тайпскрипт ушло полгода.
2. «JavaScript isn't broken enough and Dart didn't fix it enough either» — на ранних стадиях разработки была большая конкуренция между разными компаниями и идея Гугла с Dart была заменить джаваскрипт, в то время как ребята из Майкрософта хотели всего лишь «поправить» какие-то части языка.
3. «We not married to one particular framework or to one particular methodology» — говоря про победу над flow. Об это я, кстати, немного писал.
4. «The really interesting property about TypeScript is that it's kind of meant to disappear.» — здесь подразумевается, что типы станут нативной частью языка. У команды тайпскрипта есть даже статья A Proposal For Type Syntax in JavaScript. Пока что предложение на stage-1. Ну и в любом случае нам нужен будет инструмент, чтобы проверять типы перед деплоем, так что тайпскрипт с нами, в том или ином виде, надолго.
5. «TypeScript was really the beggining of Microsoft getting really comfortable with open sorce»
Смотреть тут: youtube.com/watch?v=U6s2pdxebSo
Say Goodbye to dotenv
И вот, начиная с 20.6.0, в ноду встроена поддержка dotenv конфигов.
Конфиг явно передаётся через флаг --env-file:node --env-file=config.env index.js
До этого всегда приходилось использовать motdotla/dotenv.
Почему 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 быстрее, то приходите с пул-реквестами либо помогайте финансово.
Как вы могли заметить (или наоборот, не заметить) лето прошло продуктивно — всего лишь 1 пост, написанный лично мной!
Дело в том, что за это время я посетил 11 городов в 9 странах. А всего в этом году за спиной уже (или пока что) 15 стран. В общем, такой режим существования крайне плохо сочетается с написанием постов о программировании.
Зато, в таком режиме, хочется писать о странах, перемещениях, специфических номадских девайсах и т.д.
В общем, если вас это почему-то заинтересовало, то подписывайте на мой второй канал — «Номадские приколы»!
P.S. Не переживайте, в этом канале всё останется как и было. Ну, возможно только постов будет побольше (или не будет).
Рубрика "что там у DHH?"
Там в интернетах драма-драма, видели уже? https://github.com/hotwired/turbo/pull/971
Если вкратце: DHH решил стремительным движением выпилить TypeScript из js-библиотеки "Turbo". Запушили огромный PR с сотней файлов и молниеносно его апрувнули. Интернет возмутился, скандал докатился аж до главной страницы HN.
Кто такой DHH - автор Ruby-on-rails и кофаундер компании "37 signals". Почему "DHH" - потому что всем лень писать "Девид-Хейнемайер-Хэнссен". Когда-то был всеобщей ролевой моделью, сейчас душный дед.
Кто такие "37 Signals" - авторы продукта "Basecamp". Когда-то были пионерами SaaS-рынка и, де-факто, являются авторитетами в комьюнити bootstrapped-стартапов.
Что такое "bootstrapping" - это когда ты создаешь прибыльный стартап на свои и не в Долине.
(происходит от "pull yourself up by your own bootstraps" - "вытянуть себя из болота за шнурки ботинок" - т.е. сделать что-то невозможное. На современном языке предпринимателей значит "создать бизнес без внешней помощи")
Компания прославилась не в последнюю очередь благодаря эмоциональным выходкам своих фаундеров. И когда-то это отлично работало. Лично я даже согласен почти со всем, что DHH и Джейсон Фрид понаписали в своих бизнес-нижках, но вот с техническими решениями им пора, пожалуй, притормозить.
Например, последнее время парни решили, что они будут громко воевать за концепцию "нахер все лишнее" (в целом, звучит неплохо). Для начала, они с помпой переезжают из AWS в собственный датацентр. Или вот пару недель назад они изобрели - вы не поверите - селф-хостед софт. И даже потратили охуллионы долларов на домен https://once.com/ где выложили Очередной. Очень. Пафосный. Манифест.
А года три назад они изобрели этот самый Turbo/Hotwire - "революционную" либу, которая по кусочкам обновляет SPA-страницу сгенерированным на сервере HTML (олды морщились и вспоминали майкрософтовский <asp:UpdatePanel> 15-летней давности).
Но когда тебе сильно за 40, эпатировать индустрию молодых все сложнее и сложнее. Вместо эмоционального пиара все чаще получается кринж психованных дедов. Говорю как психованный дед.
Кажется, DHH это подсознательно понимает. И вместо того чтобы перейти в режим спокойного и авторитетного аксакала - он продолжает выпрыгивать из штанов и набрасывать говно на ветряные мельницы. А в результате из неплохой опенсорсной либы выпилили TS, потому что одному идиоту не зашла строгая типизация.
В github-репо случился срач и революция. TS попытались вернуть (не вышло), потом убрать из репо самого DHH (не дали), потом вообще поступил пул-реквест удалить всю эту Турбу к херам. В конце все свелось к гифкам и лулзам. А сам DHH написал длинное заявление (TL;DR "я обиделся")
Как убить опенсорсный проект за 3… 2… 1…
Ладно. Турбо-хуюрбо... Не Реакт, как-нибудь переживем. Просто фиксируем, что харизматичный чувак окончательного превратился в душного бумера.
Rome is Biome now
Well, вот и продолжение сериала.
Т.к. истории уже больше двух лет, то небольшая ретроспектива:
1. /channel/valya_reads_issue/141 — Себастьян и Джейми поднимают инвестиций, чтобы сделать ультимативный тулинг, который будет делать всё-всё-всё (бандлер, линтер, тесты, whatever).
2. /channel/valya_reads_issue/164 — Rometools аплаятся в TC39, чтобы развивать язык и экосистему вокруг него.
3. /channel/valya_reads_issue/237 — через 7 месяцев Джейми уходит из компании.
4. /channel/valya_reads_issue/296 — в конце января 2023 года у компании кончились деньги, статус проекта не ясен, все разработчики ушли/уволены.
???
5. «Rome won't be maintained anymore by the same people that maintained it so far. Biome will provide new features and fixes» красуется в ридми github.com/rome/tools.
Biome является «официальным» форком Rome. Под «официальным» подразумеватся, что форкнули его те же люди, что и работали над Rome. Одна из причин форка — Себастьян просто всех заигнорил, а у команды не было доступа к организации, хостингу и т.д.
Ну и вот сам блогпост Announcing Biome.
P.S. К сожалению, всё это было очень предсказуемо… Посмотрим, что получится у этих ребят дальше.
Опять Гугл всё сломал
В мае Гугл запустил новый домен первого уровня .zip
и неплохо так насолил безопасникам. Дело в том, что браузеру тоже можно скормить урл с userinfo частью (<протокол>//<userinfo>@<домен>), а значит, можно подсунуть пользователю адрес вида
https://github.com∕kubernetes∕kubernetes∕archive∕refs∕tags∕@v1.27.1.zip.
v1.27.1.zip. Более того, собачку в адресе можно скрыть в интерфейсе, уменьшив шрифт.
.mov
. А мессенджеры превратили это в ссылки. Так и живём.ReferenceError: a is not defined / Safari class fields implementation is buggy
Напомню, переделывая компиляцию в монорепозитории, мы взяли самый современный таргет компиляции — esnext.
Само собой, у нас есть пользователи, у которых браузеры старее. Особенно сафари, который обновляется только вместе с операционной системой.
В проектах, которые используют такие пакеты, мы просто транспайлим все нод-модули в скоупе @aviasales
— это позволяет не париться на счёт обновления таргета тайпскрипта в монорепе и транспайлить через Babel только то, что нужно на основе текущего конфига Browserslist.
Задеплоив, мы увидели всплеск ошибок «a is not defined» в Rollbar’е в сафари с крайне непонятным стек-трейсом.
Ну, начали разбираться. Честно говоря, даже немного стыдно, т.к. проблема оказалось совсем нелепой, а для того, чтобы понять в чём дело понадобилось аж 3 разработчика…
Начали с поиска проблемного места.
Беда в том, что у нас регулярно возникают проблемы с сорсмапами в ролбаре — то они не заливаются, то не подхватываются в веб-интерфейсе. Из-за этого в ролбаре стектрейс частенько указывает на минифицированные файлы, в которых, как вы понимаете, бесполезно что-то искать: 3 строка и 58375 колонка, хех! А в дев-режиме проблема, естественно, не воспроизводилась.
Несмотря на кажущуюся бесмысленность, я всё таки попробовал поискать нужную колонку — никакой переменной «a» там и рядом не было.
Решили попробовать выкатить неминифицированный код, чтобы убедиться, что проблема именно в минифакторе, т.к. это самое большое отличие дев и прод режимов. Выкатили — проблема ушла. Обновляем terser (минифактор, который использует вебпак) — не помогает.
Решаем попытаться отловить проблему локально в прод режиме с включенными сорсмапами, и у одного из нас получается! Но при этом стектрейс абсолютно бесмысленный, указывает чёрт знает куда. А ещё проблема очень плавающая — появляется при первом визите без кеша и то не всегда. Загадка!
Ищем ишью в терсере, бабеле — ничего не находим. Настроение упадническое, т.к. пытаемся разобраться уже дня 4, пробуем переписывать какие-то странные места со смесью UMD, ESM и CommonJS — ничего не помогает.
Я набираюсь сил и отправляюсь на поиски злосчастной переменной «a». Прогоняю минифицированный файл через преттиер включаю в поиске Match Whole Word и нахожу 100+ переменных. Проверяю каждую из них: где объявляется и как используется. Смотрю раз, смотрю два, смотрю три и нахожу подозрительное место — незатранспайленный class field. Примерно в это же время мой напарник скидывает мне ишью Safari class fields implementation is buggy - ReferenceError: Can't find variable. Чудесно.
Проблема выглядит так:import helper from './helper'
class C {
property = helper(() => {})
}
Т.е. если в class field есть вызов функции, объявленной за пределами класса, то всё взрывается, а стектрейс указывает на абсолютно другое место.
Но почему так в принципе получилось? А всё просто — я забыл добавить ту самую транспиляцию нод-модулей со скоупом @aviasales
… Стыдно!
Но ещё более стыдно за сам процесс дебага и сколько времени он занял (напомню, 4 дня).
Ретроспективно становится очевидно, что процесс дебага должен был быть другим:
1. Действительно имело смысл попробовать найти место в коде на основе строки и столбца, хоть этот пункт и не увенчался успехом.
2. Вместо деплоя неминифированного кода, нужно было выключить mangle. Эта опция отвечает за переименование переменных: yourVeryLongVariable → a — и тогда в ошибке мы бы увидели оригинальную переменную и сразу было бы понятно, на какой участок кода смотреть.
Вот так вот просто, да! А ещё мы почему-то не посмотрели на статистику браузеров в Ролбаре — тогда стало бы очевидно, что в 16-ом сафари проблему починили, и именно по этому только у одного из нас проблема иногда воспроизводилась — у него был 15-ый сафари.
В общем, ещё раз стыдно! Вроде бы опытные ребята, а так затупили! В оправдание остается сказать, что это была первая рабочая неделя после новогодних праздников — видимо мозги не включились ещё :D
Внезапно, мне забанили, а затем и разбанили GitHub Copilot
Забанили, т.к. я пару раз подключался к российскому VPN. Не думал, что это может быть проблемой в принципе, учитывая что гитхаб работает из РФ. Однако, оказалось что может.
Написал тикет: объяснил, что живу не в России, какого-то другого резиденства у меня нет, пообещал, что конектов из рф больше не будет.
И это помогло!
DefinitelyTyped is a monorepo!
DefinitelyTyped только что стал полноценным монорепозиторием на основое pnpm!
В DefinitelyTyped хранятся все пакеты в @types
организации. Если пакет не поставляет типы сам, то всегда можно прислать пул-реквест в этот репозиторий и установить пакет отдельно (так делает, например, react с его @types/react
).
Масштаб впечатляет — 8710 пакетов в одном репозитории!
Это миграции посвящены аж три поста:
1. What is DefinitelyTyped, and is it a monorepo? — как был устроен репозиторий и какие проблемы были до миграции.
2. Speeding up pnpm — название говорит само за себя. Естественно, при таком объёме всплывают не очень эффективные алгоритмы. Особенно круто, что показан процесс профилирования.
3. DefinitelyTyped is a monorepo! — как теперь всё устроено, какие проблемы сохранились (или появились) и что дальше.
Монументальная работа, огромный, в том числе и маркетинговый, успех для pnpm!
Safari class fields implementation is buggy: part two, Tt edition
Я уже рассказывал о том, как сафари не очень хорошо (мягко говоря) дружит с замыканиями в class fields. И вот, спустя полгода, мы снова здесь. Long time no see как говорится!
В прошлый четверг я закончил миграцю с Jest на Vitest в последнем нашем проекте (про наш опыт можно почитать тут), всё протестил и выкатил в прод. На следующей день пришла жалоба от пользователя «форма поиска исчезает в сафари 15 — ничего не работает». При этом я форму эту не трогал даже близко. Весело!
Для начала пошли в BrowserStack чтобы посмотреть что ж там в 15 сафари происходит (какая же гениальная система обновлений у сафари, боже, я никогда это не пойму). В 15 сафари мы ничего не могли воспроизвести около часа, хотя у тестировщика разок получилось. Решили ради интереса попробовать сафари 14, который мы не поддерживаем — и сразу же воспроизвелось, причём стабильно. Увидели «ReferenceError: Tt is not defined». В этот раз проблемное место нашли сразу же, т.к. такая переменная была одна на весь бандл. Ну в общем всё тоже самое: class field, замыкание, вспомнили что в 15 сафари проблема иногда воспроизводилась, а иногда не особо.
Но как так вышло, что мы чиним ту же проблему, что и полгода назад? А всё просто — проблема та же, но в другом проекте! Понятно, что это чинится использованием babel/plugin-proposal-class-properties, но почему всё сломалось?
Если поменялся результат билда, то очевидно, что обновилась какая-то транизитивная зависимость (зависимость зависимости зависимости зависимости, ну вы знаете). В yarn.lock смотреть было бесполезно, т.к. дифф очень большой.
Решил сравнить мастер с веткой через yarn info.yarn info --recursive --name-only
выводит плоский список зависимостей с их версиями:├─ @adobe/css-tools@npm:4.3.1
├─ @ampproject/remapping@npm:2.2.1
├─ @aviasales/analytics@npm:4.0.7
и т.д.
В дифе помимо кучи других пакетов, я увидел caniuse-lite
и @babel/compat-data
, а именно их использует @babel/preset-env
, чтобы решить нужно трансформировать ту или иную фичу.
Начиная с 7.22.6 в @babel/compat-data указано, что class properties поддерживаются в iOS 14.5, а до этого было указано что в iOS 15, т.е. с Safari 15 сдаунгрейдили поддержку до Safari 14.1. Напомню, без багов эта фича работает начиная с Safari/iOS 16.
Что ж, тут вроде всё понятно. А что с caniuse-lite? Его использует browserslist, чтобы получить браузеры, которые мы хотим поддерживать. В конфиге у нас было указано defaults, last 2 years, not ie > 0, not ie_mob > 0, chrome >= 94. Сравнил вывод yarn dlx browserslist
и увидел, что из поддерживаемых браузеров исчез сафари 14, т.к. ему исполнилось больше двух лет.
Получается, что к проблеме мог привести апдейт babel/compat-data и caniuse-lite в любых комбинациях: по отдельности и вместе.
А кто их обновил? Ну, в общем-то я, когда устанавливал vitest и пару зависимостей к нему. Мы используем yarn dedupe, чтобы в рамках SemVer использовалась только одна библиотека. При установке и babel/compat-data, и caniuse-lite зарезолвились на последнюю версию и всё сломалось! Этой проблемы можно было бы избежать, если yarn dedupe умел бы в другие стратегии, но пока что только latest.
Ну и напоследок: что сделали, чтобы такого больше не случалось?
1. Явно включили babel/plugin-proposal-class-properties.
2. Посмотрели, что пользователи 14 сафари приносят нам 1% деняк и явно указали safari >= 14 в конфиге браузерслиста.
3. Через resolutions явно установили browserslist и caniuse-lite в единственных экземплярах, чтоб прозрачно контролировать процесс обновления.
А что там с ишью? А ишью в бабеле так и висит без изменений…
От себя добавлю, что автор не кто иной, как создатель npm.
Ну и забавный комментарий от Кристофа Наказавы, создателя jest: «The reason the JavaScript community is using the “spec family” is because I subjectively preferred that one by far.»
Rolldown: a rust port of Rollup
У вебпака есть rspack, а у ролапа будет Rolldown.
Сейчас проходит ViteConf (я, кстати, не рекомендую смотреть такие штуки в лайве, лучше потом в 1.5× промотать на ютубе) и Эван Ю анонсировал Rolldown — порт ролапа на расте.
Основная цель — заменить esbuild и Rollup в Vite незаметно для конечных юзеров.
Интересно, что в разработке участвуют ex-rspack разработчики, а Лукас Таегерт-Акинсон, мэйнтэйнер ролапа, выступает в роли консультанта. Обещают в открытом доступе до конца года.
Меня долгое время смущало, что в JS-тулинге появилась двойственность: го и раст. Проектов на расте, конечно, больше, но esbuild очень успешный проект. Ну что ж, посмотрим как это повлияет на расстановку сил, но кажется раст начинает побеждать.
Слайды доклада вот тут.
P.S. За новость спасибо @Safort
devtools.fm: Jarred Sumner - Bun
Ну и на хайпе Бана, решил послушать выпуск с Джаредом годичной давности. В целом тоже необязательно к прослушиванию, но если вам интересно почему он выбрал Zig, а не Rust и в целом как пришёл к созданию Bun, то можно уделить время. Ещё там сравниваются V8 и JavaScriptCore и рассказывают пару других прикольных штук про внутренности рантаймов, браузеров и движков.
https://www.youtube.com/watch?v=1kP5YgeDj00
lodash: issue bankruptcy
Сегодня все ишью и пул-реквесты в lodash были закрыты и помечены лейблом «issue bankruptcy».
Кажется, это связано с релизом 5 версии и полной миграцией на ESM. По крайней мере такой вывод можно сделать по комментарию «Working on it now :)» от Джона-Дэвида Далтона (ключевой контрибьютор в лодаш).
Ну и, естественно, всё это на ts и bun (вот коммит). Мастер, правда, пока что красный…
Комьюнити уже попросило автора как-то более прозрачно коммуницировать с пользователями.
Но мне есть чем дополнить: две мысли от Джеймса Снела (один из ключевых контрибьюторов в ноду)
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.
Пока я по кусочкам собирал твиты, Матео написал статью, а Андрей сделал саммари
Читать полностью…Там, кстати, и prettier под нож пустили за компанию
https://twitter.com/peer_rich/status/1699740787230028006
Эх, так и знал, что вчера об этом надо было писать
Читать полностью…Привет!
Ищу коллегу в нашу платформенную команду для разработки и поддержки React
мета-фреймворка tramvai
Мы - одна из команд в Tinkoff Coretech Frontend, которая отвечает за создание инструментов и общих практик для огромного фронтенд коммьюнити в Тинькофф.
Почему у нас классно:
- работа в небольшой и технически прокачанной команде, без менеджмента, бюрократии и лишних встреч
- сами себе продакты - ставим задачи и выбираем приоритеты, ориентируясь на потребности наших пользователей и тренды развития JS экосистемы
- ежедневные челленджи - сложные задачи из самых разных областей: клиентская и серверная разработка, консольные утилиты, бандлеры, производительность, логи и метрики, CI/CD процессы
- самые крутые пользователи - разработчики, активный Inner Source и хорошая обратная связь
- несколько десятков tramvai
приложений в продакшене - battle-tested это про нас
- заботимся о качестве продукта - пишем RFC и ADR, интеграционные тесты и документацию, проходим code review, придерживаемся Zero Bug Policy, собираем обратную связь
- регулярно контрибьютим в Open Source, также имеем большие планы на OSS для tramvai
Наши основные задачи:
- Разработка собственного SSR фреймворка
- Поддержка пользователей фреймворка - исправление багов, ответы на вопросы, помощь с ревью и миграциями
- Обеспечивать качественную работу всех tramvai
приложений в Tinkoff экосистеме - интеграционные тесты, помощь в разборе инцидентов, рекомендации по улучшению
- Исследовать и исправлять проблемы производительности и на сервере, и на клиенте
- Совместная работа с другими платформенными командами - tramvai
содержит много полезных интеграций для итоговых пользователей и приложений
Наш технический стек:
- монорепозиторий на 150+ пакетов и модулей - Typescript, Nx + Yarn workspaces, PVM + SemVer + Conventional Commits, Rollup, Gitlab CI
- view слой - React, CSS Modules, Tinkoff UI-kit
- серверная часть - Node.js и Fastify
- тестирование - Playwright, Jest, React Testing Library
- сборка приложения - Webpack, Module Federation, Babel / SWC, Postcss
Идеальный кандидат подходит под любое описание из списка:
- знает и любит React, изучал новую Suspense SSR архитектуру и React Server Components
- имеет широкий кругозор, понимает принципы работы других фреймворков, интересуется развитием таких мета-фреймворков как Next.js, Remix, Nuxt.js, SvelteKit, Astro, Qwik City
- разрабатывал и поддерживал Node.js приложения в продакшене, знает на какие метрики стоит обращать внимание, исправлял высокий event loop lag или исследовал утечки памяти
- имеет опыт работы в платформенной команде - поддержка продукта для других разработчиков, обратная совместимость и long-term миграции, написание технической документации
- хорошо знаком с любым популярным бандлером и транспайлером, писал под них плагины и обходил AST, не боится изучать исходных код инструментов и контрибьютить в них
- умеет профилировать и оптимизировать web приложения, знает как улучшить waterfall загрузки ресурсов страницы или медленные анимации, использовать такие инструменты как WebPageTest, Lighthouse и Performance Insights, знает про Web Vitals и Chrome UX Report, читает CPU Flamegraph как открытую книгу
- есть опыт организации JS библиотек - организации репозиториев, сборки, тестирования, линтера, полного релизного цикла, настройки CI/CD, работы с транзитивными зависимостями и дубликатами, понимание плюсов и минусов чистых ESM пакетов
- знаком с различными стратегиями деплоя серверных и SPA приложений, есть опыт работы с Docker и k8s
- интересуется архитектурными подходами, знаком с IoC и Dependency Injection в частности, Clean Architecture, Feature-Sliced Design
- вдохновлен развитием сетевых протоколов, знает как устроены DNS, TCP, HTTP и QUIC, пользовался такими инструментами как Wireshark
- знаком с мониторингом - собирает, рисует и использует метрики и логи, участвует в разборе инцидентов
Пишите ваши вопросы или присылайте резюме в личку!
У нас в Авиасейлс появилось пара вакансий для фронтенд-стажеров на 2 месяца (июль - август), платим по 500$ в месяц.
Вряд ли это вы, но наверняка у вас есть кто-то из знакомых, кто только начинает свою карьеру :)
Так же есть бекенд, девопс, дизайн и другие варианты:
https://www.aviasales.ru/about/vacancies
Переопределение заголовков ответа для дебага
В Chrome 113 Dev Tools появилась, на мой взгляд, потрясающая фича, которая сильно ускорит параллельную разработку фронтенда и бэкенда в некоторых конкретных случаях.
Представьте, что у вас есть какая-то функциональность на сайте, которая зависит от HTTP-заголовков ответа сервера. Да даже представлять особо не надо, она точно есть: кэширование, куки, CORS, CSP, скачивание файлов, редиректы и разное другое. И вот в какой-то момент эту функциональность нужно доработать новыми заголовками, но на бэкенде доработка требует 2 дня разработки, тестирование и деплой, а на фронтенде — пары часов небольших правок с тестированием. Что можно сделать, чтобы не стопорить фронтенд в таком случае:
1. Сделать заглушку на бэкенде, которая топорно возвращает нужные заголовки по параметрам в URL. Плохой вариант, потому что отвлекается бэкендер, который мог бы уже фичу начать делать. И всё равно нужно ждать деплой.
2. Настроить фронтендеру что-то проксирующее, вроде Charles, научить подменять конкретные заголовки на уровне сети. Уже лучше, но джуну, который только-только освоил вёрстку и какой-нибудь фреймворк, объяснять, как сниффить трафик, кажется оверинжинирингом. К тому же не на всех корпоративных машинках можно ставить сторонние прокси.
3. Воспользоваться новой фичей Chrome Dev Tools! (как будто в телемагазине вещаю, простите)
В чём суть фичи:
- В открытых Dev Tools во вкладке Network > Headers > Response Headers
теперь можно редактировать заголовки ответа сервера. Или добавить новые.
- Во вкладке Sources > Overrides
можно найти домен, на котором экспериментируете с заголовками, и отредактировать там файл .headers
, внутри которого можно задать переопределения не конкретному ответу, а вообще всем ответам.
А ещё обязательно покажите эту фичу вашему QA, чтобы ему было ещё удобнее ломать тестировать подобные кейсы без страданий.
https://developer.chrome.com/blog/new-in-devtools-113/#network
И последний (ребята, я правда надеюсь) пост в этом цикле: обзор от Глеба Бахмутова на встроенный тест-раннер: что умеет, какие ограничения и перф
https://glebbahmutov.com/blog/trying-node-test-runner/
И, заканчивая тему развития, пару раз я пытался законтрибьютить в джест: внедрял source-map-js вместо source-map без какого либо фидбека, а второй с валидацией каверджа только для изменившихся файлов — тут получше, мне ответили через 4 месяца, я не нашёл времени воскрешать его, а чуть позже пришёл агрессивный бот и залочил ПР.
Для сравнения, мой пул-реквест с сжатием HTML отчёта в Vitest приняли меньше чем за неделю.