JulesBlom.com - Avoid anonymous components with `displayName`
Дебаг в JS, традиционно, осложняется тем, что многие функции являются анонимными и не имеют имен. Движки даже пытаются по максимуму помочь разработчикам и сами дают имена анонимным функциям, если это возможно в кейсе
Например, ходит поверье, что все стрелочные функции анонимны и имя им нужно задавать явно
Но это не так
Например, попробуйте выполнить в консоли браузера
```
const myNameIsA = () = {}
console.log(myNameIsA.name) // "myNameIsA"
```
Однако, движок нам не может помочь с React кодом.
В статье описывается, что нам следует более внимательно следить за тем, как мы заводим контексты и используем React.memo и React.forwardRef, т.к. при обычном использовании мы в React DevTools получим непонятное название компонентов.
Для контекстов нужно явно указывать `displayName`, тогда вместо непонятных `Context.Provider` мы в DevTools сможем увидеть `MyAwesomeContext.Provider`
С React.memo и React.forwardRef есть разные способы решения проблемы, но самый простой и эффективный - также явно указывать displayName
```
const HeavyComponent = React.memo(() = (props) { ... })
HeavyComponent.displayName = "HeavyComponent"
```
Хотя можно вынести колбек в отдельную переменную и это тоже сработает.
JavaScript SDK “Package Size is Massive” - So we reduced it by 29%
Sentry уменьшили размер своего SDK на 29%.
Что они сделали для этого:
- Теперь код поставляется как es6. Если кому-то из пользователей sentry требуется es5-версия кода, то он может затранспайлить sentry на своей стороне
- Удалили лишний код
- Удалили лишние абстракции. В некоторых случаях были выделены абстракции, для, например, разделения контекстов. Однако профит был малым, а лишние байты отсылать не хотелось.
- В sentry теперь можно самим определять некоторые фичи. Например, многим клиентам не нужны ВСЕ фичи sentry. Достаточно базовых. Или не нужны какие-то интеграции. Но вот это все, что не нужно - оно встроенно в класс клиента Sentry. В новой версии клиент Sentry не содержит в себе вообще всё, теперь есть возможность прямо провайдить те фичи и интеграции, которые нужны вашему проекту, что снижает количество бесполезных импортов, что снижает вес SDK
- Включили тришейкинг webpack. Т.е. внутри кода sentry теперь расставлены разные *магические* константы типа `SENTRY_DEBUG`, которые вырезаются webpack'ом (или другими инструментами сборки, умеющими в dead code elimination и tree-shaking). Кроме служебных фич, можно отключить и фичи sentry
Из этого всего, мне показалось достаточно интересным, то что для уменьшения размера SDK помог Inversion Of Control - теперь клиенту sentry надо самим провайдить транспорт, интеграции и прочие сущности. А также то, что часть функционала можно отключить через ENV переменные во время сборки.
Если у вас есть свои либы - возможно это даст вам какой-то инсайт
Чем же занимаются staff-инженеры?
Термин staff engineer я встречал только в англоязычном интернете. В русскоговорящей среде, как будто, нет аналога. Есть старшие разработчики, ведущие, техлиды, архитекторы. И в разных компаниях они занимаются совершенно разными вещами.
В статье описываетс, чем же обычно занимается Staff инженер.
Если сильно утрировать, то staff инженер занимается стратегически важными направлениями в рамках технического развития и развития команд.
В статье выделяются следующие направления работы
**Техническое лидерство (в оригинале Setting technical direction)**
Технологии не могу говорить за себя, поэтому нужен человек, который будет выступать адвокатом технологии. Эти адвокаты прагматичны и мыслят стратегически.
Иногда staff инженеры нанимаются для ведения специальной области, такой как проектирование API.
В целом в рамках этой роли нужно уметь принимать стратегические технологические решения, которые, в первую очередь, следуют от нужд организации.
**Менторство**
Многие инженеры избегают менторства, считая это "ненастоящей" работой. Однако, это одна из самых важных работ staff инженера. Staff инженер должен распространять свои знания в организации, менторить других людей, давать советы. Staff инженер должен растить людей вокруг себя
**Представляет инженерный взгляд (в оригинале Providing engineering perspective)**
При принятии решении о том, что и как нужно делать, всегда необходим взгляд инженера на проблему. Это позволяет принимать решения, которые могут быть лучше для пользователя (например, инженер может увидеть, что фичу можно улучшить без дополнительных затрат), или проще реализовать, при этом не потеряв в функционале.
**Исследование**
Организациям нужно уметь исследовать. Исследовать и экспериментировать с новыми фичами, рынками, возможностями.
При этом крупные исследования - всегда риск. В таких исследованиях, как правило, принимают участие staff инженеры.
**Быть клеем (в оригинале Being Glue)**
Делать нужные, но невидимые другим, задачи, которые позволяют команде делать работу и релизить задачи. Этим особо не похвастаешься, но как правило 1 или несколько Staff инженеров работают где-то на невидимом фронте, позволяя командам работать быстро и эффективно.
**Пишут ли staff инженеры код?**
it depends. В целом пишут, но не в том объеме, что на более ранних позициях и, скорее всего, не тот код. Если, будучи разработчиком в продукте нужно писать разные продуктовые фичи, то staff инженер изредка пишет продуктовый код, но пишет много кода "вокруг" - автоматизация, аналитика, эксперименты
**Медленная обратная связь**
Работа staff инженера - она про стратегию. Поэтому цикл обратной связи очень долгий - недели, месяцы, годы. Это, с одной стороны деомтивирует, т.к. ты работаешь, но можешь не видеть результата месяцами. С другой стороны, когда результат виден - он значимый.
Например, можно вырастить самостоятельную самоорганизаванную команду, управляющую своими процессами. Можно внедрить сложный подход к разработке (разработка через контракты например). Оба этих действия делаются долго, скорее всего месяцы. Но зато, когда в итоге получилось изменить систему - результаты от изменений дают значительное влияние на организацию.
Custom ESM loaders: Who, what, when, where, why, how
Оказывается, в NodeJS есть возможность определять кастомные загрузчики для esm файлов. Пока, правда, это фича считается экспериментальной
Что это значит и как это работает?
NodeJS поддерживает ES modules. Но некоторые модули мы не можем заимпортировать в nidejs просто так. Например, нельзя просто так, без уважения, делать импорт css-стилей для реакт приложения или импорт TS файла. Для решения этой задачи можно взять какой-нибудь инструмент типа babel, webpack, vite etc. Но также в NodeJS есть возможность указать кастомные загрузчики модулей, которые могут помочь в этой ситуации.
В статье рассматривается загрузка css-кода в рамках запуска тестов в mocha.js. Для решения этой задачи мы могли бы заиспользовать какие-нибудь плагины к mocha или сделать обвязку вокруг mocha, которые подготовят все файлы, предсобрав их с помощью какого-нибудь препроцессора.
Но решения для этой задачи можно написать свой кастомный загрузчик. Для тестов нам не нужно получать честный css, достаточно получить только имена классов. Такой загрузчик относительно легко написать, при этом не нужно заводить сложные инструменты для решения этой простой задачи.
В рамках статьи также добавляются лоадер на TS файлы и лодар для загрузки сетевых ресурсов (`import blabla from 'https://blabla.com'`).
Само применение лоадеров выглядит вот так
```
node \
--loader typescript-loader \
--loader css-loader \
--loader network-loader \
app.tsx
```
Применение этих лоадеров позволило в 8 раз ускорить работу тестов.
Также в статье приводятся ссылка на другие интересные лоадеры.
Рекомендую посмотреть статью, если вы интересуетесь nodejs или кастомными решениями для автоматизации (возможно кастомные лоадеры помогут вам решить какие-то проблемы)
Testing Bun's compatibility with Node.js and speed with a complex application
И вот подошли первые независимые тесты перформанса нового рантайма Bun.
David Herron попробовал запустить на Bun свой генератор статических сайтов AkashaCMS на примере реальных проектов. Один из них остоит из 1600 страниц - достаточно внушительный размер.
Для того чтобы запустить свой проект на bun, пришлось сделать немножко приседаний. Например, bun не предоставлял некоторых значений в `process`, а также не умеет скачивать зависимости из package.json, которые ведут на github. В целом это минорные проблемы и их должны порпавить в ближайшее время.
Затем David Herron провел сравнение bun и nodejs для двух сценариев:
- копирование статики (более 2000 файлов для одного из сайтов)
- рендер статики
В обоих сценариях bun имеет примерно тот же перформанс, что и nodejs.
Какие выводы из этого можно сделать?
- bun в бета и поэтому еще поддерживает не все (значения в process, зависимости ссылкой)
- пока что супер перформанс bun'а не подтвержден
- тем не менее, то что bun версии 0.1.0 по перформансу такой же как nodejs - это очень круто.
Ждем еще независимых исследований.
Вышел Vite 3.0.
Если вы вдруг не знаете, что такое Vite - то пару лет назад создатель Vue решил сделать свой бандлер на основе современных подходов и назвал его Vite. С тех пор Vite обзавелся хорошей документацией и экосистемой. Vite - это, в первую очередь, аналог webpack, но только легче и быстрее. Что интересно, в экосистеме Vite также есть аналоги, которые тоже просто легче и быстрее оригиналов, например vitest (аналог jest) и vitebook (аналог storybook).
В общем, очень крутой инструмент и один из лучших вариантов для выбора бандлера в новый проект
Вернемся к релизу 3.0, что изменилось:
- Новая документация (сделана с помощью VItePress)
- Для разработки
- Добавлены стартовые шаблоны для самых популярных кейсов (vue, svelte, react, etc)
- Ускорена первая сборка в dev режиме (холодная сборка)
- Собирается в ESM по дефолту для SSR сборки.
- NodeJS 12 более не поддерживается
Также в блог-посте есть график с фиксом багов в репозитории Vite. И этот график внушает уважение к команде разработки.
Если вы хотели попробовать vite - вот вам еще один повод. А если вы уже используете vite - можете в комментариях рассказать, как он вам.
Лично у меня есть 1 пет-проект, который собирается с помощью Vite и после webpack'а это как глоток свежего воздуха. Что приложение что storybook (с vite внутри) собираются очень быстро.
Isolating and fixing a memory leak in a real Node.js web application
Короткий гайд про то, как найти утечку памяти в nodejs приложении.
Рекомендуемый алгоритм такой:
- Взять один из инстансов прод приложения после старта, вывести его из под трафика, сделать снапшот. Создание снапшота - ресурсоемкая операция. Поэтому мы выводим инстанс из под трафика и также нужно следить, чтобы инстансу хватило памяти так как для создания снапшота необходимо примерно столько же памяти, сколько уже используется приложением
- Ввернуть трафик на инстанс
- Снова вывести, сделать второй снапшот, сравнить их и провести анализ
При этом в статье есть ссылки на инструменты для этого и ссылки на три больших и полных гайда по устранению утечек памяти
Помните времена, когда каждый день появлялся новый стейт менеджер для React?
Это происходилл, потому что React, с одной стороны, не дает никаких рекомендаций по управлению состоянием, а с другой стороны, нужно решить несколько проблем:
- прокидывать данные через дерево компонент или напрямую в компонент?
- мутабельный или иммутабельный стор?
- один глобальный стор или много маленьких?
- а как оптимизировать ререндеры?
- как работать с сетью?
Каждый вопрос решается по-разному в разных решениях.
Статья подробно описывает и проблемы и решения, эволюцию подходов к управлению данными в React, и даже есть поверхностное сравнение каким образом решены одинаковые проблемы разными инструментами
Огромный и подробный туториал по тому, как сделать свои шахматы на JS. Здесь проектируется именно алгоритм игры, сама же доска и движок (то что обсчитывает, как могут двигаться фигуры, а как не могут) - берутся готовые.
В статье сначала разбирается простейшая задача - как сделать так, чтобы компьютер играл сам с собой, выбирая случайные ходы.
Это красиво, но лишено смысла. Поэтому автор постепенно делает более жесткие требования к движку и по-немногу добавляет логику.
Сначала учит алгоритм выбирать ходы, где есть взятие фигуры.
Но такие ходы тоже не оптимальны. Поэтому затем собирается min-max алгоритм для определения наилучшего хода.
Затем мы начинаем упираться в перформанс и автор погружает читателя в разные оптимизации.
В конце получается движок, который, по заверениям автора, может играть на ELO-рейтинге больше тысячи (кажется это уровень любительской игры обычного человека)
Если вам интересны алгоритмы или вы хотели когда-то сделать свои шахматы - обязательно к прочтению. Очень хорошая стать
GitHub - makenotion/notion-sdk-js: Official Notion JavaScript Client
Вышла версия 2.0 notion-sdk-js. Не знал, что вообще есть что-то подобное для автоматизации notion, а тут аж вторая версия.
Если вы активно пользуетесь notion (как я знаю, он достаточно популярен), то можно поиграться и сделать что-то полезное.
Bun - новый рантайм для JS (типа как NodeJS и Deno), который используется движок JavascriptCore, а обвязка вокруг написана на zig - это язык уровня C - низкоуровневый, ручное выделение памяти.
Из интересного в Bun встроен бандлер, транспайлер (поддерживает JSX и typescript), тестовый фреймворк, клиент для sqllite, менеджер пакетов.
Также из коробки поддерживается большинство NodeJS API, что позволяет использовать пакетов из нпм (да и вообще переиспользовать существующий nodejs код).
В документации написано, что много чего написано с нуля (например транспайлеры).
Также приводятся замеры, в которых bun просто разносит nodejs и deno по перформансу (разница в разы).
Однако, если провалится в бенчмарк по рендеру реакта - то к нему есть вопросики.
В общем, новый рантайм, но теперь на языке zic. Обещают что работает blazing fast, все есть из коробки и при этом совсестимо с NodeJS API.
Однако 01.0 бета версия и пока никто не пробовал в продакшне.
В целом развитие новых рантаймов считаю хорошим делом, но Bun на главной странице так себя продает, что появляется скепсис к нему. Посмотрим, что будет дальше.
Testing the boundaries of collaboration – Increment: Testing
Кент Бек, создатель Extreme Programming и популяризатора многих лучших практик, написал статью, в которой рассматривает вопрос минимального размера изменений.
Блокирующее асинхронное код-ревью является, на текущий момент, стандартом индсутрии. Про пользы и минусы код-ревью написано уже много, но мы выделим один минус - если мы используем блокирующее (нельзя влить код без апрувов) асинхронное (непонятно когда мы получим апрув) код-ревью, то мы не можем делать маленькие изменения в систему т.к. это приведет к огромноу количеству код-ревью и взаимных блокировок. Поэтому, как бы не были хороши практики про частые изменения, при блокирующем код-ревью разработчики мотивированы группировать свои изменения, чтобы снизить издержки на код-ревью.
Но даже если мы откажемся от код-ревью, у нас останется вопрос "а какой возможен минимальный объем изменений при применении CI и CD?".
В рамках эксперимента по достижению минимального объема изменений Кент Бек с другими разработчиками попробовали схему из двух практик при разработке небольшого пет-проекта.
Первая практика - Test-Commit-Revert (TCR)
Она заключается в том, что если мы пишем код и хотим его закомитить, то если тесты прошли - коммит создается, а если не прошли - все изменения удаляются.
```
python sample.py && git commit -am "working" || git reset --hard
```
Звучит дико, но это мотивирует делать очень маленькие и безопасные изменения. Применение этой практики изменило подход к разработке - вносимые изменения были не просто небольшими, они были крошечными. И частыми.
Вторая практика - это постоянный пуш и подтягивание изменений
В рамках эксперимента это было реализовано простым скриптом
```
while(true);
do
git pull --rebase;
git push;
done;
```
В результате совместной работы в рамках 1го репозитория участники получали чужие и отправляи свои изменения моментально. Код всех разработчиков моментально становился синхронизированным.
Конечно, такие практики нельзя просто взять и начать применять в реальных проектах. Для этого нужно менять культуру, нужные новые инструменты, нужны иные подходы к разработке. Решение проблем, блокирующих применение этих практик - ключ к быстрой разработке.
Sigma.js version 2 finally released! | médialab Sciences Po
Вышла 2 версия библиотеки sigma.js. Sigma.js это библиотека, которая умеет рисовать графы. В релиз-посте описывается краткая история таких инструментов, почему понадобилась 2 версияя sigma и что в ней нового.
Если коротко, то первая версия Sigma была написана в 2013 году и ее стало тяжело интегрировать с современным JS. Также было сложно имплементировать некоторые алгоритмы из теории графов и были возможности для оптимизации перформанса
Во второй версии библиотека переехала на современный JS, из коробки имеет разные методы обработки графа (по-крайней мере я так понял, что они доступны из коробки, а также рендер теперь в WebGL.
В посте пишут, что теперь можно рисовать огромные графы из десяток тысяч узлов и сотен тысяч связей.
Список фич, вошедших в ES2022 (большинство из них ддолжны быть вам уже знакомы):
**`arr.at()` позволяет получить элемент по индексу (включая кейсы `arr.at(-1)` для взятия последнего)**
```
const cart = ['🍎', '🍌', '🍍'];
cart.at(0); // '🍎'
cart.at(-1); // '🍍'
```
**матчинг по RegExp возвращает индексы сопоставленных строк**
```
let input = "12,34";
let match = /,(\d+)/.exec(input);
let indices = match.indices;
// Первый элемент отдает индексы всего сопоставления
indices[0]; // [2, 5];
// Второй элемент отдает индексы первой сопоставленной группы
indices[1]; // [3, 5];
```
**Object.hasOwn**
```
const obj = {
prop: true
}
Object.hasOwn(obj, 'prop') // true
Object.hasOwn(obj, 'toString') // false
'prop' in obj // true
'toString' in obj //true
```
**Error cause**
Фича, которую лично я ждал давно - возможно указать источник ошибки. Иногда в коде приходится перехватывать ошибки, обрабатывать их и кидать другие ошибки. Из-за этого изначальный стактрейс теряется. Эта фича позволяет нам явно указать, что мы кидаем ошибку, источник которой - другая ошибка
```
try {
someCode()
} catch (err) {
const newError = new Error('Новая ошибка', { cause: err })
newError.cause === err // true
throw newError;
}
```
Раньше, в общем-то, тоже никто не мешал заполнять поле `cause` и были разные подобрые решения или паттерны. Но они были разобщены и поэтому были несовместимы друг с другом. Также, т.к. это были нестандартные решения, то многие инструменты из коробки их не поддерживали (например, вывод ошибки в консоли браузера, обработка ошибки системой sentry)
**Top-Level await**
await теперь официально можно использовать на верхнем уровне модуля.
```
const result = await someAsyncFunction();
export { result }
```
**Class field declarations**
```
class SampleClass {
publicID = 42; // public field
static staticPublicField = -1;
static #staticPrivateField = 'private';
#privateMethod() {}
static {
console.log('выполняется при создании инстанса класса'
}
}
```
**ergonomic brand checks for private fields**
Возможность проверять наличие приватных свойств инстанса класса. Когда предлагали ввести приватные методы в ES, то была большая дискуссия на счет того, как правильно проверять существование приватного поля. Ведь вне кода этого класса не должно быть информации о том, есть поле или нет поля.
В итоге в ES2022 можно проверять наличие приватных свойств через static методы
```
class C {
#prop;
static isC(obj) {
return #prop in obj
}
}
```
Кто верстал письма, тот в цирке не смеется.
Верстка писем - достаточно непрочто занятие. Мало толо, что там в целом достаточно большие ограничения, так еще и разные почтовые клиенты ведут себя по разному. Какие-то переписывают все ваши стили, какие-то вырезают шрифты, другие автоматически применяют темную тему и меняют все ваши цвета.
А кроме этих приколов хочется еще уметь в локальное тестирование, DRY.
В статье автор рассказывает, как он делает email-рассылки и решает эти проблемы.
90% проблем, конечно, решает mjml. Mjml - это библиотека, которая адаптирует react-подход к верстке писем. Он позволяет выделять и переиспользовать компоненты, а также забирает на себя сложность низкоуровневой верстки писем (таблички через таблички).
Из интересного в статье, кроме mjml автор использует разные примочки вокруг.
Например, сами письма он пишет в MDX, а для отправки через системы доставки писем рендерит на next. Это позволяет ему реализовать веб-версию письма за ноль усилий.
В общем, если у вас есть задача верстки писем и вы хотите использовать хорошие подходы из разработки (DRY, хранение в коде, возможно даже автотесты) - рекомендую взглянуть на подходы, упомянутые в статье
Вышел Fresh 1.0 - фреймворк для приложений на Deno. Под капотом используется Preact. Даже есть файловый роутинг.
Из интересных осоьенностей:
- только тайпскрипт
- нет этапа сборки
- 0КБ js в браузер по умолчанию
Фреймворк использует Islands Architecture. Это паттерн, когда мы считаем, что почти все на сайте статично, а значит может рендерится на сервере, кроме островов (islands) интерактивности.
По умолчанию все рендерится на сервере и только острова поставляются на клиент.
40 релизов в неделю при разработке государственного Amazon или почему Agile is dead
Статья от ЛАНИТ, про то, как они пришли к частым релизам при разработке всяких гос-систем.
Это статья хорошая по двум причинам
Во первых, очень хорошо раскрывается, почему в целом в индустрии пришли к бест-практисам вида малых и частых релизов, автоматического тестирования, devops-культуры
Во вторых, автор рассказывает, как они эти практики применили при разработке гос-систем. Для меня то, что разработка гос-системы применила бест-практисы для разработки, а многие коммерческие команды не могут - достаточно интересное явление.
Очень кратко про посыл статьи:
- Чем больше задача, тем сложнее ее делать, сложнее тестировать. А стоимость разработки возрастает нелинейно
- Поэтому нужно уметь разрабатывать и доставлять функционал часто и маленькими кусками. Маленькие задачи проще делать, быстрее тестировать, при релизе маленькой задачи легче найти причину проблемы, в случае ее возникновния
- Чтобы научиться делать маленькие частые релизы надо научиться работать определенным образом
- Делить бизнесовые задачи на мелкие (в статье - пара дней разработки, но при этом задача понятна заказчику)
- Разрабатывать через фиче-флаги. Фиче-флаги помогают одновременно часто релизить приложение, но при этом не доставлять неготовые фичи до пользователей.
- Писать авто-тесты. Авто-тесты необходимо постоянно писать и постоянно запускать. Авто-тесты отлавливают регрессы, а если ни один авто-тест не упал - это может служить сигналов к релизу.
- Автоматизировать инфраструктуру. Необходимо, чтобы каждый член команды разработки мог сам вносить необходимые изменения в инфраструктуру. Но чтобы это делалось просто и надежно, должна быть сделана автоматизация для изменений инфраструктуры.
Просто великолепная статья про разработку в целом, написанная в шутливой манере.
По-началу может показаться, что это какое-то несерьезное чтиво, но на самом деле очень хорошо написано про основные принципы хорошей разработки.
В целом, ИМХО, похоже на "Идеальный программист" Роба Мартина, но короче и веселее.
Часть тезисов в тексте спорная, но в большинстве своем они весьма хороши.
Будь как груг!
When You Should Prefer Map Over Object In JavaScript
Статья, сравнивающая использование Map и {} для хранения данных.
В целом все сводится к следующему:
- Map имеет более удобное и богатое API. Например, в Map можно использовать как ключи что-угодно и удаление всех ключей делается просто через вызов метода clear. Также для некоторых операций для объектов нужно писать дополнительный код, чтобы они отрабатывали корректно. Например, необходимо сделать несколько приседаний, чтобы проверить, действительно ключа нет в объекте, или он есть, но там undefined
- Для большинства кейсов Map работает быстрее, чем объект
- Для объектов, у которых ключи - небольшие целые числа, работа с объектами - эффективнее в разрезе скорости и потребления памяти.
Последний пункт оказался неожиданным. В статье можно увидеть сравнение, где сравнивается скорость вставки и итерации по объектам\Map, у которых 100 ключей и эти ключи - случайные целые числа от 0 до 1000. И в этом сравнении обьекты значительно выигрывают. Но если поменять ключи на случайные целые числа от 0 до 1200, то Map становится в разы быстрее. Для разных значений количества полей в объекте будет разная "точка слома производительности" объекта.
В целом конечно есть вопросы к методике оценки производительности, также стоит учитывать, что скорость работы кода зависит от реализации в движках, а движки а) могут реализовать по-разному и иметь свои нюансы б) разработчики движков постоянно оптимизируют разные части движка.
Но в статье также указаны преимущества Map перед объектами с точки зрения Developer Experience. Имейте их в виду, при выборе между Map и объектом.
Дмитрий Карловский, он же nin-jin, он же автор фреймворка $mol, выложил на хабре краткий обзор свой последней статьи про реактивность. На хабре она получилась очень обрезанная и поэтому неинтересная, но в оригинале статья весьма хороша.
Дмитрий рассказывает, как построить супер крутую систему реактивности, которая, как водится в статьях Дмитрия, уделывает всех :)
В целом статья очень хороша по нескольким причинам:
- Настоящий хардкор. Таких хардкорных материалов мало
- Дмитрий показывает, как построить супер-реактивность по шагам, начиная с самых простых примитивов, а затем композируя их в во все более сложные
- Материал очень насыщен. Настолько, что некоторые части необходимо перечатывать. Но при этом - все понятно.
Рекомендую к прочтению, если вас заинтересовало мое краткое описание статьи
Notes on maintaining an internal React component library
Записки мейнтейнера внутреннего ui-kit команды DigitalOcean.
Автор описывает практики и прицнипы, которые считает основопологающими для создания хорошего ui-kit'а. Большая часть советов - правильные и хорошие.
Часть советов, на мой взгляд, не то что неправильные, просто очень субьективны и в некоторых контекстах могут причинить вред.
Философия ui-kit:
- Должно быть легко перенести дизайн в код
- Компонент должен быть черным ящиком для родителя, использующего его
- Решение в ui-kit'е должны быть одновременным очевидными, простыми и правильно в большинстве случаев
- Делать плохие вещи должно быть как минимум некомфортно, как максимум - невозможно.
Советы:
- У kit'а должен быть мейнтейнер или группа мейнтейнеров. Без мейнтейнерства измененися будут вноситься абы как, что через какое-то время сделает использование системы невозможной
- Интерфейс компонента должен лаконично представлять варианты использования компонента. Т.е. условно по одним пропсам можно понять, как компонент можно использовать
- Компонент не должен позиционировать себя сам
- Компоненту следует занимать все доступное горизонтальное пространство. Ограничения по размеру накладывает клиентский код.
- Не следует предоставлять API для изменения стилей. Однако, иногда следует все таки добавить для разработчиков для очень редких кейсов максимально неудобное API. И им должно быть очевидно что то, что они делают - неправильно и надо идти заводить задачу на команду ui-kit'а.
- Не следует стараться быть максимально похожими на базовые элементы
- Избегайте spread оператора в JSX
- Композиция компонентов должна быть бесплатной.
- Перед удалением чего-то из библиотеки, лучше пару мажорных версий обьявлять это как deprecated
- Код-моды позволяют ускорить массовые изменения по коду.
- Анализируйте то, как используются ваши компоненты. Лучше делайте это автоматически.
- Пишите скриншот-тесты
Я прошелся только по заголовкам. Вообще там в каждом пункте достаточно много мыслей про то, почему так стоит делать, с примерами кода. Если вы разарабываете ui-kit - must read.
Сначала Airbnb имели много css-стилей в scss файлах. Но затем они захотели перейти на css-in-js решения для повышения Developer Experience. Существующие решения им не понравились и они написали свою абстракцию над css-in-js решениями react-with-styles.
И в целом все было ок, но на текущих обьемах кода текущее css-in-js решение слишком "тяжелое" - от 10% до 20% времени старта приложения тратится на css-in-js решение.
Поэтому было принято решение, что нужно поменять текущее решение. Когда-то давно оно подходило, но сейчас контекст поменялся.
Был выбор между тремя путями:
- Извлечение CSS во время сборки
- Написать свой фреймворк
- Применить существующий фреймворк
Первое решение банально дорогое. Нужно потратить много усилий, но непонятно зачем их тратить.
Написать свой фреймворк - к счастью, у Airbnb нет NIH-синдрома. Поэтому они посчитали здраво, что существующие решения уже давно существуют, развиваются, учитывают фидбек комьюниты и успешно обрабатывают разного рода эдж-кейсы. Свой "золотой" инструмент мы не сделаем.
Поэтому лучше взять что-то готовое в сообществе и начать это использовать, возможно немного адаптировав под себя.
Получается нужно выбрать один из существующих фреймворков. Как кандидаты были выбраны:
- Emotion
- Treat
- Linaria
Ребята сделали какие-то перформанс замеры и выяснили, что все решения лучше чем текущее, но Treat и Linaria "лучше" чем Emotion, а Treat немного "лучше" чем Linaria, но Airbnb все равно выбрали Linaria как новый css-in-js инструмент.
Linaria позволяет писать css-in-js и при этом умеет извлекать стили из JS во время компиляции, но при этом умеет инжектить критический CSS при SSR, а также умеет во время сборки отбросить дубликаты css-свойств. Когда вы применяете 2 класса в коде, Linaria сама определяет какой итоговый набор css-свойств надо применить и извлекает в сss-класс только нужные.
Из преимуществ Airbnb также выделяет улучшение DX за счет того, что в Linaria для описания css используются шаблонные строковые литералы, в которых css-свойства пишутся также, как они пишутся в css (например `flex-direction` а не `flexDirection`)
Также airbnb использует atomic-css, но в Linaria нет поддержки для atomic стилей, но при этом Linaria из коробки умеет отбрасывать лишние свойства - что очень удобно.
Airbnb законтрибьютили в Linaria решение для atomic-css.
Миграция на Linaria была достаточно спокойной:
- Во первых, команды сами были мотивированы писать код на Linaria т.к. он был удобнее
- Во вторых, инженеры в Airbnb написали кодмоды для автоматической миграции (об этом в статье написано не очень подробно)
По перформансу: в результате перевода 10% компонентов, перформанс сайта улучшился на доли процентов - разные метрики стали лучше от 0.25% до 1.6%. Если перевести 90% кода, то должно быть лучше.
Итог:
- Airbnb мигрирует на Linaria, что одновременно улучшает и перформанс и DX.
- Для миграции используется автоматика в виде код-модов
- Airbnb при этом законтрибьютили код в Linaria, улучшив его для всех
Очень интересная во всех аспектах статья - есть и про миграцию большо количества кода и про выбор инструмента и про оценку эффекта от смены инструменты.
Вышел fastify 4.
Из важных изменений:
* Ускорение холодного старта
* Улучшение перформанса.
* Обновление Pino
* Задепрекейтили кучу разных способов вызвать listen, оставили основные 3
* Изменили композицию обработчиков ошибок
* Пофиксили разные случаи, когда было странное поведение
Introducing Opportunities & Experiments: Taking the Guesswork out of Performance - WebPageTest Blog
Webpagetest - это инструмент для анализа скорости работы сайтов. Он очень крутой, но, по моим ощущениям, малоизвестен.
Обычно все знают про lighthouse или sitespeed, но мало кто знает про webpagetest
У меня был положительный опыт использования webpagetest. Он позволяет замерить как простые сценарии вида "Зашел по ссылке и открыл сайт" так и сложные вида "зашел по ссылке, открыл сайт, ввел что-то поиск, нажал найти, выбрал первый результат".
При этом дается полный отчет начиная от базовых метрик типа TTFB, TTI, LT, так и метрики по каждому запросу, который делает браузер, и waterfall диаграмму по запросам и событиям и даже видео.
Также в нем можно сравнивать разные запуски между собой. На одной из прошлых работ мы с помощью webpagetest следили, чтобы наши базовые сценарии проходили быстрее, чем на сайтах конкурентов.
В общем, очень крутая штука. Но у нее был 1 недостаток. Webpagetest дает очень много инфы, но совсем непонятно, что же с ней делать.
Теперь же webpagetest запустили Opportunities & Experiments. Webpagetest сам находит проблемы с загрузкой сайта и предлагает провести эксперимент, который может их решить.
Например, у вас грузятся блокирующие сторонние скрипты. Webpagetest может в этом случае предложить вам проверить, как изменится скорость загрузки, если бы скрипты грузились асинхронно.
Раньше для такого же эксперимента нужно было:
* Уменять подменять контент страницы без изменения кода приложения. Не всегда можно быстро изменить код, задеплоить куда-нибудь, чтобы проверить как эксперимент влияет на загрузку. Поэтому нужно было придумать, как правильно подменить контент
* Додуматься до самой оптимизации. В данном примере она достаточно тривиальна и может быть очевидна. Но не все оптимизации настолько очевидны.
Теперь же webpagetest может значительно ускорить ускорение сайта т.к. с таким инструментарием очень легко найти проблему и проверить гипотезу, что решение проблемы действительно приведет к значительному ускорению.
Svelvet - библиотека компонентов на Svelte для создания интерактивных флоу диаграм.
Красиво выглядит и svelte под капотом. Даже захотелось сделать что-нибудь на основе этого.
Достаточно обширный туториал про монорепо. Рассказывается про:
- что такое монорепо и в чем отличие от монолита (в конце еще сравнивается с микрофронтендами о0)
- какие плюсы от использования монорепо
- типовая файловая структура монорепозиториев
- какие инструменты используются для работы монорепозиториев (что-то для воркспейсов (yarn, npm, pnpm) и что-то для запуска скриптов (lerna, nx, turbo))
- как настроить публикацию ченджлога и пакетов
В целом хорошая статья для тех, кто про монорепо слышал только краем уха и не в курсе что это и как это делается. Если вы уже знакомы с тем, что это, для чего это и как это реализуется - вряд ли вы увидите там что-то новое.
Статья про hurl - инструмент на rust для тестирования http серверов.
Hurl позволяет писать тесты вида:
- сделай запрос
- проверь его заголовки
- сделай дополнительный запрос
- проверь его
Автор приводит в плюс скорость его работы, хотя я пока не сталкивался с ситуацией, чтобы тестирование через http-запросы было медленным. Также автор говорит, что его студентам было легче писать тесты, используя hurl.
В целом выглядит интересно и стоит запомнить, что есть вот такой инструмент для тестирования, который подходит для интеграционного тестирования и контрактного тестирования.
Пример теста на hurl
```
# 1. Get the GitHub user info for @Orange-OpenSource
GET https://api.github.com/users/Orange-OpenSource
# 2. We expect to get back an HTTP/2 200 response. Also, assert
# various things about the Headers and JSON body. Finally
# capture the value of the `blog` property from the body into
# a variable, so we can use that in the next step.
HTTP/2 200
[Asserts]
header "access-control-allow-origin" == "*"
jsonpath "$.login" == "Orange-OpenSource"
jsonpath "$.public_repos" = 286
jsonpath "$.folowers" isInteger
jsonpath "$.node_id" matches /^[A-Za-z0-9=]+$/
[Captures]
blog_url: jsonpath "$.blog"
# 3. Get the blog URL we received earlier, GET it, and make
# sure it's an HTML page
GET {{blog_url}}
HTTP/2 200
[Asserts]
header "Content-Type" startsWith "text/html"
```
Рассказ про то, как работает https и зачем он нужен в виде комикса.
Выглядит очень красиво, рассказывается и про историю безопасности в сети и про протоколы достаточно просто и наглядно
Lerna - она теперь как феникс.
Сначала обьявили о том, что проект больше не разрабатывается, затем команда NX взяла на себя мейнтейнерство над проектом, а теперь выходит релиз 5.1-beta в котором Lerna под капотом позволяет использовать NX и тем самым добивается ускорение работы скриптов в 10 раз по сравнению с "без NX", а также в 5 раз быстрее чем Turborepo (еще 1 инструмент для монорепо).
Бенчмарки, возможно, немножко синтетические (например, они могут быть специально проверять только кейсы, в которых NX справляется лучше чем turborepo), но для существующих пользователей Lerna это точно хорошее дело.