Dev News от Максима Соснова @msosnovfeed Channel on Telegram

Dev News от Максима Соснова

@msosnovfeed


Привет! Меня зовут Максим Соснов и по утрам я читаю всякие разные дайджесты про фронтенд, разработку и управление разработкой. Самые интересные, по моему мнению, ссылки из этих дайджестов я кидаю в этот канал с небольшим описанием.

Контакт: @msosnov

Dev News от Максима Соснова (Russian)

Добро пожаловать в Telegram-канал "Dev News от Максима Соснова"! Меня зовут Максим Соснов, и каждое утро я тщательно изучаю различные дайджесты по фронтенду, разработке и управлению проектами. Все самые интересные и актуальные материалы я выкладываю в этот канал с кратким описанием, чтобы вы всегда были в курсе последних новостей и тенденций в мире IT.

Здесь вы найдете ссылки на статьи, видео, инструкции и многое другое, что поможет вам быть в курсе современных технологий и методов разработки. Если вам интересна IT-индустрия, вы точно оцените ценность информации, которую я собираю для вас.

Присоединяйтесь к нашему каналу, чтобы получать актуальные обновления и быть в курсе всех новостей от меня, Максима Соснова. Не упустите возможность узнавать первыми о самых важных событиях и разработках в мире технологий!

Связаться со мной вы можете через мой личный контакт: @msosnov

Dev News от Максима Соснова

21 Nov, 07:00


Legacy Modernization meets GenAI

Статья в блоге Мартина Фаулера про то, как они в ThoughtWorks используются нейронки для модернизации всякого легаси.

Как только нейронки стали публично доступными и удобными, в ThoughtWorks начали с ними экспериментировать. Один из очевидных юзкейсов для нейронок - это работа с кодом: документирование, переписывание, построение модели системы по коду. Для легаси систем это супер актуальная задача.

В ThoughtWorks есть клиенты, у которых есть легаси приложение без хорошей документации и которым нужно либо сделать в нем изменения либо переписать его. Как обычно происходили такие задачи: команда инженеров погружалась в код, ревьюила его, строила диаграммы работы системы, выделяла бизнес-правила. Это занимало около 6 недель на 1 модуль из 10к строк.

В ThoughtWorks придумали сделать систему, которая ускорит этот процесс - CodeConcise. Берется код, преобразуется в AST, анализируются связи между разными файлами на уровне кода (например, модуль А зависит от модуля Б, но только при использовании метода Х). По этой инфе уже работает CodeConcise, внутри которого нейронка

Использование CodeConcise ускоряет разбор легаси модуля с 6 недель до двух.

Что еще пробовали делать с кодом через нейронку:
- Удалять мертвый код - оказалось не очень эффективно, относительно тулов, которые уже есть в индустрии
- Переписывать код с 1го стека на другой - также оказалось не эффективно. Код оказывался низкого качества.

https://martinfowler.com/articles/legacy-modernization-gen-ai.html

#development #martinFowler #chatgpt #ai #refactoring

Dev News от Максима Соснова

20 Nov, 07:00


Организация базы знаний в obsidian

Наконец-то я настроил пайплайн выпуска постов так, что могу вставлять сюда контент без ссылок :) Поисследуем, насколько интересны авторские посты.

Что я имею в виду под знаниями:
- Шпаргалки по использованию инструментов
- Полезные ссылки
- Конспекты и интересные идеи
- MN-ки
- Заметки по проекту или разным областям

Давайте поговорим об организации своих знаний в каком-то инструменте. Кто-то этого вообще не делает (и хранит все в голове), кто-то по хардкоду переводит вообще все знания в какие-то инструменты

Самый необычный инструмент для хранения знаний, который я видел, это Trello. Чел (привет Костя) заводил карточку на trello-доске под каждую тему и в ее контенте и комментариях скидывал всякое интересное.

Самые популярные, из тех что я вижу у своих коллег, это notion и встроенные в ОС заметки.

Лично мне оба инструмента не нравятся:
- Notion чисто онлайн-инструмент - не очень отзывчивый, не очень быстрый. Зато, конечно, удобный, позволяет сделать красиво и позволяет настроить совместную работу. Но главный минус, для меня, это vendor-lock. Сложно перейти из Notion куда-то, сложно делать офлайн-бекапы. В случае если Notion решит вас заблокировать, то можно потерять все свои заметки
- Встроенные в ОС заметки как правило плохо шарятся между устройствами. В целом это очередной vendor-lock

В какой-то момент я перешел на работу с markdown-файлами. Почему так:
- Полный контроль над контентом. Это просто файлы - храню где хочу, легко бекапить, легко синхронизировать, можно открыть на любом тостере
- Markdown легко конвертировать в другие форматы. Например, посты в канал я пишу в markdown и телега их принимает. Заметки по работе я тоже пишу в markdown и в confluence есть конвертер из markdown в confluence формат
Конечно же есть и минусы:
- markdown формат весьма ограничен. Приходится, как минимум, отказаться от работы с таблицами
- Тяжело найти инструмент, который оставит полный контроль над файлами и позволит легко шарить эти файлы и работать с ними в режиме совместной работы

Я попробовал несколько разных инструментов для работы с markdown, но в итоге остановился на obsidian.

Obsidian - это приложение, которое создано вокруг идеи Zettelkasten. Сам метод Zettelkasten я не использую т.к. имхо, проблемы, которую решал Zettelkasten уже нет. Obsidian из коробки позволяет работать с папкой с markdown файлами как с базой знаний: можно линковать файлы друг с другом, организовывать вокруг тэгов, быстро рефакторить их (например, вынести часть заметки в другую и тут же оставить ссылку в текущем документе на новую заметку). Также obsidian очень мощный благодаря плагинам от сообщества: их много, они часто немного сыроваты, но в целом хорошо расширяют возможности Obsidian.

Используемые мной плагины:
- Outliner - позволяет удобно работать со списками
- Dataview - позволяет строить запросы по заметкам
- Excalidraw - позволяет рисовать диаграммы прямо в obsidian, используя excalidraw
- Whisper - позволяет наговаривать аудио, которое потом распознается в текст с помощью whisper
- Templater - позволяет создавать заметки по шаблону
- Tasks - добавляет работу с задачами - можно делать запросы в Dataview, ставить дедлайны, связывать задачи
- Meta Bind - позволяет создать удобные кнопки с кастомной логикой
- Advanced Slides - позволяет делать слайды на основе reveal.js. Использую для простых презентаций

С этими плагинами (и еще парочкой мелких) я веду 3 базы знаний:
- По каналу. Вот прям щас пишу в ней пост
- По работе. Там все задачи, заметки, MN-ки, ведение больших проектов, 1:1, слайды
- Личный. Там все общие заметки как по разработке, так и просто житейские. Также там конспекты по книжкам.

База знаний для канала синхронизируется через гит
База знаний по работе только на рабочем ноуте
Личная база знаний синхронизируется по гугл диску

А как вы организуете свою базу знаний?



#note #obsidian #knowledgeManagement

Dev News от Максима Соснова

18 Nov, 07:00


setImmediate() vs setTimeout() in JavaScript

Хороший разбор того, как в NodeJS работает event-loop на примере разбора порядка вызовов setTimeout и setImmediate.

Посмотрите на этот код
setImmediate(() => {
console.log("setImmediate 1");
});

setTimeout(() => {
console.log("setTimeout 1");
}, 0);

setTimeout(() => {
console.log("setTimeout 2");
}, 0);

setImmediate(() => {
console.log("setImmediate 2");
});


Предположите, в каком порядке пойдет вывод в консоль?

Я, честно сказать, не так сильно погружен в особенности работы ивент-лупа, поэтому ответил неправильно. Не ожидал я что setTimeout пойдет первым

setTimeout 1
setImmediate 1
setImmediate 2
setTimeout 2


Почему так происходит? Потому что event loop в NodeJS работает следующим образом:
- Таймеры
- Колбеки IO
- Хендлинг IO
- Check

Когда мы вызываем setTimeout(cb, 0) мы складываем задачу в ивент луп. Задачи берутся по одной и колбек таймаута разберется в фазе таймеров. Затем выполняются IO-фазы, а затем фаза Check. setImmediate как раз выполняется в фазе Check, причем с гарантией, что все задачи этой фазы разберутся сразу после IO.

Поэтому получается так, что
- Из ивентлупа забирается первый таймер
- Исполняется
- Проходит IO
- Выполняется Check, в рамках которого выполняются все setImmediate
- Goto start

При этом, если мы поставим таймер и immediate в рамках колбека IO, то можно получить другой результат

const fs = require('fs');

fs.readFile('example.txt', () => {
setTimeout(() => {
console.log("setTimeout after I/O");
}, 0);

setImmediate(() => {
console.log("setImmediate after I/O");
});
});



setImmediate after I/O
setTimeout after I/O


Так происходит, потому что setImmediate был зарегистрирован во время одной из IO фаз и в этом случае он будет выполнен сразу после IO. А колбек setTImeout будет взят позже из ивент-лупа

https://www.trevorlasn.com/blog/setimmediate-vs-settimeout-in-javascript

#development #javascript #setImmediate #setTimeout

Dev News от Максима Соснова

18 Nov, 06:06


Дайджест за 2024-11-11 - 2024-11-15

Crafting a 13KB Game: The Story of Space Huggers
Периодически проходит интересный челлендж - необходимо создать игру на JS, которая поместится в 13кб. Всегда интересно почитать, как люди делают полноценные игры и умещают их в такой крохотный размер.

Данная статья - как раз одна из таких. Автор одной из игр делится тем, как создать такую игру. Здесь не так много технических деталей, связанных с JS, но зато очень много про сам гейм-дизайн и про принятие решений.

Announcing Official Puppeteer Support for Firefox
Наконец-то появилась официальная поддержка firefox в puppeteer. Теперь можно использовать puppeteer для работы с firefox.

Из интересных технических деталей в статье: было два основных варианта для реализации интеграции с puppeteer:

Common Causes of Memory Leaks in JavaScript
Хорошая статья про утечки памяти.

How we shrunk our Javascript monorepo git size by 94%
У статьи очень кликбейтное название. Я сначала подумал, что чуваки комитили node_modules и теперь решили его удалить или что-то в этом роде. Но все оказалось куда интереснее.

Есть команда в Microsoft, которая разрабатываем в большом монорепо на JS. Называется это 1JS, в нем около 20 миллионов строк кода, 2500 пакетов, а клонирование требует 178 гигабайт дискового пространства и некоторые коллеги из Европы (странное уточнение от автора, ну да ладно) не могли его склонировать.

Самые тяжелые NPM пакеты
Одновременно интересная и практически бесполезная таблица с самыми тяжелыми npm пакетами и тем, сколько мирового интернет траффика они потребляют.

Рассчет трафика достаточно простой: берем вес tar.gz пакета, берем количество загрузок в неделю, перемножаем, получаем трафик в неделю

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂

Dev News от Максима Соснова

15 Nov, 07:00


Самые тяжелые NPM пакеты

Одновременно интересная и практически бесполезная таблица с самыми тяжелыми npm пакетами и тем, сколько мирового интернет траффика они потребляют.

Рассчет трафика достаточно простой: берем вес tar.gz пакета, берем количество загрузок в неделю, перемножаем, получаем трафик в неделю

Самый большой трафик создают swc, typescript, next, esbuild, aws-sdk, pnpm, prettier, date-fns

Jquery на 178 месте по трафика. React-dom - 28, сам React - 275.

В целом можно посмотреть за популярностью инструментов для сборки и самыми популярными либами.



https://docs.google.com/spreadsheets/d/1oYJxQgMA7lQ6-wNaBKNNDz6vr3Yaa1EDsI_Hakr4ROg/edit?gid=1891857584#gid=1891857584

#development #javascript #npm

Dev News от Максима Соснова

14 Nov, 07:00


How we shrunk our Javascript monorepo git size by 94%

У статьи очень кликбейтное название. Я сначала подумал, что чуваки комитили node_modules и теперь решили его удалить или что-то в этом роде. Но все оказалось куда интереснее.

Есть команда в Microsoft, которая разрабатываем в большом монорепо на JS. Называется это 1JS, в нем около 20 миллионов строк кода, 2500 пакетов, а клонирование требует 178 гигабайт дискового пространства и некоторые коллеги из Европы (странное уточнение от автора, ну да ладно) не могли его склонировать.

История про клонирование 178 гигабайт звучит очень странно т.к. я точно помню, что microsoft делала свою файловую систему для работы с огромными гит-репозиториями, которая решает проблему клонирования "лишних" файлов. Ну, видимо в репозитории 1JS это не так.

В репозитории есть 2 основных ветки - mainи versioned. В первой ведется разработка, во второй ведутся релизы. По сути ветка versioned хранит в себе изменения CHANGELOG.md и CHANGELOG.json. На удивление, обнаружилось, что именно эти файлы приводят к тому, что в дереве гита приходится хранить дополнительные 125 гигабайт данных.

Почему так? По умолчанию, алгоритм запаковки изменений и снапшотов в git для идентификации файла использует только последние 16 символов названия файла. Поэтому, если изменить repo/packages/foo/CHANGELOG.json, то git будет собирать diff и к repo/packages/bar/CHANGELOG.json (пересчитал символы, у меня получилось что 15 совпадают, а 16 отличается. Либо я не так считаю, либо что-то не так понял). Т.к. это монорепо с 2500 пакетов, то ченджлогов много и git считает дифф каждый к каждому (опять же, если я правильно понял).

Это можно поправить, увеличив окно для сравнения. Для этого ребята добавили возможность регулировать это окно в git for windows. После перепаковки репозитория, размер уменьшился с 178ГБ до 5ГБ.

Очень интересная история с неожиданной развязкой. Никогда бы не подумал что ведение ченджлога может привести к 94% затрат на размер репозитория.

https://www.jonathancreamer.com/how-we-shrunk-our-git-repo-size-by-94-percent/

#development #javascript #performance #monorepo #git #microsoft

Dev News от Максима Соснова

13 Nov, 07:00


Common Causes of Memory Leaks in JavaScript

Хорошая статья про утечки памяти.

Статья начинается с разбора типов памяти в V8.

Есть:
- RSS (Resident Set Size) - все используемая память
- Heap Total - Память выделенная под JS-объекты
- Heap Used - Память, используемая JS-объектами
- External - Память под С++ объекты, прилинкованные к JS объектам
- Array Buffers - Память выделенная под ArrayBuffer. Используется для хранения бинарных данных

Получить текущее использования можно так

console.log('Initial Memory Usage:', process.memoryUsage());


Initial Memory Usage: {
rss: 38502400,
heapTotal: 4702208,
heapUsed: 2559000,
external: 1089863,
arrayBuffers: 10515
}



Основные причины утечки памяти:
- Плохая работа с данными. Например, когда данные уже не нужны, а мы все еще их храним (в глобальной переменной или в замыкании)
- Плохая работа с event listeners. Если их не удалять, после того как они стали не нужны, они будут также держать объекты и защищать их от сборки
- Замыкания
- Некорректной использование bind. Например, мы забиндили метод к this, но в методе this не используется. В этом случае из-за bind GC не сможет собрать то, на что забинжена функция (this).
- Циклические зависимости (пример в статье интересный - this.reference = this;

Третья часть статьи описывает, как же профилировать использование памяти в ноде.

Сначала надо запустить процесс с записью лога node --prof server.js
Затем необходимо прочитать лог node --prof-process isolate-0x140008000-42065-v8.log > processed-profile.txt

Что выдаст в файл человеко-читаемый профайлинг, где описано, какие функции запускались, сколько времени заняли, какие объекты аллоцированы

https://www.trevorlasn.com/blog/common-causes-of-memory-leaks-in-javascript

#development #javascript #performance #memoryLeak

Dev News от Максима Соснова

12 Nov, 07:00


Announcing Official Puppeteer Support for Firefox

Наконец-то появилась официальная поддержка firefox в puppeteer. Теперь можно использовать puppeteer для работы с firefox.

Из интересных технических деталей в статье: было два основных варианта для реализации интеграции с puppeteer:
- Использовать WebDriver BiDi протокол. Это штука, которая была стандартизирована еще w3c и поверх нее, как я помню, работает selenium
- Использовать CDP (chrome dev-tools protocol), по которому puppeteer работает с хромом, т.е. по сути надо имплементировать CDP в firefox; Или сделать интеграцию puppeteer с RDP - это аналог CDP но для firefox

Сначала попробовали сделать экспериментальную и ограниченную поддержку CDP в firefox. Но решили что лучше идти в сторону Webdriver BiDi, как более стандартизированная и кросс-браузерная штука.

https://hacks.mozilla.org/2024/08/puppeteer-support-for-firefox/

#development #javascript #puppeteer #firefox

Dev News от Максима Соснова

11 Nov, 07:00


Crafting a 13KB Game: The Story of Space Huggers

Периодически проходит интересный челлендж - необходимо создать игру на JS, которая поместится в 13кб. Всегда интересно почитать, как люди делают полноценные игры и умещают их в такой крохотный размер.

Данная статья - как раз одна из таких. Автор одной из игр делится тем, как создать такую игру. Здесь не так много технических деталей, связанных с JS, но зато очень много про сам гейм-дизайн и про принятие решений.

Хорошее чтиво на вечер

https://frankforce.com/space-huggers-how-i-made-a-game-in-13-kilobytes/

#development #javascript #game

Dev News от Максима Соснова

11 Nov, 06:09


Дайджест за 2024-11-05 - 2024-11-08

Максим Соснов. Двое за ноутом, не считая copilot’а, или Как внедрить парное программирование
Мое выступление на codefest про парное программирование и его применение в нашей команде.

Please Stop Using Barrel Files
Статья про вред от использования barrel-файлов.

Optimizing SPA load times with async chunks preloading
Небольшая статья про оптимизацию загрузки асинхронных чанков в SPA-приложении.

React Switchboard
React-switchboard - библиотека для создания своих дев-тулов в приложении. Под дев-тулами тут имеются в виду быстрый способ управлять поведением приложения. Например, залогиниться под определенным юзером, получить какое-то специфичное состояние или настройка мокирования определенных сетевых запросов.

В общем, готовая библиотека на случай, если вам нужен быстрый способ настроить контекст или окружение.

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂

Dev News от Максима Соснова

08 Nov, 07:00


React Switchboard

React-switchboard - библиотека для создания своих дев-тулов в приложении. Под дев-тулами тут имеются в виду быстрый способ управлять поведением приложения. Например, залогиниться под определенным юзером, получить какое-то специфичное состояние или настройка мокирования определенных сетевых запросов.

В общем, готовая библиотека на случай, если вам нужен быстрый способ настроить контекст или окружение.

https://github.com/coryhouse/react-switchboard

#development #javascript #react #library

Dev News от Максима Соснова

07 Nov, 07:00


Optimizing SPA load times with async chunks preloading

Небольшая статья про оптимизацию загрузки асинхронных чанков в SPA-приложении.

В чем вообще проблема: как правило, если у вас SPA, у вас есть роутинг, в который асинхронными чанками подключены страницы.

Если сильно утрировать, то в коде проекта есть что-то типа:
const routes = {
'/': import('pages/main'),
'/search': import('pages/search')
}


Чем это плохо: сначала грузится основной скрипт приложения. Он парсится, запускается и только потом браузер начинает грузить чанк. В итоге мы задерживаем рендер страницы.

Примерно та же проблема есть и при навигации. Пользователь делает действие, которое должно перекинуть его на страницу search и снова ждет загрузки скрипта.

Что предлагает автор: надо написать свой плагин для сборщика, который будет инжектить скрипт загрузки нужного чанка. Звучит мощно

5 простых шагов для реализации идеи:
- Добавляем имена чанкам import(/* webpackChunkName: "main" */ "./pages/main")
- Пишем плагин (в случае автора - плагин для RSPack)
- Плагин получает стату сборки и из нее достает ссылку до именованного чанка
- В проекте заводится способ нахождения имени чанка по текущему урл
- Плагин инжектит скрипт в head, который на основе window.loocation.href находит нужное имя чанка и инжектит ссылку до чанка в link rel=preload.

Таким образом достигается ускорение загрузки страниц.

Как альтернатива, достойная отдельная статьи, упоминается предзагрузка на стороне сервис-воркера.

https://mmazzarolo.com/blog/2024-08-13-async-chunk-preloading-on-load/

#development #javascript #performance

Dev News от Максима Соснова

06 Nov, 07:00


Please Stop Using Barrel Files

Статья про вред от использования barrel-файлов

Немного контекста, что такое barrel file. Это когда у нас есть папка dir с файлами someFile1.ts и someFile2.ts.
Мы могли бы импортировать их так

import { someFunction } from 'dir/someFile'
import { someFunction2 } from 'dir/someFile2'


Но есть паттерн barrel (в переводе бочка) файлов, когда мы в папке dir создаем index.ts, который ре-экспортит все внутренние сущности

dir/index.ts
export { someFunction } from './someFile'
export { someFunction2 } from './someFile2'


Использование
import { someFunction, someFunction2 } from 'dir'


Какие минусы выделяет автор у таких файлов:

Первый минус - циклические импорты. Тут автор дает какой-то странный юзкейс, когда мы в файлах внутри папки dir также делаем все импорты через index. В этом случае index импортирует модули, а модули импортируют другие модули через index. Это максимально странное использование паттерна

Второй минус уже более близок к реальности - barrel-file ведут к замедлению перформанса инструментов сборки. Когда в тулинге сборки появилась оптимизация по выбросу неиспользуемых экспортов, в сознании разработчиков это отпечаталось как "если я не использую экспорт, его стоимость для сборки - нулевая". Однако, это не так. Если вы используете jest для юнит-тестов, то вы напрямую можете столкнуться с этой проблемой, т.к. jest не занимается три-шейкингов и если вы импортируете 1 маленькую функцию из barrel-файла - вы, на самом деле, импортируете весь модуль.

Автор приводит в пример свой проект, где замена импортов на прямые ускорила сборку на 70% (также могу подтвердить такое по своему опыту борьбы с jest).

Также автор приводит в пример опыт Next.js, которые для борьбы с этой проблемой сделали фичу optimizePackageImports, которая заменяет импорты из barrel-файлов на прямые импорты во время сборки

Не смотря на минусы, такие файлы могут быть полезны, если используются по назначению: для организации публичного API библиотеки

https://tkdodo.eu/blog/please-stop-using-barrel-files

#development #javascript #barrelFile

Dev News от Максима Соснова

05 Nov, 13:18


Давно не делился папками с телеграм каналами 🙃

Тут завели новую тг-папку, называется "Архитектура", но это обманчивое название - там много каналов от фронтенд-разработчиков (в том числе этот канал) 😁

Подборка хорошая, подписался на парочку челиков. Рекомендую хотя бы ознакомиться со списком, вдруг найдете что-то интересное для себя

https://t.me/addlist/Pk3F9xr4il5lZTc6

Dev News от Максима Соснова

05 Nov, 07:00


Максим Соснов. Двое за ноутом, не считая copilot’а, или Как внедрить парное программирование

Мое выступление на codefest про парное программирование и его применение в нашей команде.

Весьма обзорный доклад (как почти и все у меня). Посмотрите, если вы про парное программирование слышали только отдаленно или если вам интересна практика, но вы не знаете с какой стороны к ней подойти. Если вы уже применяете парное программирование в команде, то вряд ли в этом докладе для вас будет что-то новое (все таки целевая аудитория доклада как раз те, кто не применяет)

Для меня откровением оказалось, что самая скучная (по моему мнению) часть доклада являлась самой интересной для многих слушателей. Повод, конечно, сделать отдельный пост про парное программирование, но на сайд-активности остается мало времени, а их много :С

https://www.youtube.com/watch?v=T14D2GVHGgw&list=PL8761XQAJnrb2Z-Q50OocgfyAyAMlDDEs&index=14
https://vk.com/video/@codefest/playlists?z=video-65336816_456239569%2Fclub65336816%2Fpl_-65336816_29

#development #pairProgramming #extremeProgramming #codefest #speech

Dev News от Максима Соснова

05 Nov, 04:58


Дайджест за 2024-10-28 - 2024-10-31

pretty-print
pretty-print - библиотека для удобного вывода в консоль любых JS-значений. Когда делаешь обычный console.log по большим объектам, то там легко наступить на кейс, когда в каком-нибудь поле выведется Object object. Эта "проблема" решается с помощью JSON.stringify, но либа предлагает еще кучу всякого и удобного

При кажущейся простоте задачи, либа имеет много методов и много опций (когда смотришь доку, видишь что это реально комбайн). Например, из интересных юзкейсов - либа умеет выводить свойства прототипа рядом со свойством объекта, отмечая их отдельным символом.

Inverse Assertions
Небольшая статья, которая рассказывает как правильно проверять в тестах, что сайд-эффекта не случилось. Например, вам нужно проверить, что после клика на кнопку уведомление не появилось.

Логично сделать что-то типа expect(notification).not.toBeInTheDocument(). Но что, если нотификашка появляется не сразу?

ECMAScript proposal updates 2024-10
Пришел октябрьский апдейт по пропозалам в EcmaScript.

В 4 стейдж перешли Promise.try, Import Attributes, RegExp Modifiers, Sync Iterator helpers, JSON Modules

Announcing Deno 2
Вышел Deno 2.0. Сделали аж целое часовое видео про то, какой Deno крутой. Сам видос начинается с немного кринжовой рекламы про то, как тяжело разработчикам без Deno и как хорошо с Deno.


——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂

Dev News от Максима Соснова

31 Oct, 07:00


Announcing Deno 2

Вышел Deno 2.0. Сделали аж целое часовое видео про то, какой Deno крутой. Сам видос начинается с немного кринжовой рекламы про то, как тяжело разработчикам без Deno и как хорошо с Deno.

Что нового в Deno 2 (согласно статье):
- Обратная совместимость с nodejs и npm (можно запустить свое node.js приложение в deno без дополнительных усилий)
- Поддержка package.json и node_modules
- Свой менеджер пакетов - deno install, deno add, deno remove
- Стандартная библиотека (вместо десятка пакетов из npm)
- Поддержка приватных реджистри
- Поддержка воркспейсов и монорепо
- LTS-релизы
- JSR - свой модный реджистри пакетов

Также улучшили много существующих фичей:
- deno fmt теперь умеет в HTML, CSS, YAML
- deno lint теперь умеет в специфику Node
- deno test теперь поддерживает тесты, написанные с помощью node:test
- deno task запускает скрипты из scripts
- deno doc - улучшили вывод
- deno compile - поддерживает подпись и иконки для Windows
- deno serve теперь умеет запускать сервер на нескольких ядрах
- deno init позволяет инициализировать библиотеки и сервера
- deno jupyter теперь поддерживает изображения, графы и HTML
- deno bench теперь более точно замеряет
- deno coverage теперь умеет отдавать вывод в HTML

https://deno.com/blog/v2.0

#development #javascript #deno #release

Dev News от Максима Соснова

30 Oct, 07:00


ECMAScript proposal updates 2024-10

Пришел октябрьский апдейт по пропозалам в EcmaScript.

В 4 стейдж перешли Promise.try, Import Attributes, RegExp Modifiers, Sync Iterator helpers, JSON Modules

Promise.try
Позволяет завернуть колбек в промис
До Promise.try
await new Promise((resolve) => resolve(fn()))


С Promise.try
await Promise.try(fn)


Import Attributes
Позволяет указать мета-информацию для импортов
import json from "./foo.json" with { type: "json" };
import("foo.json", { with: { type: "json" } });


RegExp Modifiers
Модификаторы RegExp (например i, m и другие) теперь можно использовать и в под-выражениях
Пример из доки (внимание на группы, внутри которых используется i)
const re1 = /^[a-z](?-i:[a-z])$/i;
re1.test("ab"); // true
re1.test("Ab"); // true
re1.test("aB"); // false

const re2 = /^(?i:[a-z])[a-z]$/;
re2.test("ab"); // true
re2.test("Ab"); // true
re2.test("aB"); // false


Sync Iterator helper
Добавляет удобные методы (map, filter, take, flatMap, reduce, toArray, forEach , some , every, find, from) для работы с итераторами
Пример
function* naturals() {
let i = 0;
while (true) {
yield i;
i += 1;
}
}

const result = naturals()
.take(5)
.reduce((sum, value) => {
return sum + value;
}, 3);

result // 13


В stage-3 перешел Atomics.pause. Этот метод позволяет указать, что треду следует встать на короткую паузу. Это позволяет более оптимально использовать CPU

В stage-2.7 перешли: Error.isError и Iterator Sequencing

Error.isError решает ту же проблему что и Array.isArray, а именно создание инстансов Ошибки в разных контекстах (например, iframe имеет полностью свой контекст и там свой класс Error, поэтому проверка ошибки на instanceof Error в родительском контексте выведет false т.к. в родительском контексте есть свой класс Error)

Iterator Sequencing добавляет API для объединения итераторов.
Например, у вас есть 2 итератора и вы между ними еще хотите добавить значений. Сейчас самый удобный способ сделать это

let lows = Iterator.from([0, 1, 2, 3]);
let highs = Iterator.from([6, 7, 8, 9]);
let digits = function* () {
yield* lows;
yield 4;
yield 5;
yield* highs;
}();

Array.from(digits); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


А будет
let lows = Iterator.from([0, 1, 2, 3]);
let highs = Iterator.from([6, 7, 8, 9]);
let digits = Iterator.concat(lows, [4, 5], highs);



В stage-2 пришли Extractors, structs, iterator chunking

Extractors - это расширение деструктуризации, которое позволяет сразу обработать деструктурированное значение.
Проще всего показать на примере
Сейчас приходится делать так:
const { field: rawField } = data 
const field = process(rawField)


Пропозал позволяет сделать так
const processData({ field }) = data


Ну и пример того как сделать простую деструктуризацию в этом пропозале
class C {
#data;
constructor(data) {
this.#data = data;
}
[Symbol.customMatcher](subject) {
return #data in subject && [this.#data];
}
}

const subject = new C({ x: 1, y: 2 });

const C({ x, y }) = subject;
x; // 1
y; // 2


structs добавляет структуры в язык. Это более строгая версия классов. Эта штука нужна для повышения производительности (в том числе для кейсов с воркерами)

struct Box {
constructor(x) { this.x = x; }
x;
}

let box = new Box(0);
box.x = 42; // x is declared
assertThrows(() => { box.y = 8.8; }); // structs are sealed
assertThrows(() => { box.__proto__ = {}; }); // structs are sealed


iterator chunking - мега простой пропозал, позволяет нарезать итератор на куски
const digits = () => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].values();
let chunksOf2 = Array.from(digits().chunks(2));
// [ [0, 1], [2, 3], [4, 5], [6, 7], [8, 9] ]



https://ecmascript-daily.github.io/ecmascript/2024/10/12/ecmascript-proposal-update

#development #javascript #ecmascript #proposal

Dev News от Максима Соснова

29 Oct, 07:00


Inverse Assertions

Небольшая статья, которая рассказывает как правильно проверять в тестах, что сайд-эффекта не случилось. Например, вам нужно проверить, что после клика на кнопку уведомление не появилось.

Логично сделать что-то типа expect(notification).not.toBeInTheDocument(). Но что, если нотификашка появляется не сразу?

Можно поставить какой-нибудь sleep. Лично я во всех проектах делаю утилку const wait = (msec) => new Promise(resolve => setTimeout(resolve, msec)), который, по сути, и есть sleep и вызывается как await wait(1000). Проблема с таким подходом, что мы либо подбираем эмпирически нужное значение ожидания, либо завязываемся на детали реализации (т.е. должны знать через сколько примерно появляется нотификашка)

Как же делать правильно. В testing-library есть waitFor - функция резолвнет промис, как только её колбек пройдет

Например
await waitFor(() => {  
expect(notification).toBeVisible()
})


Сам waitFor в данном случае очень полезен - мы просто пишем что ожидаем какого-то условия и это позволяет нам отвязаться от деталей реализации, а также гарантирует что мы не будем ждать лишнее время (как в случае со sleep)

Но тут нам мешает, что waitFor ожидает успешного колбека. Т.е. если мы напишем

await waitFor(() => {
expect(notification).not.toBeInTheDocument()
})


То waitFor завершится сразу же, хотя нотификашка может появиться позже.

Решение здесь - инвертировать проверку

const notificationVisiblePromise = waitFor(() => {
expect(notification).toBeVisible()
})

// Assert that the notification promise has, eventually, rejected.
await expect(notificationVisiblePromise).rejects.toThrow()


В данном случае мы через waitFor проверяем, что нотификашка хотя бы раз появилась. И затем ожидаем что промис от waitFor реджектнется, что позволяет быть увереным в том, что нотификашка не появилась.

https://www.epicweb.dev/inverse-assertions

#development #javascript #testingLibrary #testing #assertions

Dev News от Максима Соснова

28 Oct, 07:00


pretty-print

pretty-print - библиотека для удобного вывода в консоль любых JS-значений. Когда делаешь обычный console.log по большим объектам, то там легко наступить на кейс, когда в каком-нибудь поле выведется [Object object]. Эта "проблема" решается с помощью JSON.stringify, но либа предлагает еще кучу всякого и удобного

При кажущейся простоте задачи, либа имеет много методов и много опций (когда смотришь доку, видишь что это реально комбайн). Например, из интересных юзкейсов - либа умеет выводить свойства прототипа рядом со свойством объекта, отмечая их отдельным символом.

https://www.npmjs.com/package/@parischap/pretty-print

#development #javascript #library #console

Dev News от Максима Соснова

28 Oct, 06:07


Дайджест за 2024-10-21 - 2024-10-25

Unleash JavaScript's Potential with Functional Programming
Еще одна статья про функциональное программирование в JS. Данная статья представляет собой гайд, который погружает вас в функциональное программирование шаг за шагом.

Объяснение начинается с определений - что такое примитив, что такое композируемая сущность, что такое функция и из чего она состоит и тд и тп. Заканчивается все применением каррирования.

⭐️SVG Coding Examples: Useful Recipes For Writing Vectors By Hand
Огромный гайд по рисованию SVG в JS на Smashing Magazine.

Начинается все с основ: что за поле используется в SVG, как управлять его размером, что с единицами измерения. Затем гайд переходит в варианты создания простых svg примитивов (линии, квадраты, окружности, овалы) в JS, затем переходит к более сложным техникам (полигоны, паттерны).

How Bun supports V8 APIs without using V8 (part 1)
Команда разработки Bun рассказывают, как они поддерживают API V8 (движок гугл хрома) без использования V8. Bun стремиться быть совместимым с nodejs API, чтобы любой nodejs код можно было запускать в bun. Если nodejs для каких-то операций использует С++ библиотеки, то bun тоже их использует (или их аналоги). Сложнее обстоят дела с теми кейсами, когда реализация nodejs сделана через вызов V8. В Bun используется не V8 а JavaScriptCore (движок, используемый в safari). Поэтому прост так взять и использовать тоже самое не получается - надо либо найти аналог в JSC и убедиться что он работает также, либо написать свою имплементацию

Собственно про это и статья. В статье рассказывается про подводные камни такого подхода. 2 практических идентичных куска кода на С++ будут вести к разным результатам при использовании V8 и JSC. Статья подробно рассказывает про часть этих подводных камней с примерами С++ кода.

assistant-ui
Assistant-ui набор компонентов для быстрой реализации чатов с AI. Есть клишка, которая поможет инициализировать проект с простым чатом. Есть несколько базовых примеров использования библиотеки для реализации простого функцинала

https://github.com/Yonom/assistant-ui

Ultimate Express
Ultimate Express - http сервер с полной совместимостью с express, но реализованный на µWebSockets (это веб-сервер написанный на С++). Основная фича (помимо скорости работы) - что это drop-in замена обычному экспрессу. Если вы используется 4 экспресс, все что нужно, это поставить новый пакет npm install ultimate-express и затем по всему коду заменить express на ultimate-express.

Есть несколько ограничений и отличий от обычного express, но они минимальны.

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂

Dev News от Максима Соснова

25 Oct, 07:00


Ultimate Express

Ultimate Express - http сервер с полной совместимостью с express, но реализованный на µWebSockets (это веб-сервер написанный на С++). Основная фича (помимо скорости работы) - что это drop-in замена обычному экспрессу. Если вы используется 4 экспресс, все что нужно, это поставить новый пакет npm install ultimate-express и затем по всему коду заменить express на ultimate-express.

Есть несколько ограничений и отличий от обычного express, но они минимальны.

На странице в гитхабе представлены 2 бенчмарка перформанса - в одном сравнивается обычный express и ultimate-express. В нем ускорение составляет от 4 до 12 раз. Другой бенчмарк от bun. В этом бенче ultimate-express занимает 3 место среди замеров на node.js (в общем списке он где-то 12)

Крутая либа по нескольким причинам. Во первых, чуваки сделали быстрый http-сервер. Во вторых, они сделали полную поддержку API express, что позволяет переехать, заменив только импорты (ну вообще можно и без замены импортов обойтись, поправив алиасы для импортов).

https://github.com/dimdenGD/ultimate-express

#development #javascript #express #httpServer

Dev News от Максима Соснова

24 Oct, 07:00


assistant-ui

Assistant-ui набор компонентов для быстрой реализации чатов с AI. Есть клишка, которая поможет инициализировать проект с простым чатом. Есть несколько базовых примеров использования библиотеки для реализации простого функцинала

https://github.com/Yonom/assistant-ui

#development #javascript #react #ai

Dev News от Максима Соснова

23 Oct, 07:00


How Bun supports V8 APIs without using V8 (part 1)

Команда разработки Bun рассказывают, как они поддерживают API V8 (движок гугл хрома) без использования V8. Bun стремиться быть совместимым с nodejs API, чтобы любой nodejs код можно было запускать в bun. Если nodejs для каких-то операций использует С++ библиотеки, то bun тоже их использует (или их аналоги). Сложнее обстоят дела с теми кейсами, когда реализация nodejs сделана через вызов V8. В Bun используется не V8 а JavaScriptCore (движок, используемый в safari). Поэтому прост так взять и использовать тоже самое не получается - надо либо найти аналог в JSC и убедиться что он работает также, либо написать свою имплементацию

Собственно про это и статья. В статье рассказывается про подводные камни такого подхода. 2 практических идентичных куска кода на С++ будут вести к разным результатам при использовании V8 и JSC. Статья подробно рассказывает про часть этих подводных камней с примерами С++ кода.

https://bun.sh/blog/how-bun-supports-v8-apis-without-using-v8-part-1

#development #javascript #bun

Dev News от Максима Соснова

22 Oct, 07:00


SVG Coding Examples: Useful Recipes For Writing Vectors By Hand

Огромный гайд по рисованию SVG в JS на Smashing Magazine.

Начинается все с основ: что за поле используется в SVG, как управлять его размером, что с единицами измерения. Затем гайд переходит в варианты создания простых svg примитивов (линии, квадраты, окружности, овалы) в JS, затем переходит к более сложным техникам (полигоны, паттерны).

С одной стороны, достаточно простая по смыслу статья (ну, признаемся честно - рисовать SVG из базовых примитивов - это не рокет сайнс), с другой стороны - это крутая вводная статья по SVG.

https://www.smashingmagazine.com/2024/09/svg-coding-examples-recipes-writing-vectors-by-hand/

#development #svg #recommended

Dev News от Максима Соснова

21 Oct, 07:00


Unleash JavaScript's Potential with Functional Programming

Еще одна статья про функциональное программирование в JS. Данная статья представляет собой гайд, который погружает вас в функциональное программирование шаг за шагом.

Объяснение начинается с определений - что такое примитив, что такое композируемая сущность, что такое функция и из чего она состоит и тд и тп. Заканчивается все применением каррирования.

Контент скорее полезен для джунов, позволяя им мягко погрузиться в основу композиции функций. Если вы отличаете каррирование от частичного применения и знаете что такое монады - смело скипайте - ваш текущий уровень понимания ФП выше, чем тот, который дает статья.


https://janhesters.com/blog/unleash-javascripts-potential-with-functional-programming

#development #javascript #functionalProgramming

Dev News от Максима Соснова

21 Oct, 05:00


Дайджест за 2024-10-14 - 2024-10-18

Bundling - Past, Present, and Future
Давненько в канале не было видео-контента. В основном, потому что я сам не люблю видео контент, больше читаю. Но вот есть неплохой видел на английском от создателя Parcel про историю бандлинга в вебе.

Неплохо рассказывается история бандлинга и модульности в JS-экосистеме от AMD модулей и до современных тулов и проблем

Nodejs dev - fastify book
Есть среди подписчиков чел, который делает свои сайты-документашки по популярным инструментам. Они уже попадали в канал. В этот раз появился сайт-документашка по fastify.

Гайды - моё уважение, очень подробные, объясняют все шаг за шагом. Если вы хотите изучить fastify или изредка пишете на нем, и вам иногда нужна дока - сохраняйте в закладки.

Деконструкция монолита: Максимально производительный подход к проектированию программ
Перевод статьи о том, как shopify переходил от монолита к модульному монолиту. Shopify был огромным монолитом на Ruby on Rails, в который на протяжении более десяти лет вносили изменения свыше тысячи разработчиков. В какой-то момент команда осознала, что текущее решение необходимо декомпозировать

Монолитная архитектура позволяет упростить код: если тебе нужен какая-то функция - просто импортируй и вызови ее, ведь весь код находится в одном скоупе. Монолиты (до определенного размера) проще деплоить и поддерживать с точки зрения инфраструктуры.

⭐️Canon TDD
Статья от Кента Бека (автора TDD) про TDD. Основная проблема TDD в том, что его неправильно понимают и применяют. Кент Бек в очередной раз рассказывает, как правильно применять каноничный TDD.

В целом, TDD действительно трактуется достаточно широко. Кто-то понимает это как "тесты перед разработкой", кто-то использует для описания процесса, где просто пишутся тесты. Сам по себе термин TDD не самый удачный, т.к. по смыслу под него подходит очень много вариаций процесса разработки. Кент Бек, если мне не изменяет память, где-то уже писал что это не самое удачное название, но зато оно достаточно понятное и позволило практике закрепиться и стать популярной

Улучшение производительности рендеринга с помощью CSS content-visibility
Перевод небольшой статьи от автора emoji-picker-element (компонент для выбора эмодзи) про увеличение производительности рендера этого компонента. Каждый эмодзи состоит из двух элементов - button и img. Достаточно простая верстка. Однако, пользователи компонента пожаловались на медленную работу компонента. Оказалось, что у них более 19 тысяч эмодзи в селекте, из-за чего браузер "подвисает" на пару секунд

Для картинок уже использовался loading=lazy, поэтому такой долгий рендер не был связан с загрузкой почти 20 тысяч картинок. Можно было бы добавить виртуализированный список, но это усложняет решение и делает компонент хуже с точки зрения доступности (хотя, конечно, сложно назвать список из 20к элементов доступным в принципе)

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂

Dev News от Максима Соснова

18 Oct, 07:00


Улучшение производительности рендеринга с помощью CSS content-visibility

Перевод небольшой статьи от автора emoji-picker-element (компонент для выбора эмодзи) про увеличение производительности рендера этого компонента. Каждый эмодзи состоит из двух элементов - button и img. Достаточно простая верстка. Однако, пользователи компонента пожаловались на медленную работу компонента. Оказалось, что у них более 19 тысяч эмодзи в селекте, из-за чего браузер "подвисает" на пару секунд

Для картинок уже использовался loading=lazy, поэтому такой долгий рендер не был связан с загрузкой почти 20 тысяч картинок. Можно было бы добавить виртуализированный список, но это усложняет решение и делает компонент хуже с точки зрения доступности (хотя, конечно, сложно назвать список из 20к элементов доступным в принципе)

Первым делом автор использовал css content-visibility. Это новый фукционал CSS, который позволяет "скрыть" элементы с точки зрения вёрстки и рисования. При этом контент все еще будет доступен в дереве доступности и по нему можно делать поиск по страницу (ctrl+F). Единственное что нужно - уметь предрасчитать размер скрываемых элементов.

После применения content-visibility, прирост в производительности составил 15% - заметно, но не то что ожидалось. Дальнейшее погружение в перформанс показало, что не смотря на loading="lazy", картинки все еще как-то обрабатываются браузером. Следующее решение: заменить img на background-image, но только если элемент с эмодзи появился на экране. Для этого используется IntersectionObserver. Данная техника позволила ускорится на 40%

Автор на этом остановился - он получил достаточно хорошее ускорение. Однако, это не масштабируемое решение (для списка из 200к элементов загрузка будет заметной). В идеале следовало бы использовать виртуализацию списка, но это усложняет компонент, поэтому пока остается так. Стоит заметить, что использование content-visibility и IntersectionObserver относительно "бесплатное" (делается за час времени), но дает огромное ускорение.

https://habr.com/ru/articles/846842/

#development #css #performance

Dev News от Максима Соснова

17 Oct, 07:00


Canon TDD

Статья от Кента Бека (автора TDD) про TDD. Основная проблема TDD в том, что его неправильно понимают и применяют. Кент Бек в очередной раз рассказывает, как правильно применять каноничный TDD.

В целом, TDD действительно трактуется достаточно широко. Кто-то понимает это как "тесты перед разработкой", кто-то использует для описания процесса, где просто пишутся тесты. Сам по себе термин TDD не самый удачный, т.к. по смыслу под него подходит очень много вариаций процесса разработки. Кент Бек, если мне не изменяет память, где-то уже писал что это не самое удачное название, но зато оно достаточно понятное и позволило практике закрепиться и стать популярной

В этой статье Кент Бек снова рассказывает о каноничном TDD, которое он описывал в своих книжках

TDD помогает разработчику изменить систему так что:
- Все что работало, продолжает работать
- Новое поведение работает как ожидается
- Система готова к применению новых изменений
- Разработчик и его коллеги уверены в верности предыдущих высказываний

Шаги по реализации TDD:

1) Список тестов. Первый шаг - описать список всех ожидаемых вариаций нового поведения. При этом не следует думать о том, как это будет работать технически (ОК думать о том, что состояние заказа изменится, но не ОК думать о том, в какие поля БД будут записаны данные).
2) Выберите тест из списка тестов и напишите его. Один тест. Полноценный тест с фазами подготовки, запуска и проверки. Типичные ошибки: писать тесты без проверок; писать сразу кучу тестов.
3) Сделайте так, чтобы тест прошел. Типичные ошибки: удалять проверки; копировать вычисленные значения в проверки; делать рефакторинг в этой фазе (умная мысль на запомнить - "Make it run, then make it right"). Если во время реализации вы понимаете, что нужен еще 1 тест - запишите его в список тестов из списка 1. После того как тест прошел, вычеркните его из списка тестов (он реализован)
4) Опциональный рефакторинг. Типичные ошибки: слишком глубокий рефакторинг, который не требуется сейчас; Слишком раннее создание абстракций
5) Если список те стов еще не пуст, перейдите к пункту 2.

В статье также есть крутая визуализация этого алгоритма.

https://tidyfirst.substack.com/p/canon-tdd

#development #TDD #kentBeck #recommended

Dev News от Максима Соснова

16 Oct, 07:00


Деконструкция монолита: Максимально производительный подход к проектированию программ

Перевод статьи о том, как shopify переходил от монолита к модульному монолиту. Shopify был огромным монолитом на Ruby on Rails, в который на протяжении более десяти лет вносили изменения свыше тысячи разработчиков. В какой-то момент команда осознала, что текущее решение необходимо декомпозировать

Монолитная архитектура позволяет упростить код: если тебе нужен какая-то функция - просто импортируй и вызови ее, ведь весь код находится в одном скоупе. Монолиты (до определенного размера) проще деплоить и поддерживать с точки зрения инфраструктуры.

Однако монолит не лишен и проблем. Начиная с определенного размера монолиты становится тяжело развертывать и поддерживать инфраструктурно. Также, из-за отсутствия четких границ между кодом внутри монолита, небольшие изменения, которые кажутся изолированными, могут сломать что-то в месте, где изменений не ожидается. Фронтенд-специфичная аналогия: поправил шапку сайта, сломалась форма оплаты. Из-за отсутствия явных границ разработчикам нужно держать в голове большой скоуп знаний, тестировать это также сложно.

У shopify стоял выбор между микросервисами и модульным монолитом. Микросервисы являются стандартом в индустрии, но они также несут в себе кучу сложностей. Поэтому команда shopify решила оставить преимущества монолита (простота деплоя и поддержки инфраструктуры), но решить недостатки добавлением модульности

Модульный монолит - это когда у вас приложение деплоится единым куском, но при этом внутри монолита все декомпозировано по модулям с четко очерченной ответственностью. В идеале, любой модуль из модульного монолита может быть вынесен в микросервис через минимальные правки.

Т.к. shopify достаточно большой, то нельзя просто взять и единомоментно переехать на новую структуру системы. Для этого был разработан план плавной миграции на новую архитектуру

В первую очередь решено было переделать структуру файлов. Каждый бизнесовый модуль был вынесен в отдельную папку, которая организована как мини-приложения на рельсах и которая может быть вынесена как ruby-модуль. В рамках этого перемещения потерялась история изменений в гит т.к. гит распознал переносы файлов как удаление и добавление, вместо перемещения. В целом историю отследить можно, но github отказывается это делать в веб-интерфейсе.

После переноса куча файлов и раскладывание этих файлов по папкам надо превратить эти папки в настоящие модули. Для этого надо выделить публичное API модулей и запретить использование непубличного API. Ребята написали свой инструмент, который следит за тем, насколько модули изолированы (есть ли публичный интерфейс, и используют ли они сами только публичный интерфейс других модулей). Таким образом инструмент отслеживает прогресс модуляризации папок с файлами и позволяет разработчикам более эффективно принимать решения

https://habr.com/ru/companies/piter/articles/844572/

#development #monolith #microservices #modularMonolith

Dev News от Максима Соснова

15 Oct, 07:00


Nodejs dev - fastify book

Есть среди подписчиков чел, который делает свои сайты-документашки по популярным инструментам. Они уже попадали в канал. В этот раз появился сайт-документашка по fastify.

Гайды - моё уважение, очень подробные, объясняют все шаг за шагом. Если вы хотите изучить fastify или изредка пишете на нем, и вам иногда нужна дока - сохраняйте в закладки.

https://nodejsdev.ru/frameworks/fastify.3.book/

#development #javascript #nodejs #fastify

Dev News от Максима Соснова

14 Oct, 07:00


Bundling - Past, Present, and Future

Давненько в канале не было видео-контента. В основном, потому что я сам не люблю видео контент, больше читаю. Но вот есть неплохой видел на английском от создателя Parcel про историю бандлинга в вебе.

Неплохо рассказывается история бандлинга и модульности в JS-экосистеме от AMD модулей и до современных тулов и проблем

https://www.youtube.com/watch?v=JUS6EPMbk0U

#development #javascript #bundlers #youtube #video

Dev News от Максима Соснова

14 Oct, 05:00


Дайджест за 2024-10-07 - 2024-10-11

ts-blank-space
Bloomberg заопенсорсили свой компилятор TS в JS. Это, конечно, сложно назвать компилятором - он очень быстро удаляет весь синтаксис TS и оставляет только нативный синтаксис JS.

Сам инструмент максимально простой: парсит AST, находит токены, связанные с TS и заменяет их на пробелы (поэтому blank-space в названии).

stricli
Еще 1 инструммент от Blooomberg. На этот раз - инструмент для создания cli. Основные фичи: поддержка typescript, отсутствие депенденсей, умеет и в ESM и в commonjs, умеет в автокомплит из шела, умеет в код сплиттинг и инъекцию зависимостей

What in Zod's name?
Есть библиотека для валидации по схеме - Zod. Она достаточно популярна, но ошибки валидации от нее сложно воспринимать. Для упрощения разбора ошибок появился zod.fyi - вы вставляете в него текст ошибки, а он выдает вам человекопонятное описание, что же случилось. В целом, наверное, можно закидывать ошибку и в chatGPT.


ESLint now officially supports linting of JSON and Markdown
Eslint продолжает развиваться. На этот раз представили поддержку линтинга json и markdown.

С одной стороны, линтить JSON и markdown не очень то интересно. С другой стороны есть 2 плюса: 1) можно использовать 1 инструмент для линтинга не только кода, но и json и доки на markdown; 2) сделали полноценную поддержку других языков

Announcing VoidZero - Next Generation Toolchain for JavaScript
Evan You (создатель vue, vite и кучи других инструментов) основал компанию, задача которой - создать тулчейн нового поколения для JS. Компания называется VoidZero. В целом, примерно те же цели что и у Rome, но доверия к Evan You намного больше - человек ультра продуктивен и делает действительно крутые инструменты.


——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂

Dev News от Максима Соснова

11 Oct, 07:00


Announcing VoidZero - Next Generation Toolchain for JavaScript

Evan You (создатель vue, vite и кучи других инструментов) основал компанию, задача которой - создать тулчейн нового поколения для JS. Компания называется VoidZero. В целом, примерно те же цели что и у Rome, но доверия к Evan You намного больше - человек ультра продуктивен и делает действительно крутые инструменты.

Что уже было разработано командой Evan You
- Vite, который стал уже основным сборщиком для многих мета-фреймворков
- Самый быстрый JavaScript парсер oxc-parser, в 3 раза быстрее чем SWC
- Самый быстрый Node.js резолвер зависимостей oxc-resolver, в 28x раз быстрее чем enhanced-resolve
- Самый быстрый TS/JSX трансформер oxc-transform, в 4 раза быстрее чем SWC. Не видел его, кстати, в бенчмарке от Блумберга, где они сравнивали свой ts-blank-page
- Самый быстрый линтер oxlint, в 50–100 раз быстрее чем ESLint
- Самый фичастый (в оригинале the most feature-complete) тест-раннер для веб приложений - vitest
- Самый быстрый бандлер Rolldown. Быстрее чем esbuild и другие бандлеры, написанные на Rust

Я верю в то, что у Evan You все получится. Во первых, он уже доказал, что умеет делать крутые тулы. Во вторых, в отличии от Rome, у него уже есть куча инструментов, часть из которых уже популярны - он делает свой тулчейн не на пустом месте

https://voidzero.dev/posts/announcing-voidzero-inc

#development #javascript #EvanYou

Dev News от Максима Соснова

10 Oct, 07:00


ESLint now officially supports linting of JSON and Markdown

Eslint продолжает развиваться. На этот раз представили поддержку линтинга json и markdown.

С одной стороны, линтить JSON и markdown не очень то интересно. С другой стороны есть 2 плюса: 1) можно использовать 1 инструмент для линтинга не только кода, но и json и доки на markdown; 2) сделали полноценную поддержку других языков

Получается, теперь можно писать плагины на eslint для линтинга других языков. Это позволит сообществу сделать плагины для линтинга css, html, всяких svelte и прочих форматов прямо внутри eslint. Что звучит круто

Подключение новых плагинов выглядит вот так
import json from "@eslint/json";

export default [
{
plugins: {
json,
},
},

// lint JSON files
{
files: ["**/*.json"],
language: "json/json",
rules: {
"json/no-duplicate-keys": "error",
},
},
];


https://eslint.org/blog/2024/10/eslint-json-markdown-support/

#development #javascript #eslint #markdown #JSON

Dev News от Максима Соснова

09 Oct, 07:00


What in Zod's name?

Есть библиотека для валидации по схеме - Zod. Она достаточно популярна, но ошибки валидации от нее сложно воспринимать. Для упрощения разбора ошибок появился zod.fyi - вы вставляете в него текст ошибки, а он выдает вам человекопонятное описание, что же случилось. В целом, наверное, можно закидывать ошибку и в chatGPT.

https://zod.fyi/

#development #javascript #zod #validation

Dev News от Максима Соснова

08 Oct, 07:00


stricli

Еще 1 инструммент от Blooomberg. На этот раз - инструмент для создания cli. Основные фичи: поддержка typescript, отсутствие депенденсей, умеет и в ESM и в commonjs, умеет в автокомплит из шела, умеет в код сплиттинг и инъекцию зависимостей

https://bloomberg.github.io/stricli/

#development #javascript #typescript #bloomberg #cli

Dev News от Максима Соснова

07 Oct, 08:42


ts-blank-space

Bloomberg заопенсорсили свой компилятор TS в JS. Это, конечно, сложно назвать компилятором - он очень быстро удаляет весь синтаксис TS и оставляет только нативный синтаксис JS.

Сам инструмент максимально простой: парсит AST, находит токены, связанные с TS и заменяет их на пробелы (поэтому blank-space в названии).

Зачем это вообще нужно.

Во первых, тул не проводит никакой тайп-чек, да и сам алгоритм простой, что делает его очень быстрым.

Во вторых, подстановка пробелов вместо конструкций TS позволяет гарантировать, что код никуда не съехал. Это лучше показать на примере

Оригинальный код
class Cat<T> {
public whiskers: number;
public tail: T;

constructor(count: number, tail: T) {
this.whiskers = count;
this.tail = tail;
}
}

throw Error();


Код, скомпилированный TS в esnext

class Cat {
whiskers;
tail;
constructor(count, tail) {
this.whiskers = count;
this.tail = tail;
}
}
throw Error();


Очень близко к оригиналу, но вы можете заметить что исчезли пустые строки. А это значит, что теперь stacktrace у ошибки будет указывать на другую строчку.

ts-blank-space компилирует код в такой вариант
class Cat    {
whiskers ;
tail ;

constructor(count , tail ) {
this.whiskers = count;
this.tail = tail;
}
}

throw Error();


Как видите, вся специфика TS была заменена на пробелы, все значимые токены остались на своих местах. Это позволяет упростить дебаг: stacktrace ошибок всегда указывает на ту же строчку и колонку, на которой стоит конструкция в оригинальном коде; также упрощается сбор сорс-мапов. Если код меняется, то сорсмапы, грубо говорят, содержат мапинг вида "вот была строчка 10 колонка 11, теперь она строчка 7, колона 8". С использованием ts-blank-space сорсмапы описываются 1 строчкой //# sourceURL=cat.ts

Простота инструмента позволяет ему быть быстрым: по бенчмаркам блумберга, если не учитывать работу с AST для сорс-мапов, то ts-blank-space уступает лишь esbuild и @swc/core. Если же учитывать мапинг сорс-мапов, то ts-blank-space является самым быстрым тулом

Простота инструмента также и ограничивает его. Поддерживается на весь синтаксис TS:
- не поддерживаются неймспейсы (declare namespace поддерживается)
- не поддерживается специфика commonJS
- енамы (declare enum поддерживается)
- Свойства класса, объявляемые в конструкторе constructor(public prop) {}

В общем, интересный тул. Для каких-то простых проектов можно спокойно использовать.

https://bloomberg.github.io/ts-blank-space/

#development #javascript #typescript #bloomberg #compiler

Dev News от Максима Соснова

30 Sep, 08:45


Сегодня и завтра я на Frontendconf 2024. Завтра буду рассказывать свой доклад "релизим без стресса" про то, как применять лучшие инженерные практики и быть уверенными, что релиз пойдёт гладко.

Если вы на frontendconf 2024, приходите слушать.
Если вы не на конференции - новости пойдут в канал либо с пятницы, либо со следующей недели.

А ещё скоро появится публичная ссылка моего выступления с codefest про парное программирование, также скину в канал.

Dev News от Максима Соснова

23 Sep, 06:26


Дайджест за 2024-09-16 - 2024-09-20


——————————————————

Сейчас я активно готовлюсь к выступлению на FrontendConf. Поэтому могут быть задержки в публикации ссылок (пока некогда читать). В частности, сегодня будет только дайджест :С

——————————————————

How I Created a 3.78MB Docker Image for a JavaScript Service
Чем бы ты не занимался, всегда найдется азиат, который сделает это круче.

Так произошло и с докер-образами для JS-сервисов. Чела не устраивало, что все текущие образы весят 50+ МБ, вне зависимости от рантайма, и тогда он сделал свой докер-образ, который весит 3.7МБ.

Exploring Goja: A Golang JavaScript Runtime
Вот было у вас такое, что вы пишете на golang, и вам не хватает простого человеческого javascript? Теперь ваша боль решена - Goja - js рантайм для Golang

Если без шуток, челу необходимо было запускать JS в рамках Golang приложения. Конкретного кейса автора я не понял, но в целом могу выдумать несколько интересных: запуск JS-кода в контролируемом рантайме (для спортивного программирования например), описание сложных правил в UI на JS, а исполнение правил - на сервере на golang.

⭐️How to Use React Compiler – A Complete Guide
Огромная статья, рассказывающая про то, как работает React Compiler. Статья рассказывает, из чего состоит React Compiler как внутри себя, так и через какие инструменты он подключается в проект.

Также в статье показывается на простом кейсе, как React compiler упрощает работу разработчика на практике.

Multithreading in Node.js: Using Atomics for Safe Shared Memory Operations
Статья про многопоточность в nodejs и про atomics API.

Основная проблема мульти-поточности, это race-conditions.

Mutation-testing our JavaScript SDKs
Статья от Sentry, про применение мутационного тестирования в Sentry. Если коротко, мутационное тестирование - это когда инструмент меняет немного ваш код (создает мутанта) и ожидает, что тесты отловят это изменение. Мутанты при этом создаются тысячами, поэтому этот процесс весьма ресурсо-затратен. Однако и результаты всегда однозначны - если мутант выжил, значит вы что-то не протестировали. По сути мутационное тестирование оценивает качество ваших тестов, а не вашего кода. Есть и минусы - не всегда мы хотим писать столько тестов, сколько нужно для набора 100% скора (например, как часто вы в своих тестах проверяете, что вам реально в catch прилетел instanceof Error, а не какой-то кастомный клас?)

Статья рассказывает, как в Sentry решили начать запускать мутационные тесты и следить за скорингом, пытаясь его улучшать и отключая "ненужные" алгоритмы мутации кода. В целом статья не дает каких-то конкретных выводов по этой практике, но рассказывает как настроить и запустить мутационные тесты в своем JS-проекте.

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂

Dev News от Максима Соснова

20 Sep, 07:00


Mutation-testing our JavaScript SDKs

Статья от Sentry, про применение мутационного тестирования в Sentry. Если коротко, мутационное тестирование - это когда инструмент меняет немного ваш код (создает мутанта) и ожидает, что тесты отловят это изменение. Мутанты при этом создаются тысячами, поэтому этот процесс весьма ресурсо-затратен. Однако и результаты всегда однозначны - если мутант выжил, значит вы что-то не протестировали. По сути мутационное тестирование оценивает качество ваших тестов, а не вашего кода. Есть и минусы - не всегда мы хотим писать столько тестов, сколько нужно для набора 100% скора (например, как часто вы в своих тестах проверяете, что вам реально в catch прилетел instanceof Error, а не какой-то кастомный клас?)

Статья рассказывает, как в Sentry решили начать запускать мутационные тесты и следить за скорингом, пытаясь его улучшать и отключая "ненужные" алгоритмы мутации кода. В целом статья не дает каких-то конкретных выводов по этой практике, но рассказывает как настроить и запустить мутационные тесты в своем JS-проекте.

Ожидаем продолжения, где ребята поделятся результатами трекинга скора мутационного тестирования.

https://sentry.engineering/blog/js-mutation-testing-our-sdks

#development #javascript #testing #mutationTesting #sentry

Dev News от Максима Соснова

19 Sep, 07:00


Multithreading in Node.js: Using Atomics for Safe Shared Memory Operations

Статья про многопоточность в nodejs и про atomics API.

Основная проблема мульти-поточности, это race-conditions.

Для визуализации проблемы можно взять следующий пример. У нас есть приложение, которое запускает 2 воркера и передает им одни и те же данные

Код приложения и воркера
import { Worker, isMainThread, workerData, threadId } from 'node:worker_threads';

// код приложика
if (isMainThread) {
const buffer = new SharedArrayBuffer(1);
new Worker(import.meta.filename, { workerData: buffer });
new Worker(import.meta.filename, { workerData: buffer });
} else {
// код воркера
const typedArray = new Int8Array(workerData);
typedArray[0] = threadId;
console.dir({ threadId, value: typedArray[0] });
}


Воркеры пишут id своего треда в общие данные и делают console.log этих общих данных. Т.к. код синхронный, то в целом у меня, как у обычного человека, редко пишущего многопоточные приложики, есть ожидание что в console.log всегда будет выводится id текущего треда

Однако практика показывает, что это не так
# 1 type of results
{ threadId: 1, value: 2 }
{ threadId: 2: value: 2 }

# 2 type of results
{ threadId: 1, value: 1 }
{ threadId: 2: value: 1 }

# 3 type of results
{ threadId: 1, value: 1 }
{ threadId: 2: value: 2 }



ОС может передать процессорное время в другой тред после того, как тред записал данные в массив, но до того, как тред вывел свои данные в консоль

Проблема стара как мир и я помню, как мы в универе на изучении C++ изучали всякие схемы для эксклюзивного доступа к памяти (семафоры, мьютексы).

В JS для эксклюзивного и безопасного доступа к шареной памяти используется atomics. В данном кейсе автор разбирает использование store и load для блокирующего доступа к памяти, что не до конца решается кейс, но уже делает лучше.

const typedArray = new Int8Array(workerData);
Atomics.store(typedArray, 0, threadId);
const value = Atomics.load(typedArray, 0);
console.dir({ threadId, value });


Более сложные решения автор опишет в будущих статьях. Штош, ждем в будущих дайджестах

https://pavel-romanov.com/multithreading-in-nodejs-using-atomics-for-safe-shared-memory-operations

#development #javascript #nodejs #multiThreading #atomics

Dev News от Максима Соснова

18 Sep, 07:00


How to Use React Compiler – A Complete Guide

Огромная статья, рассказывающая про то, как работает React Compiler. Статья рассказывает, из чего состоит React Compiler как внутри себя, так и через какие инструменты он подключается в проект.

Также в статье показывается на простом кейсе, как React compiler упрощает работу разработчика на практике.

Статья не очень глубока с технической точки зрения, но очень хорошо верхнеуровнево объясняет, что такое этот React Compiler и как он работает с практической точки зрения - объясняется, что происходит с кодом, который я пишу, и что мне необходимо было бы сделать самому для достижения того же результата

https://www.freecodecamp.org/news/react-compiler-complete-guide-react-19/

#development #javascript #react #reactCompiler #recommended

Dev News от Максима Соснова

17 Sep, 07:00


Exploring Goja: A Golang JavaScript Runtime

Вот было у вас такое, что вы пишете на golang, и вам не хватает простого человеческого javascript? Теперь ваша боль решена - Goja - js рантайм для Golang

Если без шуток, челу необходимо было запускать JS в рамках Golang приложения. Конкретного кейса автора я не понял, но в целом могу выдумать несколько интересных: запуск JS-кода в контролируемом рантайме (для спортивного программирования например), описание сложных правил в UI на JS, а исполнение правил - на сервере на golang.

Автор смотрел в сторону разных вариантов запуска JS в рамках Golang, но остановился на Goja. Основное преимущество Goja - это бесшовная связка структур в Golang со структурами JS.

В целом, если у вас на сервере крутится golang и вам надоело дублировать какую-то логику в нескольких местах, можете предложить в команде использовать Goja, чтобы реализовывать общую логику на JS и использовать ее в golang. Ну или у вас могут быть еще какие-то кейсы для использования такой библиотеки

На последок, закину сниппет кода, который использует Goja

package main

import (
"fmt"

"github.com/dop251/goja"
)

func main() {
vm := goja.New()

// Passing an array of integers from 1 to 100
values := []int{}
for i := 1; i <= 100; i++ {
values = append(values, i)
}

// Define the JavaScript code to filter even values
script := `
values.filter((x) => {
return x % 2 === 0;
})
`

// Set the array in the JavaScript runtime
vm.Set("values", values)

// Run the script
result, err := vm.RunString(script)
if err != nil {
panic(err)
}

// Convert the result back to a Go slice of empty interfaces
filteredValues := result.Export().([]interface{})

fmt.Println(filteredValues)
// Outputs: [2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100]

first := filteredValues[0].(int64)
fmt.Println(first)
}


https://jtarchie.com/posts/2024-08-30-exploring-goja-a-golang-javascript-runtime

#development #javascript #runtime

Dev News от Максима Соснова

16 Sep, 07:00


How I Created a 3.78MB Docker Image for a JavaScript Service

Чем бы ты не занимался, всегда найдется азиат, который сделает это круче.

Так произошло и с докер-образами для JS-сервисов. Чела не устраивало, что все текущие образы весят 50+ МБ, вне зависимости от рантайма, и тогда он сделал свой докер-образ, который весит 3.7МБ.

Чтобы сделать такой худой образ, автор использует LLRT как рантайм. Это рантайм, который развивает AWS, если я правильно помню. Создан поверх движка QuickJS.

Т.к. llrt весит так мало не просто так (а потому что многое там упрощено и многого там просто нет), то пришлось немножко адаптировать свое приложение. Например, переписать часть, связанную с http сервером.

Итоги:
- Докер образ стал весить меньше
- Приложение быстрее стартует
- Приложение медленее работает
- Автор в целом рекомендует оставаться на nodejs для большинства кейсов.

https://shenzilong.cn/record/How%20I%20Created%20a%203.78MB%20Docker%20Image%20for%20a%20JavaScript%20Service

#development #javascript #docker

Dev News от Максима Соснова

16 Sep, 05:05


Дайджест за 2024-09-09 - 2024-09-13

⭐️Особенности Effector, которые почему-то никто не обсуждает: опыт ВКонтакте спустя год использования
На Codefest команда ВК рассказывала, как они решили перейти на effector и почему пришлось откатываться. Мне лично доклад сильно понравился, потому что он, по своему смыслу, двух-уровневый: на первом уровне - критика effector, на втором уровне - как выбирать инструменты (отдельно кекнул прям на докладе, что решили выбирать стейт менеджер на основе голосования)

Записи докладов с Codefest еще не обнародовали, но команда VK выпустила статью на ту же тему. Статья уже стала источником небольшой драмы в сообществе (например, можно почитать кучу постов у sergeysova и немножко у artalog).

An SSR Performance Showdown
Немного странный бенчмарк производительности серверного рендеринга разных библиотек. Задача простая: отрисовать спираль из 2398 дивов. В сравнении участвовали fastify-html (простая либка для рендера html из fastify), react, preact, vue, solidjs, svelte.

В явных лидерах (>1000 RPS): fastify-html и vue, далее с небольшим отставанием (>900 RPS) идут svelte и solidjs, завершают рейтинг preact (717 RPS) и react (572 RPS).

В комментах отписаличь, почему бенчмарк - фигня

Announcing Vue 3.5
Анонсирован Vue 3.5. Давно не следил за vue, хотя продолжительно время писал на нём. И вот решил посмотреть что там нового в vue 3.5.

Я, конечно, давно уже не слежу за тем, насколько Vue быстрее или медленнее других библиотек и фреймворков. Но в моей памяти - он считается достаточно быстрым (поправьте в коментах, если это уже давно не так). Тем не менее, в 3.5 уменьшили в 2 раза потребление памяти системой реактивности, а трекинг огромных вложенных массивов ускорился в 10 раз в определенных кейсах

В комментах разные уточнения к посту и перформансу

OpenAI is shockingly good at unminifying code
Небольшая статья, показывающая интересный юзкейс для нейронок. Чувак увидел прикольную ASCII-анимацию на сайте, и захотел узнать как она работает. Как это часто бывает на сайтах - из исходников есть только минифицированный код на React в сорсах страницы.

Его можно было бы и реверснуть ручками (там небольшой фрагмент кода), но чел воспользовался мощью chatGPT, который правильно разобрал алгоритм и затем почти правильно написал читаемую имплементацию на typescript.

Inside ECMAScript: JavaScript Standard Gets an Extra Stage
Комитет стандартизации Ecmascript добавил еще 1 Stage для предложений по улучшению языка. Между 2 и 3 этапом добавился stage 2.7.

Почему он понадобился: часто большие предложения, попадавшие на Stage 3, разворачивались обратно на Stage 2 т.к. оказывалось, что у предложения есть существенные недостатки, которые не были выявлены ранее. Это означает, что вся работа, сделанная в stage 3, была сделана зря. Чтобы минимизировать подобные кейсы, решили добавить шаг 2.7, в котором уже договорились о том, как все должно работать, но теперь пишут тест-кейсы и валидируют, что это предложение действительно рабочее (если я правильно понял).

——————————————

Также короткий пост о том как я посетил конфу в Томске

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂

Dev News от Максима Соснова

14 Sep, 14:40


Обычно я не рассказываю как прошла очередная конфа, но про город ИТ не могу не поделиться.
В прошлом году фронтенд трек проходил в ночном клубе и это было супер-атмосферно: томный свет, на заднем фоне был, есть танцпол, липкий пол, кожаные диваны. В этом году площадку взяли ровно противоположную - филармонию. Я уж думал буду как ферзь выступать на крутой сцене. Но все оказалось ещё круче - утренний фронтенд трек проходил в шатре на улице (а сентябрь в Томске не прям тёплый, утра холодно было). Рассказал доклад про парное программирование, вроде людям зашло) позадавали вопросов и рассказали своих кейсов. На стенде сибура выиграл мемного кота.

Томск, конечно, ультра вайбовый город. Чем то похож на Питер, только компактнее как в целом по масштабам, так и по размерам старых зданий. Также здесь есть очень хорошая бургерная. Местные говорят, что лучшая в мире и я им верю